CTFphp 代码审计strpos ()函数漏洞XXE 漏洞xinclude ()
0x00 第⼀次尝试
这个题是别⼈⼀个⽉前问我的⼀个题,当时忙,看了下,发现好像不会,就先放着了。。。
0x01 第⼆次尝试这个题之前弄了好⼀会,都没搞出来,⼀直没时间,今天下定决定把它做出来(,我最后花了半个⽉)原代码如上,采⽤oop的⽅式来写的,先看loginViaXML()相关函数。
hightlight_file()以php格式⾼亮来输出⽂件内容;
_FILE_,php内置常量,当前⽂件的绝对⽬录;
strops()⽤来查字符串A当中是否存在字符串B(从左往右),如果有,返回位置,从0开始计数,如果没有返回false;sprintf()只格式化,返回字符串,不输出字符串,printf()同样也是格式字符串,但是会输出字符串;
SimpleXLElement()实例化xml;
dom_import_simplexml 将xml转化为dom;
$dom->ownerDocument->xinclude(),有点没搞明⽩啥意思,知道的告诉我⼀下,谢谢。 这⾥才是拿flag的重点,⽤这个来包含xml $dom->ownerDocument->saveXML(),将xml放⼊⼀个字符串
其实没明⽩想要⼲什么,⽆⾮是把⽤户和密码加上后格式成新的字符串,然后将字符串实例成对象,接着将XMl对象转成dom,然后⼜把dom转成字符串。。。想了半天没看出来想这和flag有什么关系的。
提交了参数以后,确实能输出。<?php    highlight_file (__FILE__);    class  Login {    public  function  __construct ($user , $pass ) {        $this ->loginViaXml ($user , $pass );      }    public  function  loginViaXml ($user , $pass ) {        if  (          (!strpos ($user , '<') || !strpos ($user , '>')) &&          (!strpos ($pass , '<') || !strpos ($pass , '>'))        ) {                      $format  = '<?xml version="1.0" encoding="UTF-8"?>'.            '<test>'.            '<user v="%s"></user><pass v="%s"></pass>'.            '</test>';                      $xml  = sprintf ($format , $user , $pass );            $datas  = new  SimpleXMLElement ($xml );            $dom  = dom_import_simplexml ($datas );            $dom ->ownerDocument ->xinclude ();            echo  $dom ->ownerDocument ->saveXML ();        }    }}new  Login ($_POST ['username'], $_POST ['password']);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
那就只去构造XXE注⼊呗,但是上⾯的函数中有waf,先来分析下。
strpos($user,'<')指的是提交的username中查<,如果到了就返回数字,必定为真。
!strpos()想成真,那么strpos()⼀定得成假了,假的时候也就是不到指定字符串,即提交数据时不能包含<;或者>,但是不能携带这两字符,就没有办法完成注⼊了。
这⾥就得利⽤!strpos()的⼀个问题了,当strpos()到了特定字符串,并且当这个字符串为开头时,返回的结果会是0,那么此时!strpos()就为真了。
经测试,也就是在开头加上<;或者>就可以绕过waf。
接着构造XXE的poc,好吧,真的弄不出来。凉凉,⼏天了。。有没有⼤佬教⼀下的,放弃了,回头再弄吧。0x02 第三次尝试
⼜尝试了⼀次,⽆果,记录下。由于之前尝试闭合XXE时,在写⼊⽂档定义时,⼀直在提⽰有⽆效的起始tag符号,其实就是<,⽆奈之下就放弃了,但是⼼⾥⼀直觉得有个题没弄出来,就到处问⼈,昨天经过和⼈讨论,有了⼀点新的思路,可惜还是没成功。。。这次思路是闭合<test>
。⽤⾃⼰在本地的环境下测试的闭合语句,构造payload
的情况如下如果没有了办法使⽤&以外,其余的闭合已经正常了,接着将以下payload提交。格式继续错误,查了⼀下,应该是XML的⽂件格式错误,这⾥⼤概是不能出现两个根元素,我这⾥使⽤了两次<test>,⼜失败了,下次继续尝试。
0x03 第N 次尝试
做这个题,真的是把我搞累了,我艹了,QQ⾥⾯的⼤佬全问了⼀遍,要么不理我,要么说看⼀下就没有结果,要么直接就是不会。。。⼼想着谁搞出来搞包烟他表⽰感谢,结果最后还是⾃⼰弄出来了。NMD,NMD,NMD,WC,WC,WCNDY,⼼累了。好了,⽆能狂怒结束,说正紧的。username =>"></user></test><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file :///etc/passwd">]><hehe ><wsl >&xxe ;</wsl ></hehe ><test ><user ><"&password=>"><"
1
2
3
4
5
6
7
8
重点就是这个xinculde()函数,最开始没有理解的xinclude()果然是解题关键,确认后⼜再去查了n 次,最后这⼀次查的信息感觉和⼏前的不⼀样(这是什么⿁情况),这次看得明⽩多了,也许是经历的多了吧hhh
什么是xinclude?
导⼊外部xml⽂档,将外部定义的dtd引⼊当前⽂件,类似于php的include;
为什么要使⽤ xinclude ?
为什么要使⽤ XInclude,⽽不是 XML external entities?
答案是,XML 外部实体有很多众所周知的局限和不便于使⽤的含义,这些因素极⼤地妨碍了 XML 外部实体成为多⽤途包含⼯具。具体来说:
text函数什么意思XML 外部实体⽆法成为⼀个成熟的独⽴ XML ⽂档,因为它既不允许独⽴的 XML 声明,也不允许 Doctype 声明。这实际上意味着XML 外部实体本⾝⽆法包括其他外部实体。XML 外部实体必须是格式规范的 XML(第⼀眼看起来好象没有这么差,但想象⼀下怎样将⽰例 C# 代码包括到 XML ⽂档中)。未能加载外部实体是重⼤错误 (fatal error);严格禁⽌任何恢复。只能包括整个外部实体,⽆法只包括⽂档的⼀部分。
外部实体必须在 DTD 或内部⼦集中进⾏声明。例如,这些含义可能是:要求⽂档元素必须在 Doctype 声明中命名,以及对读取⽅的验证可能需要在其他⽂档的 DTD 中定义⽂档的全部内容模型。
嗯,上⾯都是查的,。。。其中有的碰到过,⽐如之前在研究闭合的时候,DTD怎么写都不对,只能重新闭合构造根元素,闭合构造后⼜提⽰格式错误,这些都是因为XML的限制。
如何使⽤xinclude()?
XInclude 定义了⼀个便于在 XML ⽂档中实现模块化的多⽤途包含机制。包括过程被正式定义为将很多 XML 信息集 (XML Infoset) 合并到单个复合的 XML 信息集中。作者通过包含指令来指定要合并哪些⽂档并控制合并过程。包含指令的 XInclude 语法基于⼤家熟悉的、容易产⽣和处理的 XML 构造:元素、属性和 URI 引⽤。
XInclude ⽀持包含⾮ XML ⽂本⽂档,并允许作者控制恢复过程。例如,您可以提供要包含的默认内容或备⽤⽂档,如果⽆法加载远程资源,就将包括这些默认内容或备⽤⽂档。
XInclude 还⽀持部分 XML 包含,也就是说,您可以定义(通过提供 XPointer 指针)应当包括 XML ⽂档的哪⼀(些)部分。
下⾯是另⼀个介绍性⽰例,它演⽰了如何将外部⾮ XML ⽂本数据包含到 XML ⽂档中。假设您有⼀个存储在服务器上的 XML ⽂档,并且您想让它包含⼀个计数器,该计数器描述⽂档访问的次数:
处理后html页⾯
xinclude 语法
xi:include 元素<?xml version="1.0"?><catalog xi ="/2003/XInclude ">  <p >This document has been accessed  <include href ="so/Counter.aspx?pid=catalog " parse ="text "/> times.</p ></catalog >
1
2
3
4
5<?xml version="1.0"?><catalog xi ="/2003/XInclude ">  <p >This document has been accessed  45453 times.</p ></catalog >
1
2
3
4
5

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。