浅析php原生类的利用
[出自:jiwo.org]
如果在代码审计或者ctf中,有反序列化的功能点,但是却不能构造出完整的pop链,那这时我们应该如何破局呢?我们可以尝试一下从php原生类下手,php有些原生类中内置一些魔术方法,如果我们巧妙构造可控参数,触发并利用其内置魔术方法,就有可能达到一些我们想要的目的。
一、常见魔术方法
二、原生类中的魔术方法
我们采用下面脚本遍历一下所有原生类中的魔术方法
三、一些常见原生类的利用
Error/Exception
Error 是所有PHP内部错误类的基类。 (PHP 7, 8)
**Error::__toString ** error 的字符串表达
返回 Error 的 string表达形式。
Exception是所有用户级异常的基类。 (PHP 5, 7, 8)
**Exception::__toString ** 将异常对象转换为字符串
返回转换为字符串(string)类型的异常。
类属性
message 错误消息内容
code 错误代码
file 抛出错误的文件名
line 抛出错误的行数
XSS
__toString方法会返回错误或异常的字符串形式,其中包含我们输入的参数,如果我们构造一串xss代码,结合echo渲染,将触发反射形xss漏洞
示例:
POC:
hash绕过
先看一道题
[2020 极客大挑战]Greatphp
需要绕过两个hash强比较,且最终需要构造eval代码执行
显然正常方法是行不通的,而通过原生类可进行绕过
同样,当md5()和sha1()函数处理对象时,会自动调用__tostring方法
先简单看一下其输出
可以发现,这两个原生类返回的信息除了行号一模一样,利用这点,我们可以尝试进行hash函数的绕过,需要注意的是,必须将两个传入的对象放到同一行
因此我们可以进行简单的测试,发现使用此方法可以绕过hash强(弱)函数比较
根据这些知识点,我们可以轻松构造payload
SoapClient
SoapClient是一个专门用来访问web服务的类,可以提供一个基于SOAP协议访问Web服务的 PHP 客户端,可以创建soap数据报文,与wsdl接口进行交互
soap扩展模块默认关闭,使用时需手动开启
SoapClient::__call —调用 SOAP 函数 (PHP 5, 7, 8)
通常,SOAP 函数可以作为SoapClient对象的方法调用
SSRF
构造函数:
什么是soap
我们构造一个利用payload,第一个参数为NULL,第二个参数的location设置为vps地址
监听vps的2333端口,如下图所示成功触发SSRF,vps收到了请求信息
且可以看到SOAPAction和user_agent都可控
本地测试时发现,当使用此内置类(即soap协议)请求存在服务的端口时,会立即报错,而去访问不存在服务(未占用)的端口时,会等待一段时间报错,可以以此进行内网资产的探测。
如果配合CRLF漏洞,还可以可通过 SoapClient 来控制其他参数或者post发送数据。例如:HTTP协议去攻击Redis
CRLF知识扩展
通过结合CRLF,我们利用SoapClient+CRLF便可以干更多的事情,例如插入自定义Cookie,
发送POST的数据包,这里需要将Content-Type设置为application/x-www-form-urlencoded,我们可以通过添加两个\r\n来将原来的Content-Type挤下去,自定义一个新的Content-Type
看一道ctfshow上的题,完美利用上述知识点
poc:
DirectoryIterator/FilesystemIterator
DirectoryIterator类提供了一个简单的接口来查看文件系统目录的内容。
DirectoryIterator::__toString 获取字符串形式的文件名 (PHP 5,7,8)
目录遍历
使用此内置类的__toString方法结合glob或file协议,即可实现目录遍历
例如:
FilesystemIterator继承于DirectoryIterator,两者作用和用法基本相同,区别为FilesystemIterator会显示文件的完整路径,而DirectoryIterator只显示文件名
因为可以配合使用glob伪协议(查找匹配的文件路径模式),所以可以绕过open_basedir的限制
在php4.3以后使用了zend_class_unserialize_deny来禁止一些类的反序列化,很不幸的是这两个原生类都在禁止名单当中
SplFileObject
SplFileObject 类为单个文件的信息提供了一个面向对象的高级接口
(PHP 5 >= 5.1.2, PHP 7, PHP 8)
文件读取
SplFileObject::__toString — 以字符串形式返回文件的路径
如果没有遍历的话只能读取第一行,且受到open_basedir影响
SimpleXMLElement
解析XML 文档中的元素。 (PHP 5、PHP 7、PHP 8)
SimpleXMLElement::__construct — 创建一个新的 SimpleXMLElement 对象
XXE
我们查看一下其参数:
根据官方文档,发现当第三个参数为True时,即可实现远程xml文件载入,第二个参数的常量值设置为2即可。
利用可参考赛题:[SUCTF 2018]Homework
ReflectionMethod
获取注释内容
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
ReflectionFunctionAbstract::getDocComment — 获取注释内容
由该原生类中的getDocComment方法可以访问到注释的内容
同时可利用的原生类还有ZipArchive– 删除文件等等,不在叙述
————————————————
版权声明:本文为CSDN博主「Christ1na」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_53287512/article/details/123879744