如果在代码审计中有反序列化点,但是在原本的代码中找不到可利用的类时,可以考虑使用php中的一些原生类
有些类不一定能够进行反序列化,php中使用了zend_class_unserialize_deny来禁止一些类的反序列化
SoapClient __call方法进行SSRF
使用前提:
- 需要有soap扩展,且不是默认开启,需要手动开启
- 需要调用一个不存在的方法触发其__call()函数
- 仅限于http/https协议
soap是什么
soap是webServer的三要素之一(SOAP、WSDL、UDDI)
WSDL用来描述如何访问具体的接口
UUDI用来管理、分发、查询webServer
SOAP是连接web服务和客户端的接口
简单地说,SOAP 是一种简单的基于 XML 的协议,它使应用程序通过 HTTP 来交换信息。
php中的soapClient类
php中的scapClient
类可以创建soap数据报文,与wsdl接口进行交互。
用法:
1 | public SoapClient::SoapClient ( mixed $wsdl [, array $options ] ) |
正常情况下的SoapClient类,调用一个不存在的函数,会去调用__call方法,发出请求
SoapClient
发出的请求包的user_agent
是完全可控的,结合CRLF注入可以构造一个完全可控的POST请求,因为POST请求最关键的Content-Length
和Content-Type
都在user_agent
之下
如果是GET请求,就简单得多,只需要构造好location就可以了。
需要注意的是,SoapClient只会发出请求,而不会收到响应。
一个例子:flag.php
1 |
|
index.php
1 |
|
此时,构造exp.php为:
1 |
|
__toString方法进行XSS
Error
使用条件:
- php7版本
- 开启报错的情况下
1
2
3
4
5
6
7
8
$a = new Error("<script>alert(1)</script>");
$b = serialize($a);
$b = urlencode($b); // 因为有不可见字符,所以url编码一下
echo $b;
// 测试
echo unserialize(urldecode($b));
Exception
使用条件:
- 适用于php5、7版本
- 开启报错的情况下
1 |
|
实例化任意类
ZipArchive::open 删除文件
使用条件:
- 要调用对象的额open函数,且open函数中的参数可控
1 | $a = new ZipArchive(); |
GlobIterator 遍历目录
使用条件:
- 遍历对象
1 | GlobIterator::__construct(string $pattern, [int $flag]) |
使用例子:
1 | $newclass = new GlobIterator("./*.php",0); |
于此类似的还有DirectoryIterator
和FilesystemIterator
1 | $a = new DirectoryIterator("glob://*.php"); |
SimpleXMLElement XXE
用来表示XML文档中的元素
一个例子:
1 |
|
SplFileObject 读文件、SSRF、Phar反序列化
1 | $a = new SplFileObject("/etc/passwd"); |
以上直接读文件只能读取第一行的内容,可以使用php伪协议读取base64后的内容
1 | $a = new SplFileObject("php://filter/read=convert.base64-encode/resource=/etc/passwd"); |
SplFileObject
参数还可以设置为http协议,用于ssrf;设置为phar,用于phar反序列化。
SQLite3 创建空白文件
前提:需要有sqlite3扩展,且不是默认开启,需要手动开启
1 |
|
Imagick类上传文件
需要安装有Imagick扩展
如下:
1 | // test.php |
1 | POST /test.php?1=Imagick&2=vid:msl:/tmp/php* |
这将会导致php崩溃,上传的文件保留在/tmp目录下。