PHP反序列化漏洞 完整核⼼原理
一、 漏洞的官⽅定义
PHP反序列化漏洞,全称 PHP对象注⼊漏洞,是指攻击者通过控制服务器端的反序列化输⼊,将恶意构造的序列化字符串传⼊服务器的unserialize函数中,触发类中的魔术⽅法执⾏,最终导致恶意代码/系统
二、 漏洞触发的三⼤核⼼要素
反序列化漏洞的触发有严格的条件,三个要素必须同时满⾜,缺少任何⼀个都⽆法形成漏洞,这是判断是否存在漏洞的核⼼据。
1.要素一:序列化的参数完全可控且⽆校验
服务器端的unserialize函数的⼊参,是由前端⽤户传递的,且开发者没有对传⼊的序列化字符串做任何校验:
不校验序列化字符串的来源;
不校验序列化字符串对应的类名是否合法;
不校验序列化字符串的内容是否被篡改。
核⼼问题:服务器⽆条件信任所有⽤户输⼊的序列化字符串,⽆论是否是恶意构造的,都会直接执⾏反序列化操作。
2.要素⼆:⽬标类中存在可⾃动触发的魔术⽅法
⽬标服务器的代码中,被反序列化的类中,定义了__wakeup、__destruct等魔术⽅法。
核⼼问题:反序列化操作会⾃动触发这些魔术⽅法,⽆需⼿动调⽤,开发者⽆法感知这个执⾏过程。
3.要素三:魔术⽅法中调⽤了⾼危危险函数
魔术⽅法的函数体内部,调⽤了system、eval、exec等可以执⾏系统命令或PHP代码的⾼危函数,且危险函数的参数是类的可控属性。
核⼼问题:攻击者可以通过控制属性值,向危险函数传⼊恶意命令,最终被服务器执⾏。
服务器开发的初衷是,反序列化还原为User对象,读取⽤户信息。该过程中,User类中只有普通⽅法,⽆魔术⽅法、⽆危险函数,完全安全。
开发者在编写代码时,仅使⽤unserialize函数还原数据,但未对反序列化的内容做任何校验,允许攻击者传⼊任意类的序列化字符串,服务器都会照单全收并执⾏反序列化。这个疏忽是所有反序列化漏洞的原罪。
三、 漏洞利⽤的完整四步流程
第1步:开发者的正常业务逻辑:服务器开发的初衷是,反序列化还原为User对象,读取⽤户信息。该过程中,User类中只有普通⽅法,⽆魔术⽅法、⽆危险函数,完全安全。
第2步:开发者的致命安全疏忽:开发者在编写代码时,仅使⽤unserialize函数还原数据,但未对反序列化的内容做任何校验,允许攻击者传⼊任意类的序列化字串,服务器都会照单全收并执⾏反序列化。这个疏忽是所有反序列化漏洞的原罪。
第3步:攻击者构造恶意序列化载荷:攻击者通过代码审计/漏洞探测,找到服务器中存在的危险类,该类满⾜:有魔术⽅法+魔术⽅法内有危险函数。攻击者在本地复刻该类,给类中的可控属性赋值为恶意系统命令,实例化对象后执⾏序列化,⽣成恶意序列化
字符串,这个字符串就是攻击载荷。
第4步:漏洞触发与命令执行:攻击者通过抓包⼯具,将数据包请求体中原有的合法序列化字符串,替换为⾃⼰构造的恶意载荷,发送请求到服务器;服务器接收到请求后,读取参数中的恶意字符串,执⾏unserialize反序列化;反序列化的瞬间,⾃动触发
Show类中的__wakeup魔术⽅法;魔术⽅法执⾏内部的system函数,将攻击者传⼊的恶意命令作为参数执⾏;最终:服务器执⾏了攻击者的命令,攻击者实现对服务器的远程控制。
四、 漏洞的核心总结
无校验的反序列化 + ⾃动触发的魔术⽅法 + 可控参数的⾼危危险函数 = PHP反序列化漏洞

浙公网安备 33010602011771号