别再天真了!PHP反序列化漏洞,比你想象的更危险
什么是反序列化?说白了就是“格式转换”吗?
别被“格式转换”这种人畜无害的说法给骗了!本质上,反序列化就是把一坨看似无害的数据,像变魔术一样,变成一个活生生的PHP对象。这对象一旦复活,就能执行代码、读写文件,甚至控制你的服务器!
序列化?serialize()
?呵呵,这玩意儿就是把对象变成字符串的“封印术”。
class S { public $test = "you txt"; } $s = new S(); // 创建一个对象,准备搞事情 serialize($s); // 对象被“封印”成字符串:O:1:"S":1:{s:4:"test";s:7:"you txt";} // 字符串的含义?别死记硬背,理解才是王道! // O: object(对象) // 1: 对象名 "S" 的长度 // S: 对象的名字 // 1: 对象里有一个变量 // s: string(字符串)类型 // 4: 变量名 "test" 的长度 // test: 变量的名字 // s: 变量值的类型 // 7: 变量值 "you txt" 的长度 // you txt: 变量的值
反序列化?unserialize()
? 这才是真正的“潘多拉魔盒”!
$u = unserialize("O:1:"S":1:{s:4:"test";s:3:"txt";}"); echo $u->test; // 砰!txt 字符串被炸出来了!
序列化/反序列化本身没毛病?放屁!问题在于,如果反序列化的数据是用户可控的,而且你的代码里还用了那些邪恶的“魔法函数”,那就是一场灾难!
反序列化漏洞:为啥防不胜防?
别指望简单的“审查”就能搞定反序列化漏洞!你以为你是火眼金睛?能看穿每一段序列化字符串背后的恶意?太天真了!
现代应用就像一个巨大的乐高积木,依赖关系错综复杂。你根本不可能在反序列化之后,对每一个对象的调用都进行彻底的安全检查。
说白了,反序列化漏洞的根源就是:开发者对用户输入蜜汁自信! 以为用户都是乖宝宝,只会输入“hello world”。
魔法方法?__toString()
、__construct()
、__destruct()
? 呵呵,这些都是黑客的“秘密武器”。
__toString()
:对象被当成字符串用?嘿嘿,执行我的恶意代码! __construct()
:new 对象?不好意思,我只想搞破坏! __destruct()
:对象被销毁? 临死也要拉你下水! __wakeup()
:反序列化? 醒来第一件事就是搞事情! __invoke()
:把对象当函数调用? 满足你! __call()
:调用不存在的方法? 没关系,我来定义! __get()
/ __set()
:读写不可访问的属性?so easy!__sleep()
:序列化之前?先让我做点手脚!
如何找到隐藏的反序列化炸弹?
别指望一招鲜吃遍天!发现反序列化漏洞,需要十八般武艺齐上阵!
- 代码审计?
呵呵,那是神仙才能玩转的技能。 - 自动化工具?
也许能发现一些蛛丝马迹,但别指望它们能解决所有问题。 - 黑盒测试?
撞大运的概率比较高。 - 分析请求和响应?
仔细观察,也许能发现一些可疑的序列化数据。 - 使用已知库和漏洞?
站在巨人的肩膀上,总比闭门造车强。
案例:PHP反序列化漏洞“简单”复现?
别被“简单”两个字迷惑!真正的攻击往往比你想象的更复杂!
<?php // 漏洞代码!请勿在生产环境中使用! class A { public $var = 'you are very good hacker!'; public function test() { echo $this->var; return '1sss'; } public function __construct() { echo 'start' . '<br>'; } public function __destruct() { echo 'end' . '<br>'; } public function __toString() { return '转换字符串'; } } $a = new A(); // 创建对象?等着被黑吧! echo serialize($a) . '<br>'; // 序列化?给黑客送弹药! ?>
添加一句反序列化代码?unserialize($_GET['x'])
?呵呵,瞬间爆炸!
<?php class A { // ... (代码同上) ... } $a = new A(); echo serialize($a) . '<br>'; echo unserialize($_GET['x']); // 危险!用户可控的反序列化入口! ?>
传递恶意序列化数据?__toString()
魔术方法被触发了!
不传值?呵呵,啥都没有。
不用实例化对象?直接执行系统命令?
class B { public $var = 'hellow word'; public function __destruct() { system('whoami').'<br>'; // 恶意代码! } public function __construct() { echo 'you are very good hacker!'.'<br>'; } public function __toString() { return $this->var; } } //$demo=new B();//取消实例化,方便演示 //echo serialize($demo).'<br>'; //输出 O:1:"B":1:{s:3:"var";s:11:"hellow word";} $test=unserialize($_GET['x']); // 反序列化! echo $test;
发送恶意payload?whoami
命令被执行了!
再来一个例子?获取ipconfig
?
class C { public $cmd = 'ipconfig'; // 恶意命令! public function __construct() { echo 'you txt'.'<br>'; } public function __destruct() { system($this->cmd); // 执行命令! } } //echo serialize(new C());// 序列化为:O:1:"C":1:{s:3:"cmd";s:8:"ipconfig";} unserialize($_GET['x']); // 反序列化入口!
修改序列化的值?获取系统版本号?
这就是反序列化漏洞?呵呵,这只是冰山一角!
Pikachu 漏洞平台:小试牛刀?
Pikachu 平台? 适合小白入门? 别太当真!
观察表单数据? 传了一个o
参数? 网页源码? 啥也没有? 黑盒测试? 抓瞎?
直接看源码? 偷偷告诉你 payload?
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
注意 payload 长度? 必须精确匹配!
总结:反序列化漏洞?一场没有硝烟的战争!
PHP反序列化漏洞? 开发者必须高度重视! 深入理解序列化/反序列化机制? 积极采取防御措施? 才能降低风险?
安全? 持续的过程? 开发者、安全研究人员、用户? 共同努力? 才能维护?
别做梦了! 安全永远是猫鼠游戏! 黑客永远比你想象的更聪明!
-
黑客/
原文始发于微信公众号(龙哥网络安全):PHP反序列化漏洞:一场代码炼金术引发的黑客狂欢
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论