Мэдээллийн технологи
Мэдээллийн технологийн чиглэлээр сонирхогч хэн бүхэнд...
Tuesday, June 3, 2014
Хэвлэмэл монгол бичиг танигч - Traditional Mongolian script recognition OCR
Монгол Улсын Их Сургууль, Хэрэглээний шинжлэх ухаан, инженерчлэлийн сургууль (хуучнаар Мэдээллийн технологийн сургууль) бакалаврын дипломын ажил "Хэвлэмэл монгол бичиг танигч". Програмын ажиллагааны бичлэг.
Monday, November 18, 2013
CSCAMP CTF 2013: Stegno 50
https://www.dropbox.com/s/cx5v0h0kantsfmw/stega1.png
Дараах png файл өгөгдөв.
Мэдээж энгийн нүдээр харахад юу ч харагдахгүй бөгөөд StegSolver-р харахад улаан өнгөний LSB буюу 1-р битүүдээс бүтэх зургийг гаргаж харахад:
Ингээд флаг: Are_you_color_blind
Дараах png файл өгөгдөв.
Мэдээж энгийн нүдээр харахад юу ч харагдахгүй бөгөөд StegSolver-р харахад улаан өнгөний LSB буюу 1-р битүүдээс бүтэх зургийг гаргаж харахад:
Ингээд флаг: Are_you_color_blind
CSCAMP CTF 2013: Reverse 100
100 онооны reverse engineering-н даалгавар нь харьцангуй хялбар байв. Дараах 64 битийн ELF файл өгөгдөв.
https://www.dropbox.com/s/3g3z9upfe9oqp7k/null
Харин файлыг ажиллуулахд username password дамжуулж өгөх хэрэгтэй нь харагдав.
Даалгаврын зорилго нь зөв нэр, нууц үгийг өгснөөр флаг гаргаж авах юм. Ингээд IDA-р ассемблер кодыг нь харахаар нээж агуулагдаж буй тэмдэгтийн цувааг харахад.
Нэр, нууц үг нь encrypt-лэгдээгүй хэлбэрээр байж байв. r00t : OshZ2sexLLLxXXnnn001

Ингээд флаг: 2afcad7815395d567001e09100c4e2fe
Маш хялбархан 100 оноотой болов оо!
https://www.dropbox.com/s/3g3z9upfe9oqp7k/null
Харин файлыг ажиллуулахд username password дамжуулж өгөх хэрэгтэй нь харагдав.
Даалгаврын зорилго нь зөв нэр, нууц үгийг өгснөөр флаг гаргаж авах юм. Ингээд IDA-р ассемблер кодыг нь харахаар нээж агуулагдаж буй тэмдэгтийн цувааг харахад.
Нэр, нууц үг нь encrypt-лэгдээгүй хэлбэрээр байж байв. r00t : OshZ2sexLLLxXXnnn001

Ингээд флаг: 2afcad7815395d567001e09100c4e2fe
Маш хялбархан 100 оноотой болов оо!
CSCAMP CTF 2013: Web 150 Robots
"Humans, keep away!"
Өгсөн хаяг руу ороход дараах форм байв:
Уг даалгавар 'Robots' гэдэг нэрнээсээ маш хурдан хугацаанд хариу илгээх нь ёстой гэдэг нь бараг ойлгомжтой байсан бөгөөд харин яг юуг уг input-д бичиж илгээх нь эхлээд хачирхалтай байв. Ингээд жаахан эх кодыг нь ухвал хуудас дуудагдах бүрд input-н name field буюу өөрөөр хэлбэр параметрээ дамжуулах нэр нь өөр өөрөөр ирж байсан бөгөөд 'challenge' гэдэг cookie-д '2362+-+4312' эсвэл '8432+++1220' гэх мэт хэлбэрийн сонирхолтой утга мөн ирж байв. Уг илэрхийллийг бодоод формын утгыг бөглөөд илгээх код бичлээ. Ингэхдээ '+++' -г зүгээл л + үйлдэл '+-+'-г - үйлдэл гэж хэрэгжүүллээ.
Ингээд кодоо ажиллуудаад флаг гарч ирсэн бөгөөд флаг-аараа оноогоо авсан бөгөөд харин хадгалж авахаа мартсан байна лээ :)
Өгсөн хаяг руу ороход дараах форм байв:
Уг даалгавар 'Robots' гэдэг нэрнээсээ маш хурдан хугацаанд хариу илгээх нь ёстой гэдэг нь бараг ойлгомжтой байсан бөгөөд харин яг юуг уг input-д бичиж илгээх нь эхлээд хачирхалтай байв. Ингээд жаахан эх кодыг нь ухвал хуудас дуудагдах бүрд input-н name field буюу өөрөөр хэлбэр параметрээ дамжуулах нэр нь өөр өөрөөр ирж байсан бөгөөд 'challenge' гэдэг cookie-д '2362+-+4312' эсвэл '8432+++1220' гэх мэт хэлбэрийн сонирхолтой утга мөн ирж байв. Уг илэрхийллийг бодоод формын утгыг бөглөөд илгээх код бичлээ. Ингэхдээ '+++' -г зүгээл л + үйлдэл '+-+'-г - үйлдэл гэж хэрэгжүүллээ.
Ингээд кодоо ажиллуудаад флаг гарч ирсэн бөгөөд флаг-аараа оноогоо авсан бөгөөд харин хадгалж авахаа мартсан байна лээ :)
CSCAMP CTF 2013: Crypto 300 Many times pad
"Well, this is a straightforward one; a classic case of a many time pad. The 12th message contains the flag.
Code:
import os
key = os.urandom(1024)
messages = [message.rstrip('\n') for message in open("messages")]
def xor_string(x, y):
if len(x) > len(y):
return ''.join([chr(ord(z) ^ ord(p)) for (z, p) in zip(x[:len(y)], y)])
else:
return ''.join([chr(ord(z) ^ ord(p)) for (z, p) in zip(x, y[:len(x)])])
print key.encode('hex')
for i in range(0, len(messages)):
print "Message #{0}: {1}".format(i, xor_string(key, messages[i]).encode('hex'))
Message #0: 2838febbef072500b57a8e41119b051ad0174127b3f11208bd094d092bb9b6edfe0b655377a1dd6ccb5870d3ae250d91b9d097b5d13b569545c9fd0f3940195356d89ed9a99140b44fca2e5dffe40f37f07a
Message #1: 3a39badcc70c6143b47e981500974057dd100626a9f10e09af5d021731b9a8e1ec4c671c71abdd79cd5970fdac204a90f0c998f1f33012c14edeb802244215071edbccdeaddc14b14b862f1cece10572e56c80fb267a0a0b93e0458fdc3059c95ba33af02189
Message #2: 2b23eebbdf0d6141b47ed9121081051ac816473be7a50e05fc17180438f4a4e2f90b6d5a38829269855523b4a0224e9aa2c297bfd37f028e0dd8af16244f514611df85d8b7c514a8428f271cfae70831eb298ef52772431cc1f65198d1740dc957ed29eb
Message #3: 2838febbef072500a57a950d0097404ed41b062bb5a8460cbd1309401af8b3f8e50b63527ce58965c01c37f5b5294887b9c899f1c030118459c4b8117048170702d68996b3d040b958996a5fece30d37e72985ff6a4c4f0992a54595dd743ece5aa33df933c489caa16c8290717a85d2d470f6a6529d
Message #4: 2f39e8bbdc002452a33b9012459d0f1ace1b553fa2b21240b31b4d103aebb2e3e358224b71b1952de25334
Message #5: 213fe9bbc00d2044e67a9705459b09499c164726b5a24617b90f084028f1a8f8e80b6e5573a0dd7aca533cb4a0320d82b8cf8ab4943e05c15ec2b21470461f4356d685c5e4d44db959ca3d59ffea4133f0298cba2c734b0584a54b9d993210d35b
Message #6: 2838febbdc002400a36d9c0f0c9d071add10426fb3b90340b1121f0e36f7a6acfa4e705938b19568855a39f2b5290d91b1df
Message #7: 2533eebbce092d4ce67a95120ad31355d11b0620a1f11208b95d050131fda7f9e15822537ee58d78d74c3fe7a4614b9aa28696b4c67f178f498cb1063151140702d689dbe4c55cbd5eca3954e8af0c33fa298af62f7e444895ed4196993517c51ef12bfa318f9882a87dd0d96b3586
Message #8: 3d3effbbe4271364e6739c001797404ed41b0639a8b80505fc120b4026f6b4fead5c6d4e7cb6dd6ccb5870e3a0320d82a2c98ab9943e18850ddfaa022242515417c785d8a3
Message #9: 3d3effbbe4271364e662961417d32755d85e5127aeb20e40bb1208137ffba4eae259671c61aa882dcd5970e7a9204199f0c097b6dc2b568742defd1a3f52514615dd83c4a0d85abb0a9e251cece30d72f7618cee6a774f4885ec40dbdf3b0b8147ec3bb82d8adde7a761d28d253897d5c822f4e94496af2235eb4bab26
Message #10: 2b23eebbc91b6146a969d9180a86404ec90c486fbebe1340bd1309402bf8aae9ad526d496ae59762d04e3ef1b861449ba4c9dea5dc3a569644c0b90622491454059e8ecfe4c55cb90a9d2b45ade00772f76188ba187a4e4892e045
Message #11: 2437e3f9cd48384fb3718c1211950f4fd21a4b2ea9a80d05a50e4d092cb9b5e4e80b63526bb2987f85453fe1e1324890bb"
Code:
import os
key = os.urandom(1024)
messages = [message.rstrip('\n') for message in open("messages")]
def xor_string(x, y):
if len(x) > len(y):
return ''.join([chr(ord(z) ^ ord(p)) for (z, p) in zip(x[:len(y)], y)])
else:
return ''.join([chr(ord(z) ^ ord(p)) for (z, p) in zip(x, y[:len(x)])])
print key.encode('hex')
for i in range(0, len(messages)):
print "Message #{0}: {1}".format(i, xor_string(key, messages[i]).encode('hex'))
Message #0: 2838febbef072500b57a8e41119b051ad0174127b3f11208bd094d092bb9b6edfe0b655377a1dd6ccb5870d3ae250d91b9d097b5d13b569545c9fd0f3940195356d89ed9a99140b44fca2e5dffe40f37f07a
Message #1: 3a39badcc70c6143b47e981500974057dd100626a9f10e09af5d021731b9a8e1ec4c671c71abdd79cd5970fdac204a90f0c998f1f33012c14edeb802244215071edbccdeaddc14b14b862f1cece10572e56c80fb267a0a0b93e0458fdc3059c95ba33af02189
Message #2: 2b23eebbdf0d6141b47ed9121081051ac816473be7a50e05fc17180438f4a4e2f90b6d5a38829269855523b4a0224e9aa2c297bfd37f028e0dd8af16244f514611df85d8b7c514a8428f271cfae70831eb298ef52772431cc1f65198d1740dc957ed29eb
Message #3: 2838febbef072500a57a950d0097404ed41b062bb5a8460cbd1309401af8b3f8e50b63527ce58965c01c37f5b5294887b9c899f1c030118459c4b8117048170702d68996b3d040b958996a5fece30d37e72985ff6a4c4f0992a54595dd743ece5aa33df933c489caa16c8290717a85d2d470f6a6529d
Message #4: 2f39e8bbdc002452a33b9012459d0f1ace1b553fa2b21240b31b4d103aebb2e3e358224b71b1952de25334
Message #5: 213fe9bbc00d2044e67a9705459b09499c164726b5a24617b90f084028f1a8f8e80b6e5573a0dd7aca533cb4a0320d82b8cf8ab4943e05c15ec2b21470461f4356d685c5e4d44db959ca3d59ffea4133f0298cba2c734b0584a54b9d993210d35b
Message #6: 2838febbdc002400a36d9c0f0c9d071add10426fb3b90340b1121f0e36f7a6acfa4e705938b19568855a39f2b5290d91b1df
Message #7: 2533eebbce092d4ce67a95120ad31355d11b0620a1f11208b95d050131fda7f9e15822537ee58d78d74c3fe7a4614b9aa28696b4c67f178f498cb1063151140702d689dbe4c55cbd5eca3954e8af0c33fa298af62f7e444895ed4196993517c51ef12bfa318f9882a87dd0d96b3586
Message #8: 3d3effbbe4271364e6739c001797404ed41b0639a8b80505fc120b4026f6b4fead5c6d4e7cb6dd6ccb5870e3a0320d82a2c98ab9943e18850ddfaa022242515417c785d8a3
Message #9: 3d3effbbe4271364e662961417d32755d85e5127aeb20e40bb1208137ffba4eae259671c61aa882dcd5970e7a9204199f0c097b6dc2b568742defd1a3f52514615dd83c4a0d85abb0a9e251cece30d72f7618cee6a774f4885ec40dbdf3b0b8147ec3bb82d8adde7a761d28d253897d5c822f4e94496af2235eb4bab26
Message #10: 2b23eebbc91b6146a969d9180a86404ec90c486fbebe1340bd1309402bf8aae9ad526d496ae59762d04e3ef1b861449ba4c9dea5dc3a569644c0b90622491454059e8ecfe4c55cb90a9d2b45ade00772f76188ba187a4e4892e045
Message #11: 2437e3f9cd48384fb3718c1211950f4fd21a4b2ea9a80d05a50e4d092cb9b5e4e80b63526bb2987f85453fe1e1324890bb"
Даалгавар маань дээрх байдлаар өгөгдсөн бөгөөд 1024 байтын урттай санамсаргүй түлхүүр буюу key үүсгээд өгөгдлөө түлхүүртэйгээ харгалзах байт бүрээр нь XOR-дох байдлаар нууцалж байв. Уг түлхүүрийг өгөгдсөн 12 ciphertext-г ашиглан гаргаж авах кодыг python дээр бичив:
Кодын ажиллагааг тайлбарлах гэж оролдвол: XOR-дсон түлхүүрийн c-р байтыг олохын тулд нууцалсан өгөгдөл бүрийн (ciphertext) c-р байтуудыг 0-255 хүртэлх утгатай буюу cipher-р XOR-дход бүх тэмдэгтүүд хэвлэгдэх тэмдэгт байвал тэр cipher нь байх магадлалтай болно. Энэ мэтээр бүх ciphertext-г гаргаж авна. Үүний дараа 12-р text нь:
Ингээд flag нь: youjustfoundmanykeys
Wednesday, May 22, 2013
Battle City төсөл
Battle City хэмээх тоглоомыг SEGA, MEGA зэрэг тоглоомын консол дээр анх гарч байснаар нь бид бүгд сайн мэднэ. 2012 оны хавар буюу МУИС, МТС-н 2-р курс суралцаж байхдаа "Си хэл өгөгдлийн бүтцийн төсөл" хичээл дээр М.Золжаргал багшаараа удирдуулан ангийнхаа Г.Түвшинбат, Ц.Батхонгор нарын хамтаар дээрх тоглоомыг C++ програмчлалын хэл дээр хэрэгжүүлсэн.
Тоглоомын програмчлал сонирхдог болон С,C++ хэл судалж буй хүмүүст хэрэгцээтэй болов уу хэмээн тоглоомынхоо эх кодыг байршуулав.
Уг код нь C++ хэл дээр бичигдсэн бөгөөд, DEV-C editor ашигласан. Си хэл дээр графиктай ажиллахдаа BGI(Borland Graphics Interface) буюу Turbo C-н стандарт сан, Joystick-тай харьцахад mmsystem.h, сүлжээгээр өгөгдөл дамжуулахад winsock.h сангуудыг тус тус хэрэглэсэн.
Ямар ч програм хангамж буюу мэдээллийн системийн хөгжүүлэлтэнд хэрэгжүүлэлтээс гадна тест хийх шаардлагатай байдаг бөгөөд энэхүү жижиг тоглоомонд хангалттай хэмжээний тест хийгээгүй тул алдаа гарах магадлалтай. Дахин хэлэхэд энэ төслийг хэрэгжүүлэхэд бид ердөө 2-р курсын оюутнууд байсан тул зөвхөн тухайн үеийн өөрдсийн мэдлэг чадварын хүрээнд гүйцэтгэсэн болно.
Monday, April 29, 2013
Харуул занги 2-р үе Vulnerability
Уг бүлэгт нийт 4-н даалгавартай бөгөөд харин тэмцээний явцад 3 нь л нээгдсэн юм.
1. Харуул (100 оноо)
Харуул даалгавар бүрэн эхээрээ байхгүй бөгөөд гол санаа нь доорх код дээр энгийн sql injection маягийн зүйл хийнэ. Уг нь маш хялбархан даалгавар. Даанч тэр үедээ гүйцэтгэж чадаагүй л юм даа.
<?php
include('conn.php');
$flag = '...';
$admin = false;
$pass = false;
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$result = mysql_query("select * from members where username like '".real_escape_string($_POST['user'])."';");
if (!$result)
{
echo('Алдаа!');
return;
}
else
{
while ($row = mysql_fetch_assoc($result))
{
if ($row['username'] == 'admin')
{
$admin = true;
}
if ($row['userpass'] == $_POST['pass'])
{
$pass = true;
}
}
}
if ($admin && $pass)
{
echo $flag;
}
}
?>
//_______________________________________________________________________//
SOLUTION:
Уг даалгавар дээр шинээр хэрэглэгч үүсгэх боломжтой байсан бөгөөд хэрэв $row['username'] == 'admin' болон if ($row['userpass'] == $_POST['pass']) шалгалтыг давахад флаг маань гараад ирнэ. Шинээр хэрэглэгч үүсгэх боломжтой тул if ($row['userpass'] == $_POST['pass']) үүнийг давах нь үүсгэсэн хэрэглэгчийнхээ нэр, нууц үгээр нэвтрэхэд л хангалттай юм. Харин if ($row['username'] == 'admin') үүнийг давахын тулд дараах аргыг хэрэглэе.
Post-р дамжиж ирсэн өгөгдлийг real_escape_string($_POST['user']) гэж ашиглаж байгаа бөгөөд query дээрээ like ашигласан байна. real_escape_string функц нь \x00, \n, \r, \, ', ", \x1a тэмдэгтуудэд л slash(\) нэмж өгдөг бөгөөд %-г хэвээр нь үлдээх юм. Үүнийг нь ашиглавал LIKE-р нөхцөл шалгаж байгаа тул admit гэсэн хэрэглэгч үүсгээд нэвтрэхдээ хэрэглэгчийн нэр дээ admi% гэж бичээд нууц үг дээр admit-н нууц үгийг бичихэд хангалттай.
//_______________________________________________________________________//
2. Татар (200 оноо)
3. Өэлүн (300 оноо)
Мөн л даалгавар бүтнээрээ байхгүй бөгөөд гол санаа нь:
if (strcmp($arg1, "arg1value1")==0){
if (strcmp($arg2, "arg2value1")==0){
if (strcasecmp($arg1, "arg1value2")==0){
if (strcasecmp($arg2, "arg2value2")==0){
if ($arg1==arg2){
echo $flag;
}
}
}
}
}
дээрх кодонд bypass хийх хэрэгтэй. $arg1 болон $arg2 нь GET-р дамжуулагдсан хувьсагчууд.
//_________________________________________________________________________//
SOLUTION:
Дээрх бүх нөхцөл шалгалтууд(IF)-г даваад буюу бүх бүгдийг нь true буцаалгаж л чадвал flag-аа буюу оноогоо олоод авчихна. Гол асуудал нь PHP дээрх 1 хувьсагч (дан ганц PHP ч бус бусад бүх хэлүүд) 2 тэс өөр утгатай нэгэн зэрэг тэнцүү байх боломжгүй юм.
Иймд харьцуулж буй 2 хувьсагчаа GET-р дамжуулж авч байгаа бөгөөд string дамжуулбал эхний 2 л нөхцөлийг биелүүлээд цааш явахгүй нь тодорхой. Тиймээс string биш өөр зүйл дамжуулж байж л болох юм. Тэр нь массив.
Учир юунд вэ гэвэл PHP-н strcmp функцэд аргументууд нь string байх ёстой бөгөөд бусад төрөл ороод ирвэл шууд NULL утга буцаах бөгөөд харьцуулахдаа === биш == гэж харьцуулсан тул тэр нь 0-тэй тэнцдэг.
Уг тохиолдолд test.php?arg1[]=abc&arg2[]=abc ингэж буюу массив дамжуулж өгч дуудахад bypass хийх юм.
//_________________________________________________________________________//
1. Харуул (100 оноо)
Харуул даалгавар бүрэн эхээрээ байхгүй бөгөөд гол санаа нь доорх код дээр энгийн sql injection маягийн зүйл хийнэ. Уг нь маш хялбархан даалгавар. Даанч тэр үедээ гүйцэтгэж чадаагүй л юм даа.
<?php
include('conn.php');
$flag = '...';
$admin = false;
$pass = false;
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$result = mysql_query("select * from members where username like '".real_escape_string($_POST['user'])."';");
if (!$result)
{
echo('Алдаа!');
return;
}
else
{
while ($row = mysql_fetch_assoc($result))
{
if ($row['username'] == 'admin')
{
$admin = true;
}
if ($row['userpass'] == $_POST['pass'])
{
$pass = true;
}
}
}
if ($admin && $pass)
{
echo $flag;
}
}
?>
//_______________________________________________________________________//
SOLUTION:
Уг даалгавар дээр шинээр хэрэглэгч үүсгэх боломжтой байсан бөгөөд хэрэв $row['username'] == 'admin' болон if ($row['userpass'] == $_POST['pass']) шалгалтыг давахад флаг маань гараад ирнэ. Шинээр хэрэглэгч үүсгэх боломжтой тул if ($row['userpass'] == $_POST['pass']) үүнийг давах нь үүсгэсэн хэрэглэгчийнхээ нэр, нууц үгээр нэвтрэхэд л хангалттай юм. Харин if ($row['username'] == 'admin') үүнийг давахын тулд дараах аргыг хэрэглэе.
Post-р дамжиж ирсэн өгөгдлийг real_escape_string($_POST['user']) гэж ашиглаж байгаа бөгөөд query дээрээ like ашигласан байна. real_escape_string функц нь \x00, \n, \r, \, ', ", \x1a тэмдэгтуудэд л slash(\) нэмж өгдөг бөгөөд %-г хэвээр нь үлдээх юм. Үүнийг нь ашиглавал LIKE-р нөхцөл шалгаж байгаа тул admit гэсэн хэрэглэгч үүсгээд нэвтрэхдээ хэрэглэгчийн нэр дээ admi% гэж бичээд нууц үг дээр admit-н нууц үгийг бичихэд хангалттай.
//_______________________________________________________________________//
2. Татар (200 оноо)
3. Өэлүн (300 оноо)
Мөн л даалгавар бүтнээрээ байхгүй бөгөөд гол санаа нь:
if (strcmp($arg1, "arg1value1")==0){
if (strcmp($arg2, "arg2value1")==0){
if (strcasecmp($arg1, "arg1value2")==0){
if (strcasecmp($arg2, "arg2value2")==0){
if ($arg1==arg2){
echo $flag;
}
}
}
}
}
дээрх кодонд bypass хийх хэрэгтэй. $arg1 болон $arg2 нь GET-р дамжуулагдсан хувьсагчууд.
//_________________________________________________________________________//
SOLUTION:
Дээрх бүх нөхцөл шалгалтууд(IF)-г даваад буюу бүх бүгдийг нь true буцаалгаж л чадвал flag-аа буюу оноогоо олоод авчихна. Гол асуудал нь PHP дээрх 1 хувьсагч (дан ганц PHP ч бус бусад бүх хэлүүд) 2 тэс өөр утгатай нэгэн зэрэг тэнцүү байх боломжгүй юм.
Иймд харьцуулж буй 2 хувьсагчаа GET-р дамжуулж авч байгаа бөгөөд string дамжуулбал эхний 2 л нөхцөлийг биелүүлээд цааш явахгүй нь тодорхой. Тиймээс string биш өөр зүйл дамжуулж байж л болох юм. Тэр нь массив.
Учир юунд вэ гэвэл PHP-н strcmp функцэд аргументууд нь string байх ёстой бөгөөд бусад төрөл ороод ирвэл шууд NULL утга буцаах бөгөөд харьцуулахдаа === биш == гэж харьцуулсан тул тэр нь 0-тэй тэнцдэг.
Уг тохиолдолд test.php?arg1[]=abc&arg2[]=abc ингэж буюу массив дамжуулж өгч дуудахад bypass хийх юм.
//_________________________________________________________________________//
Subscribe to:
Comments (Atom)







