NodeJS Headless 动态漏扫爬虫学习记录(漏洞检测篇)

2020-01-10 约 279 字 预计阅读 2 分钟

声明:本文 【NodeJS Headless 动态漏扫爬虫学习记录(漏洞检测篇)】 由作者 Passer6y 于 2020-01-10 09:40:53 首发 先知社区 曾经 浏览数 253 次

感谢 Passer6y 的辛苦付出!

NodeJS Headless 动态漏扫爬虫学习记录(漏洞检测篇)

讲道理有点标题党了,这篇文章主要聊一聊结合爬虫实现漏洞检测的思路,以及目前用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

关键词:[‘安全技术’, ‘WEB安全’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now