php内置类小结
本文最后更新于:2023年6月5日 下午
[TOC]
php内置类小结
Error、Exception进行xss、绕过hash比较
Error类
Error(PHP 7, PHP 8) 是所有PHP内部错误类的基类。
- 使用与php7以后的版本
- 需要有报错的情况
Error类是php的一个内置类,通常用于自定义一个Error,在php7版本后适用,可能存在xss漏洞,因为内置了一个 __toString()
方法。常用于php反序列化中,如果有个pop链走不通了,可能需要使用这个类做一个xss,当php对象被当作一个字符串输出或使用的时候(如:echo
)会触发 __toString()
方法
下面我们来测试一下如何使用Error类构造xss
测试代码:
1 |
|
poc
1 |
|
测试一下:
成功触发xss漏洞
Exception类
- php5、7版本以后
- 开启报错
触发xss和上面一样,此处不再赘述
使用Error、Exception内置类绕过md5、sha1等哈希比较
我们详细介绍一下Error、Exception类
Error类详解
1 |
|
类属性:
- message:错误消息内容
- code:错误代码
- file:抛出错误的文件名
- line:抛出错误在该文件中的行数
类方法:
Error::__construct
— 初始化 error 对象Error::getMessage
— 获取错误信息Error::getPrevious
— 返回先前的 ThrowableError::getCode
— 获取错误代码Error::getFile
— 获取错误发生时的文件Error::getLine
— 获取错误发生时的行号Error::getTrace
— 获取调用栈(stack trace)Error::getTraceAsString
— 获取字符串形式的调用栈(stack trace)Error::__toString
— error 的字符串表达Error::__clone
— 克隆 error
Exception类详解
1 |
|
类属性:
- message:异常消息内容
- code:异常代码
- file:抛出异常的文件名
- line:抛出异常在该文件中的行号
类方法:
Exception::__construct
— 异常构造函数Exception::getMessage
— 获取异常消息内容Exception::getPrevious
— 返回异常链中的前一个异常Exception::getCode
— 获取异常代码Exception::getFile
— 创建异常时的程序文件名称Exception::getLine
— 获取创建的异常所在文件中的行号Exception::getTrace
— 获取异常追踪信息Exception::getTraceAsString
— 获取字符串类型的异常追踪信息Exception::__toString
— 将异常对象转换为字符串Exception::__clone
— 异常克隆
我们可以清楚的看到,两个类都带有 __toString()
方法,将异常对象转化为字符串
我们以Exception
为例,查看一下异常对象的字符串:
1 |
|
发现这会以字符串的方式输出报错,并且包含当前的错误信息:payload
和 当前报错的行号 3
,但是传入的错误代码2
没有显示出来
我们看一下另一个例子:
1 |
|
输出结果:
1 |
|
我们发现:这两个异常对象是不同的(异常代码不同)但__toString()
方法的输出的结果一模一样,
因为此时我们控制了 payload
和 行号2
一致(这里写在一行就是为了保证行号一致)
我们可以利用这个特性去绕过**md5()、sha1()**等哈希比较 。 Error用法一致(注意php版本)
例题:[2020 极客大挑战]Greatphp
1 |
|
这一题就可以使用这个特性去绕过哈希比较,我在另一篇文章写了,此处不再重复
1 |
|
使用DirectaryIterator、Filesystemlterator、Globlterator内置类读目录
Directorylterator
- (PHP 5, PHP 7, PHP 8)
DirectoryIterator
与glob://协议
结合可以进行目录读取
1 |
|
成功读取到根目录的文件
FilesystemIterator
- (PHP 5 >= 5.3.0, PHP 7, PHP 8)
1 |
|
从官方文档看出这两个类是继承关系,FilesystemIterator
内置类也有一个 __toString()
方法
我们同样可以使用glob伪协议
读取目录:
1 |
|
并且从图中就可以看出这两个原生类的些许区别了,Filesystemlterator
会以绝对路径的形式展现,而DirectoryIterator
仅显示出当前目录下的文件信息
一句话DirectoryIterator、Filesystemlterator
DirectoryIterator
1 |
|
FilesystemIterator
1 |
|
Globlterator
- (PHP 5 >= 5.3.0, PHP 7, PHP 8)
与前两个类的作用相似,GlobIterator
类也是可以遍历一个文件目录,使用方法与前两个类也基本相似。但与上面略不同的是其行为类似于使用 glob()
函数,可以通过模式匹配来寻找文件路径。
1 |
|
看了一下文档发现该原生类是继承FilesystemIterator的,所以也是以绝对路径显示的
(需要注意的是,我们使用GlobIterator只需要输入路径即可,不需要添加glob://)
SplFileObject 读取文件内容
- (PHP 5 >= 5.1.0, PHP 7, PHP 8)
SplFileObject内置类存在 __toString()
方法
使用SplFileObject
类读取 /etc/passwd
文件内容
1 |
|
使用SimpleXMLElement类进行XXE
SimpleXMLElement 这个内置类用于解析 XML 文档中的元素。
可以看到当我们设置SimpleXMLElement类构造方法的 data_is_url
参数为:true
时,我们可以实现远程包含xml文件,然后data
参数就设置为xml的远程地址即可,第2个参数我们设置为2即可
然后我们xml文件外带数据进行xxe即可
使用SoapClient类进行SSRF
- (PHP 5、PHP 7、PHP 8)
SoapClient 类为» SOAP 1.1、 » SOAP 1.2服务器提供客户端。它可以在 WSDL 或非 WSDL 模式下使用。
PHP 的内置类 SoapClient 是一个专门用来访问web服务的类,可以提供一个基于SOAP协议访问Web服务的 PHP 客户端
SoapClient
类的构造函数如下:
1 |
|
- 第一个参数是用来指明是否是wsdl模式,将该值设为null则表示非wsdl模式。
- 第二个参数为一个数组,如果在wsdl模式下,此参数可选;如果在非wsdl模式下,则必须设置location和uri选项,其中location是要将请求发送到的SOAP服务器的URL,而uri 是SOAP服务的目标命名空间。
SoapClient类还有一个 __call()
方法,当我们调用对象中不存在的方法时会触发 __call()
方法
当 __call()
方法被触发后,可以发送http、https请求。正是由于这个方法,可以导致SSRF漏洞
我们测试一下:
1 |
|
首先在服务器监听9996端口,运行代码:
服务器成功收到请求
但是它只局限于http、https协议,没什么用。
如果存在CRLF漏洞(\r\n),我们可以通过 SSRF+CRLF组合拳插入任意的HTTP头
ReflectionMethod内置类获取注释内容
- (PHP 5 >= 5.1.0, PHP 7, PHP 8)
ReflectionFunction
类的getDocComment()
方法可以获取注释内容
1 |
|