点击上方蓝色字体,关注我们
接下来的话就开始讲xxe的相关内容,我们先来了解一下xxe的一个基本概念。
概念全称是 xml的外部实体注入漏洞,会很明显的感觉到,和xml有非常密切的关系的。所以一开始会先讲xml的一些相关基础知识,然后再讲到一些具体的案例。xxe漏洞,它是发生在一个应用程序去解析xml输入的时候,没有禁止外部实体的加载。所以它的关键点其实是在一个外部实体的作用在这里,或者说很多情况下都是一个外部实体允许加载,导致的问题产生。它可以去加载外恶意的外部文件,到造成一个文件读取,命令执行,内网端口、扫描攻击内网站,发起DOS攻击等危害。
这种文件读取,其实可以被理解成是xxe的一个常规操作,但像命令执行的话,它的条件比较苛刻,是在特定条件下,比如说存在某些特定的扩展插件之类的,那么他有可能去执行内网端口、扫描攻击内网站,内外网网站发起DOS攻击,这些也是基本上来说存在xxe就可以去触发的。触发点是有几个条件,第1个能够上传xml文件,对内容没有过滤,导致可以生成a的xml文件,总结起来就是说能够去在对方服务器中去生成一个带有恶意代码的xml文件。同时他们也会去解释。就解析有恶意代码的x版文件,那么就会产生漏洞。所以说的话,它的前提条件是必然存在一个你能够传的,然后又能够解析的这么一个地方。 XML基础知识因为可能很多一开始打ctf都没接触过,而且相对来说它xxe的这种题目比较不是特别多,包括我接触的也不是很多。所以这块讲的可能就没有那么好。但是我觉得这块内容的话,就是说即使你不会真的遇到了,也不妨你去做题,因为像这种知识你临时去查历史去学是完全来得及的。这块的话可能偏向研发一点,可以简单的了解一下。
它是一种可扩展标记语言。语法简单知道一下,因为很多时候利用配套的。它是被用于去传输和存储数据的,参考w3c上的说法,把数据从html中分离开来,然后简化数据的一个传输和存储的一个过程。我们这里可以先看一下后面的简单的一个样式,看到在一开始的结构,是去声明一个版本号。
然后下面的话就是它的一些内容了。然后像这种假设我这里定一个note,这个note里面它到底有哪些内容的话,比如to、from、heading、body这种的话其实可以随便定义,比如说现在我想少一个想多一个,其实都没有关系,所以说它是没有预定义标签的。
但是你会发现他说语法规则中提到就是说必须有一个根元素,根元素 note,其实这个就可以理解为是根元素。然后元素都必须有一个关闭标签,所以你会看到这边它有点像html。前面一个标签了,后面有个闭合标签,这是标准的一个语法。然后标签的大小就敏感,也就是说前后是一致的。像这边你是to,你不能这个是大写的to这是不允许的,它会报错的。然后元素必须被正确的嵌套,以及元素值,属性值必须加引导。如果说这个note的地方,我们其实可以看到,如果你定义了,是必须要对它做一个赋值的。那么可以来看一下,我们就访问一下。
你会看我是通过浏览器直接去访问这xml文件,浏览器的话,它其实也自带解析解释器的。那么它会显示出来。如果说我这边改成一个大写的T,保存一下。我这边在刷新的时候,它会报错的,是非配对的标签。
所以说其实有时候配合浏览器,也能帮助你去查一些语法上的错误。比如说我这里去定义一个 data,这样子是可以的,就相当于我多了一个data的属性,那么他这个地方是要对他做,就不能这样去定义了,不赋值。
比如说这样子,这样就可以了。但是你要注意到的就是说,我这个地方要是没有引号是不允许的。
讲到语法中的一个点就是说,我们看到这个标签之中,随便输什么内容,它这边都会打印出来。只有两个符号会有歧义,比如说写小于号的时候,就会报格式错了。因为他在小于号和 n的服务的情况下,就会产生的歧义,会认为小于号就是一个标签开始的一个位置,所以他就会报错。
那么这种时候怎么办?实体引用,我们就可以把小于号换成这种实体的符号。1、实体引用
接下来讲的比较重要的一个内容就是DTD文档类型定义。
可以理解成就可以字面理解,文档类型定义,其实它就相当于去定义一个文档的类型,它的作用是去定义一个xml文档的合法结构模块,这个文档类型定义的时候就相当于提前定义好的,那么其实我有时候也可以理解成是这样的一个情况。从某种程度上说,有时候我感觉他也有点类似于序列化的那种一种情形。但是它这个结构定义的话,它可以直接写在xml文件中,也可以去外部引用这个结构。
我们可以来看一下,这个的话它就是一个内部声明的状况。
2、内部声明
第1行,还是一个version,第2行DOCTYPE,此文档是note类型的一个文档。这个时候去定义文章结构。接下来element就是元素的意思,它定义的就是 note里面,它有4个元素,里面有这个定义元素类型to from head in body。意思是被解释的字符数据,可以理解它是会被一些解释的一个文本。基本上你可以大致是这样一个类型结构。这个结构我们现在只写在 xml文档里面的,下面的话对于那些填充数据结构是对应的,顺序也是对应的。
这种从外部引入的时候就有可能带来一个危害,就拿文件包含来说,如果文件包含只包含本地文件,那么利用上来说你可能还是要正常流程去审计去发现漏洞,但是一旦它允许外部远程报案的时候,那么它影响就会变得非常容易去实现了。
这地方也是一样,一旦允许外部载入文件的时候,那么就有可能带来一个大的危害。这就是一个外部声明。
然后再往下的时候讲到一个关于声明的问题了。DTD文档中定义了 mail,然后他接下来是定义mail中的一个内部实体的声明,就假如说我这边去定一个hacker,然后就实体,实体名称,实体值。相当于我这边去定义的值,这边能够去调用这个值。这边输出的值其实就是这里面的字,那么再继续往下,继续往下的时候,你会发现它可以外部这个实体也是可以去外部引入的。实体化部门的时候,我这个地方其实就已经开始尝试去利用了。他这个地方就是说它是个实体名称,然后system去调做一个远程的调用。然后同样这个地方是在XML文档中去引用的。
这个路径其实在讲SSRF的时候,通过file协议,它其实能够实现类似一个文件读取的操作,既然讲到了就是说实体,然后实体名称,然后后面的值 system这个的话,它其实就相当于做配合,file协议去读取文件,读了之后它会赋给hacker这个值。做个引用,相当于它就能够显示出来。
但是假如我用php去解析它的时候,因为php它支持这种协议,你会看到这边就已经显示一个值了。
回过来看一下简单的代码,这边主要是为了显示XML文件的一个载入过程。就说if file_get contents。文件读取,那只不过我们现在用了一个PHP input,能够去接受一个原生的post的数据,
我这边能够传递进去,然后传递进去之后,它通过 simplexml_load_string,去做一个载入,相当于做一个用PHP自带的 xml解释器去解析一下,那么它就会触发里面的内容。然后获得之后的话,就把它以当作key value的形式做一个输出。要注意到一个点就是说,这个k值来自于哪里?
假如说不会去打印根元素的内容,但是会打印根元素中的4个它的子元素的一个那种标签的名称。所以说这个地方就是不同代码的情况下,要基于当时的逻辑情况去做一个分析的。刚刚这样就已经实现了一个文件读取,这就是非常简单的一种XMl文件的一个基本的使用。它使用场景其实大部分来说文件读取。继续往下看,xml不同语言写的,解释是有xxe的。
然后xml2是PHP编译的时候自带会带来这个东西的,支持file http ftp。
然后Java、donate,但是所以你会发现每种协议它支持的协议是不一样的,导致说发现一个xxe,在不同语言框架下要利用的话,你写的payload会有一定的区别,所以这里需要注意到的。
然后像这边的话就相当于extension required的,就是说你去加了扩展之后,他能支持的协议就会更多了。然后你们会看到这expect。如果存在扩展的话,那么就有可能去实现。刚才我们看到的xxe能够实现命令执行的一个条件,大部分情况现在来说都是expect在php中一个利用。
3、参数实体
实体这个概念我们先简单的来了解一下。参数实例的话,它是只用一个DTD文档,DTD和文章内部子集中的。xml的规范中定义中,只有在DTD中才能够称引用参数实体,就是说这种参数实体它只能够用在DTD中。理论上的理论是分开来的。参数实体的引用是以百分号开头的,并且参数实体的引用都是在DTD都是理解解析的。替换文本将变成DTD的一部分。所以说这个地方它能够有一个获取变量值,然后去替换引用这个概念。
比如说这样子:
我们是DTD5,你会发现这个地方能够显示出这个值, 发现它其实就在这个地方,相当于是这条实体中的一个内容,这个值其实应该就是后面实体的一个内容。
4、简单利用
再看一下两次运用的话应该是就DTD7效果。它的内容可以看一下。你会看到像我这边的话定义了两就是第1个也是一个DTD的,然后这里有个any,带有任何内容元素,就是我们随便写那种杂写东西,然后里面有 argument的,下面就是一些实体,实体中的话要有空格。
开始定义了一个实体,就是参数实体,我这边定的system,flag.txt,像我现在目录一下,这边有个flag.txt里面就有个flag字符串,然后的话我这边用file去读取,那么它肯定是能够读取到 flag.txt的,所以说像%evil其实相当于 flag.txt中的一个内容。第2个实体是能够去做一个读取。那么这个的话你会看到它是远,它是这边用的是一个.xml文件,它其实就相当于远程去载入一个DTD的文档。然后我们可以来看一下dtd7_2.xml的内容,发现它其实就是一句,也是一个实体。然后实力的话就是2%,其实就是这样的一句话,你可以看它的内容,实体 send system。你会发现它这里定义send就作为远程的去做一个调用。这system本身来说,它其实应该是远程去载入的东西,那么他要做载入的时候,他肯定能够发起一个请求。
比如说我这边去发送一个参数,跟上去传过去的话,那么它就会保存到一个我那文件里面去。
那么像现在理解上来说,我就是拼接上evil,这个evil其实就是flag.txt的内容,那会拼接过来,然后如果说这个人触发的时候,那么他就会把flag.txt的内容传递出来,像我在这边远程的情况下,我就会接收到。
那么我们再来看一下,引了xxe,作用是system相当于却引入了这个文件。相当于xxe之后,这个地方就相当于有了这一句实体在。然后接下来是%2的时候相当于他就会去有这句话的一个作用,在这边这句话就会起作用,那么他就会去发远程请求,所以说像这个值它是默认情况下,它自然就会去读回来的。读回来之后他就会赋给evil,就会赋给这边。然后在远程载入这句话之后,然后赋给2%去触发他的条件,触发他发起远程请求,之后获取值。然后xxe去引入这句话,这句话引进来之后,那么这个evil就会被替换成这个地方的evil。所谓 flag.txt的内容,然后在百分号去触发,请求就会发出去,然后就会拿到 flag。
这个的话就是一个DTT的XXE的一个盲攻击的基本的雏形。后面的话我们会看一下一些例子,一些例题之类的,给大家讲一下。这一次的话我们就先讲到这里。
戳