[DefCamp CTF Qualification 2017] - Are you brave enough? (Web)

題目資訊

You have a simple challenge, proove your web skills and get the flag. Website
Update 10:00 EEST: Check index.php~.

Author: Andrei

解法

首先進了網站會看到 Nop. ,嘗試了一下可以知道主頁是 index.php ,但是怎麼試都拿不到其他資訊,就卡住了QQ

所幸,把之前找到的 wordlist 拿來看看,在 cgis.txt 找到了神奇的 .php~ ,拿來一試居然就拿到 source code 啦! ヽ(゚∀゚ヽ 三 ノ゚∀゚)ノ

後來查了一下,看來是 editor 的 temporary / backup files ,可以參考下面兩篇問答。
Why would all of my files have duplicates with a ‘~’ at the end?
What does the tilde (~) mean at the end of a filename?

index.php source code:
https://brave.dctf-quals-17.def.camp/index.php~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
$db = mysqli_connect('localhost','web_brave','','web_brave');
$id = @$_GET['id'];
$key = $db->real_escape_string(@$_GET['key']);
if(preg_match('/\s|[\(\)\'"\/\\=&\|1-9]|#|\/\*|into|file|case|group|order|having|limit|and|or|not|null|union|select|from|where|--/i', $id))
die('Attack Detected. Try harder: '. $_SERVER['REMOTE_ADDR']); // attack detected
$query = "SELECT `id`,`name`,`key` FROM `users` WHERE `id` = $id AND `key` = '".$key."'";
$q = $db->query($query);
if($q->num_rows) {
echo '<h3>Users:</h3><ul>';
while($row = $q->fetch_array()) {
echo '<li>'.$row['name'].'</li>';
}
echo '</ul>';
} else {
die('<h3>Nop.</h3>');
}

可以看到 id 被過濾掉一堆東西,而 key 則是做了 real_escape_string 。 Regular expression 的部分可以參考這個 Regexper 視覺化的圖。

後面開始各種嘗試,把各樣的 payload 丟進 idkey ,但是 sql injection 一直無法成功。分析了一下, key 因為做了 real_escape_string 而且 query 前後都被加了單引號,嘗試用寬字符也失敗,顯然是無法控制了,因此把重心放在 id 上。

最後在 SQLi filter evasion cheat sheet (MySQL) 這篇的 filtering everything and even more 部分發現可以用 ;%00 把後面截斷。再用上 backtick (`) 就可以讓 query 變成 WHERE `id` = `id`,讓資料庫列出所有 user 的 name 。

Payload: https://brave.dctf-quals-17.def.camp/index.php?id=`id`;%00
query: SELECT `id`,`name`,`key` FROM `users` WHERE `id` = `id`;%00 AND `key` = ''

Flag: DCTF{602dcfeedd3aae23f05cf93d121907ec925bd70c50d78ac839ad48c0a93cfc54}