pikachu---php反序列化、XXE、SSRF
php反序列化:
序列化serialize()
通俗的说就是把一个对象变成可以传输的字符串。
比如下面是一个对象:
class S{
public $test="pikachu";
}
$s=new S(); //创建一个对象
serialize($s); //把这个对象进行序列化
序列化后得到的结果:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
O:代表object
1:代表对象名字长度为一个字符
S:对象的名称
1:代表对象里面有一个变量
s:数据类型
4:变量名称的长度
test:变量名称
s:数据类型
7:变量值的长度
pikachu:变量值
反序列化unserialize()
把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。
$u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
echo $u->test; //得到的结果为pikachu
漏洞原理:
序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题。
常见的几个魔法函数:
- __construct()当一个对象创建时被调用
- __destruct()当一个对象销毁时被调用
- __toString()当一个对象被当作一个字符串使用
- __sleep() 在对象在被序列化之前运行
- __wakeup将在序列化之后立即被调用
漏洞演示:
在php网站根目录新建1.php文件写入代码构造payload,然后通过网页访问来序列化输出结果。
代码:
<?php
class S{
var $test = "<script>alert('xss')</script>";
}
echo '<br>';
$a = new S();
echo serialize($a);
?>
成功弹窗。

查看网页源代码,得到payload

复制得到的payload粘贴到本关,点击提交,成功弹窗。

我们提交一个序列化好的内容,里面的变量是一个恶意的JavaScript,后台进行反序列化的过程中会自动调用魔法函数并将结果echo到前端。
总的来说就是通过一个反序列化的接口导致了一个XSS的执行。
XXE
全称:
xml external entity injection,即xml外部实体注入漏洞。
原理:
攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题。
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
现在很多语言里面对应的解析xml的函数默认是禁止解析外部实体内容的,从而也就直接避免了这个漏洞。
在PHP里面解析xml用的是libxml,在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的。
XML是一种可扩展的标记语言,用来存储和传输数据。
XML文档格式:

DTD(XML第二部分,存在XXE漏洞)
全称:
Document Type Definition,即文档类型定义,用来为XML文档定义语义约束。

漏洞产生原因:
利用XML第二部分DTD外部引用可支持http,file,ftp等协议。
如果一个接口支持接收XML数据,且没有对XML数据做任何安全上的措施,就可能导致XXE漏洞。
simplexml_load_string()
函数转换形式良好的XML字符串为SimpleXMLElement对象。
案例演示:
首先查看后台源代码:

先传一个内部实体,正常显示到页面。
输入
<?xml version = "1.0"?>
<!DOCTYPE note [
<!ENTITY hacker "ESHLkangi">
]>
<name>&hacker;</name>

再传一个外部实体,例如获取http://192.168.18.21/Less49.txt文件信息,发现成功在页面执行显示了。
输入
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "http://192.168.18.21/Less49.txt">
]>
<x>&f;</x>

SSRF
全称:
Server-Side Request Forgery,即服务器端请求伪造。
漏洞产生原因:
大多是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制,导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据。
数据流:攻击者--->服务器--->目标地址
根据后台使用的函数的不同,对应的影响和利用方法不同。
PHP中下面函数的使用不当会导致SSRF:
- file_get_contents()
- fsockopen()
- curl_exec()
如果一定要通过后台服务器远程去对用户指定或者预埋在前端的请求的地址进行资源请求,可以做好目标地址的过滤。
SSRF(curl):
打开页面后点击页面链接,发现返回了普金诗的内容。
查看后台源代码:

直接修改URL为同网段的其他主机地址的端口号,测试其端口是否开启,攻击者就可以利用端口攻击其他主机。
输入http://192.168.18.11:3306,发现成功测出其3306端口开启。

curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP。
SSRF(file_get_content):
打开页面后点击页面链接,发现返回了诗的内容。
查看后台源代码:

可以访问其他主机地址,但不能检测端口是否开启。
输入192.168.18.11,成功访问。

输入192.168.18.11:3306,页面报错警告信息。

输入php://filter/read=convert.base64-encode/resource=ssrf.php,可以读取PHP文件源码。

将回显到页面的64进制编码转换即可得到php文件源码。
说明可以访问其他主机地址,但不能测试其他主机端口号,也可以通过64进制编码获得php文件内容。

浙公网安备 33010602011771号