SoapClient反序列化SSRF组合拳
前言
有的时候我们会遇到只给了反序列化点,但是没有POP链的情况。可以尝试利用php内置类来进行反序列化。
魔术方法
魔术方法详细的讲解可以移步另一篇文章
https://cbatl.gitee.io/2020/04/22/PHPserialize/
- 构造函数
__construct
对象被创建的时候调用- 析构函数
__destruct
对象被销毁的时候调用- 方法重载
__call
在对象中调用一个不可访问方法时调用- 方法重载
__callStatic
在静态上下文中调用一个不可访问方法时调用- 在给不可访问属性赋值时,
__set()
会被调用。- 读取不可访问属性的值时,
__get()
会被调用。- 当对不可访问属性调用
isset()
或empty()
时,__isset()
会被调用- 当对不可访问属性调用
unset()
时,__unset()
会被调用__sleep()
在serialize()
函数执行之前调用__wakeup()
在unserialize()
函数执行之前调用__toString
在一个类被当成字符串时被调用(不仅仅是echo的时候,比如file_exists()判断也会触发)
CRLF攻击
什么是CRLF,其实就是回车和换行造成的漏洞,十六进制为0x0d,0x0a
,在HTTP当中header
和body
之间就是两个CRLF分割的,所以如果我们能够控制HTTP消息头中的字符,注入一些恶意的换行,这样就能注入一些会话cookie和html代码,所以crlf injection 又叫做 HTTP Response Splitting。
SoapClient与反序列化
SoapClient::__call
https://www.php.net/manual/zh/soapclient.call.php
__call()
方法是对象中调用一个不可访问方法时调用
SOAP:简单对象访问协议
底层通讯协议为HTTP,传输数据格式为XML。
测试SoapClient类调用一个不存在的函数,会去调用__call()
方法
1 |
|
nc监听6888端口
从结果我们可以看到SOAPAction参数可控,我们可以在SOAPAction处注入恶意的换行,这样一来我们POST提交的header就是可控的,我们就可以通过注入来执行我们想要执行的操作了。
尝试传入token,发现新的问题,Content-Type在SOAPAction
的上面,就无法控制Content-Typ
,也就不能控制POST的数据
在header里User-Agent
在Content-Type
前面,通过user_agent
同样可以注入CRLF,控制Content-Type
的值
这个点是百度看到的,文章地址:https://zhuanlan.zhihu.com/p/80918004
尝试控制token
1 |
|
成功控制
使用SoapClient反序列化+CRLF可以生成任意POST请求。
Deserialization + __call + SoapClient + CRLF = SSRF
题目分析
打开题目看到只有几行代码
1 |
|
还有另外一个flag.php文件
1 | $xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); |
$xff
经过了array_pop()
的处理,这个函数的作用是弹出数组最后一个单元(出栈),当我刚开始只传入了一个127.0.0.1时发现并没有利用成功,也就是说,此时数组内的最后一个ip并不是127.0.0.1,于是传入多个127.0.0.1进行尝试,发现传入两个即可成功绕过。
在百度其原理是看到了Y4tacker师傅的解释
最终exp
1 |
|
通过vip传入参数,然后访问flag.txt即可!
参考链接:
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=26gqzfgivusk8