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

浙公网安备 33010602011771号