NodeJS Headless 动态漏扫爬虫学习记录(漏洞检测篇)
2020-01-10 10:40:53 Author: xz.aliyun.com(查看原文) 阅读量:452 收藏

讲道理有点标题党了,这篇文章主要聊一聊结合爬虫实现漏洞检测的思路,以及目前用burpsuite插件实践过程的记录。

工作流程

结合上一篇爬虫篇来看,这里整个的工作流程就像这样:
浏览器插件同步Cookie -> Server -> Spider -> 正向代理(Brup、Xray等)实现漏洞检测

懒得画图了,脑补一下8

有心捣鼓的师傅会发现在我开源的爬虫CrawlerVuln中,其实在module/Crawler.js中注释掉了一行代码:'--proxy-server=http://127.0.0.1:8080',puppeteer在启动时可以配置一个代理,包括http、https、socks5等类型,配合一些正向代理漏扫工具,比如xrayGourdScanV2等等,但是觉得别人写的工具又不如自己写的用着舒服,计划 第一版先借助Burp插件实现自己一些扫描的需求,第二版将考虑写一个http正向代理,实现一个代理池去自定义规则扫描检测漏洞模块。

漏洞检测

使用Puppeteer+Brup组合使用,让Headless流量全走Burp出去,配合好写的插件进行漏洞检测。这样的好处是我不用在写爬虫的时候去hook网络请求(为了获取链接)。

思考:如何发更少的数据包,发现更多的漏洞
想这个问题的原因有几点,区别于传统扫描器的大量发生数据包,实战环境中不是太允许我们发生大量的有害payload请求去测试,一来可能会被各种防御软件拦截导致封IP、或者Cookie强制注销,得不偿失无疑造成大量测试点遗漏;二来我们的目的只是为了找到短板,找到漏洞,而不是相较于传统扫描器找全漏洞。我们就可以根据自己的想法写一些自己想测试的规则,用最少的数据包发现漏洞。

以SQL为例,分享一个在lufei师傅博客看到的挺有意思的点

11^sleep(5)#'^sleep(5)#"^sleep(5)#


11^sleep(5)#')^sleep(5)#")^sleep(5)#

当然这样检测也有缺陷,比如limit、insert、update注入不能很好的检测,但也启发着我们可以从这个角度来思考各种其他的探测场景。

BurpSuite插件开发入坑记录

环境配置

从burp导出接口文件:burp->extender->apis->save interface files

配置IDEA,参考这篇文章

命令行编译

javac -d build src/burp/*.java
jar cf plugin.jar -C build burp

动态调试
破解版动态调试和付费版有一点不太一样,需要指定一个-Xbootclasspath/p:burp-loader-keygen.jar破解文件的路径。

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Xbootclasspath/p:burp-loader-keygen.jar -jar -Xmx4G burpsuite_community.jar

接着在IDEA里边配置远程调试环境:


接着保持burp中打包的代码和本地代码一致就可以下断点debug了。

模板

一个必须要实现的接口和方法

public class BurpExtender implements IBurpExtender, IHttpListener
{
    private IBurpExtenderCallbacks callbacks;
    private IExtensionHelpers helpers;
    private PrintWriter stdout;
    private String ExtenderName = "SQL Inject Scan";
    @Override
    public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks){
        stdout = new PrintWriter(callbacks.getStdout(), true);
        callbacks.printOutput("Author: Passer6y");
        this.callbacks = callbacks;
        helpers = callbacks.getHelpers();
        callbacks.setExtensionName(ExtenderName);
        callbacks.registerHttpListener(this);
    }
}
    @Override
    public void processHttpMessage(int toolFlag, boolean messageIsRequest,IHttpRequestResponse messageInfo)
    {
        // 接着当有HTTP请求响应时,会调用该方法,我们只需要通过翻阅文档摸清这几个参数的类型所对应的用法即可
    }

拆解&重组数据包

大部分漏洞检测需求一般都在于处理HTTP的请求和响应中,这里以SQL注入探测插件为例,在爬虫爬行时,需要对所有参数进行各种payload的添加。

@Override
public void processHttpMessage(int toolFlag, boolean messageIsRequest,IHttpRequestResponse messageInfo)
{
    if(!messageIsRequest){      // 请求结束之后
        if ((toolFlag == 4)) {//经过Proxy工具的流量
            for(byte[] payload:payloads){
                attack(messageInfo, payload);
            }
        }
    }
}

在attack函数中对messageInfo参数进行数据包解体,添加payload,构造新的参数:

public void attack(IHttpRequestResponse messageInfo, byte[] payload){
    List<int[]> matches = new ArrayList<>();
    IHttpService iHttpService = messageInfo.getHttpService();
    IRequestInfo analyzeRequest = this.helpers.analyzeRequest(messageInfo);
    // this.stdout.println("[*] Current URL:" + analyzeRequest.getUrl());
    List<IParameter> paraList = analyzeRequest.getParameters();
    for (IParameter para : paraList){
        if (para.getType() == 0 || para.getType() == 1){
            //0是URL参数,1是body参数,2是cookie参数 
            String key = para.getName();
            String value = para.getValue();
            try {
                String changedValue = value + this.helpers.bytesToString(payload);
                byte[] new_Request = messageInfo.getRequest();
                IParameter newPara = this.helpers.buildParameter(key, changedValue, para.getType()); //构造新的参数
                new_Request = this.helpers.updateParameter(new_Request, newPara); //构造新的请求包
                IHttpRequestResponse messageInfoExp = this.callbacks.makeHttpRequest(iHttpService,  new_Request); //  发送含poc的包

添加issue

添加issue的时候摸索了一会,有两种办法添加issue,很多插件都是在调用IScannerCheck接口的doPassiveScan或者doActiveScan方法,接着通过return一个IScanIssue的数组,然后burp就实现添加了添加issue的过程,但是在爬虫爬行的过程中,我们想要实现的是将经过proxy的流量进行探测,探测到的结果添加issue,在这里分享一个个人习惯,搜索一个issue关键字,然后在左边api里边上下滑动api接口,可以快速定位到相关方法:

this.callbacks.addScanIssue(new CustomScanIssue(
        iHttpService,
        analyzeRequest.getUrl(),
        new IHttpRequestResponse[]{callbacks.applyMarkers(messageInfoExp, null, matches)},
        "SQL Time Delay Injection",
        "Payload: " + key+"="+changedValue + " ,sleep time: " + Long.toString(sleepTime/1000) + ", Netwok Delay: " + Long.toString(networkDelay) + "ms",
        "High"));

最后推荐给一些新入坑的小伙伴一些建议,可以多看文档,多看官方的demo,在Github学习优秀的插件代码

开源

最后奉上源码,欢迎一起交流~
https://github.com/Passer6y/SQLScan


文章来源: http://xz.aliyun.com/t/7070
如有侵权请联系:admin#unsafe.sh