XXE-lab(全踩坑)实录

在bWAPP中有一关是XML External Entity Attacks (XXE)传送门,比较简单的了解了一下XXE

师傅的博客
浅谈XML实体注入漏洞

XXE漏洞全称XML External Entity Injection即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害
xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件

所以可以先来学习一下XML的相关知识XML 简介

简单了解如下

XML 被设计为传输和存储数据,其焦点是数据的内容HTML 被设计用来显示数据,其焦点是数据的外观
HTML 旨在显示信息,而 XML 旨在传输信息

XML 用于传输数据,而 HTML 用于格式化并显示数据
XML 把数据从 HTML 分离, XML 不是对 HTML 的替代,XML 是独立于软件和硬件的信息传输工具

基本语法

所有 XML 元素都须有关闭标签
XML 标签对大小写敏感
XML 文档必须有根元素
XML 的属性值须加引号

这里着重学习一下实体引用

在 XML 中,一些字符拥有特殊的意义,如果把这些字符放在XML元素中就会产生错误,所以必须用实体引用来代替

XXE-lab(全踩坑)实录_第1张图片
下一个重点是XML验证中的DTD
DTD 简介

DTD 的作用是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构:


  <!ELEMENT to      (#PCDATA)>
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
]> 

文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
详见内部的 DOCTYPE 声明与外部文档声明

DTD元素

XXE-lab(全踩坑)实录_第2张图片
DTD属性

这里重点学习一下DTD实体

实体是用于定义引用普通文本或特殊字符的快捷方式的变量
实体引用是对实体的引用
实体可在内部或外部进行声明

内部实体声明语法

外部实体声明语法

附上实例:

内部实体声明
DTD 实例:

XML 实例:&writer;©right;

外部实体声明
DTD 实例:

XML 实例:&writer;©right;

注: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号(;)

XXE主要是利用了DTD引用外部实体导致的漏洞

XXE-Lab for PHP

XXE-lab(全踩坑)实录_第3张图片
XXE-lab(全踩坑)实录_第4张图片

输入任意账号密码进行抓包

XXE-lab(全踩坑)实录_第5张图片
观察请求包
发现头部:Accept: application/xml, text/xml, */*; q=0.01

XXE-lab(全踩坑)实录_第6张图片

构造XML声明和DTD部分,引用外部实体来进行实体调用



]>
<user><username>&test;username><password>Mikasapassword>user>

并且在元素中引用外部实体参数&test

查看回显

XXE-lab(全踩坑)实录_第7张图片

一般XXE利用分为两大场景:有回显和无回显。有回显的情况可以直接在页面中看到Payload的执行结果或现象,无回显的情况又称为blind xxe可以使用外带数据通道提取数据
xxe-lab是有回显的

看大佬的源码审计


/**
* autor: c0ny1
* date: 2018-2-7
*/

$USERNAME = 'admin'; //账号
$PASSWORD = 'admin'; //密码
$result = null;

libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');//这里面因为没有xml文档所以用的是php的伪协议来获取我们发送的xml文档

try{
     
    $dom = new DOMDocument();//创建XML的对象
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);//将我们发送的字符串生成xml文档。
    $creds = simplexml_import_dom($dom);//这一步感觉相当于实例化xml文档

    $username = $creds->username;//获取username标签的值
    $password = $creds->password;//获取password标签的值

    if($username == $USERNAME && $password == $PASSWORD){
     //将获取的值与前面的进行比较。...
        $result = sprintf("%d%s",1,$username);//注意必须要有username这个标签,不然的话找不到username,就没有了输出了,我们也不能通过回显来获取信息了
    }else{
     
        $result = sprintf("%d%s",0,$username);//与上方相同,都会输出username的值,都可以达到我们的目的
    }    
}catch(Exception $e){
     
    $result = sprintf("%d%s",3,$e->getMessage());
}

header('Content-Type: text/html; charset=utf-8');
echo $result;
?>

还可以进行其他的恶意引入外部实体方式

详见XXE漏洞攻防

XXE-Lab for Java

package me.gv7.xxe;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.*;

@WebServlet("/doLoginServlet")
public class LoginServlet extends HttpServlet {
     
	private static final long serialVersionUID = 1L;
	
	private static final String USERNAME = "admin";//账号
	private static final String PASSWORD = "admin";//密码
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();     
        DocumentBuilder db;
        String result="";
		try {
     
			db = dbf.newDocumentBuilder();
			/*修复代码*/ 
			//dbf.setExpandEntityReferences(false);
			Document doc = db.parse(request.getInputStream());
			String username = getValueByTagName(doc,"username");
			String password = getValueByTagName(doc,"password");
			if(username.equals(USERNAME) && password.equals(PASSWORD)){
     
				result = String.format("%d%s",1,username);
			}else{
     
				result = String.format("%d%s",0,username);
			}
		} catch (ParserConfigurationException e) {
     
			e.printStackTrace();
			result = String.format("%d%s",3,e.getMessage());
		} catch (SAXException e) {
     
			e.printStackTrace();
			result = String.format("%d%s",3,e.getMessage());
		}
		response.setContentType("text/xml;charset=UTF-8");
		response.getWriter().append(result);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
		doGet(request, response);
	}

	/**
	 * 
	 * @param doc 文档
	 * @param tagName 标签名
 	 * @return 标签值
	 */
	public static String getValueByTagName(Document doc, String tagName){
       
        if(doc == null || tagName.equals(null)){
       
            return "";  
        }  
        NodeList pl = doc.getElementsByTagName(tagName);  
        if(pl != null && pl.getLength() > 0){
       
            return pl.item(0).getTextContent();  
        } 
        return "";
    }
}

水平有限不会操作。。

Java XXE漏洞正确修复方法及原理

XXE-Lab for Python

#coding=utf-8

'''
autor: c0ny1
date: 2018-2-7
'''

from flask import Flask, request, url_for, render_template, redirect
from xml.dom import minidom

app = Flask(__name__)
app.config['DEBUG'] = True

USERNAME = 'admin' # 账号
PASSWORD = 'admin' # 密码

@app.route("/")
def home():
    return render_template("index.html")

@app.route("/doLogin", methods=['POST', 'GET'])
def doLogin():
    result = None
    try:
        DOMTree = minidom.parseString(request.data)
        username = DOMTree.getElementsByTagName("username")
        username = username[0].childNodes[0].nodeValue
        password = DOMTree.getElementsByTagName("password")
        password = password[0].childNodes[0].nodeValue
    
        if username == USERNAME and password == PASSWORD:
            result = "%d%s" % (1,username)
        else:
            result = "%d%s" % (0,username)
    except Exception,e:
        result = "%d%s" % (3,e.message)
	
    return result,{
     'Content-Type': 'text/xml;charset=UTF-8'}

def prn_obj(obj):
    print '\n'.join(['%s:%s' % item for item in obj.__dict__.items()])

if __name__ == "__main__":
    app.run()

大佬说是要下载Python Flask 框架,然后运行即可

附上安装教程

XXE-lab(全踩坑)实录_第8张图片
总是遇到奇怪的问题。。

按照提示先解决看看

XXE-lab(全踩坑)实录_第9张图片
呃。彻底裂开。。

再来尝试一下这种方法Windows下安装使用python的Flask框架

XXE-lab(全踩坑)实录_第10张图片一开始还是有点小问题,不过将pip版本升级后就解决了

具体操作按上面的来就行,这里是终于成功了

但是运行过程中还是出错

XXE-lab(全踩坑)实录_第11张图片

我***

XXE-lab(全踩坑)实录_第12张图片

Csharp

大佬说是放vs里,但我不会搞。。

XXE-lab(全踩坑)实录_第13张图片上面的工具栏有一个运行按键,等待运行之后会出来这样一个工具

XXE-lab(全踩坑)实录_第14张图片XXE-lab(全踩坑)实录_第15张图片
网上找的的解决办法是

XXE-lab(全踩坑)实录_第16张图片使用菜单栏工具下的NuGet包管理器,在程序包管理控制台中输入 Install-Package Microsoft.CodeDom.Providers.DotNetCompilerPlatform

静静等待。

。。。

还是没有解决,放弃了

XXE-lab(全踩坑)实录_第17张图片

你可能感兴趣的:(XXE-lab(全踩坑)实录)