高效率开发Web安全扫描器之路(一)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 经常看到一些SRC和CNVD上厉害的大佬提交了很多的漏洞,一直好奇它们怎么能挖到这么多漏洞,开始还以为它们不上班除了睡觉就挖漏洞,后来有机会认识了一些大佬,发现它们大部分漏洞其实是通过工具挖掘的,比如说下面是CNVD上面的白帽子大佬

SRCCNVD

CNVD

![](http://oss.songboy.site/blog/20221129165759.png)

ID

##

SQLMap

AWVS

使

##西

使URL

![](http://oss.songboy.site/blog/20221129170357.png)

1. URL

2. URLIP

3. POC

4.

5. IP

6. banner

7. SQL

一、背景

经常看到一些SRC和CNVD上厉害的大佬提交了很多的漏洞,一直好奇它们怎么能挖到这么多漏洞,开始还以为它们不上班除了睡觉就挖漏洞,后来有机会认识了一些大佬,发现它们大部分漏洞其实是通过工具挖掘的,比如说下面是CNVD上面的白帽子大佬

我想成为大佬要怎么做

我一直觉得自己是一个有梦想的人,我也想有一天自己的ID能出现在排行榜中,于是我凭借着自己那一点开发知识,认真研究了一下市面上的安全工具,以及怎么开发安全工具。

安全工具分析

经过我得研究发现市面上的安全工具其实只有两类,一类是面向某个漏洞的工具比如SQLMap,另外一个一类是综合扫描工具,比如AWVS;

作为一个只想挖漏洞的我,我更偏向于综合型的扫描器开发,可是综合型的扫描器开发难度真的很大,要清晰地了解各种漏洞的原理,而且还需要把他们使用代码去实现,如果是我一个人从头开发我压根做不到啊。

但我并不打算放弃,我准备集结天下之利器,为我扫描器所用;理想是有了,但现实是我要怎么实现,这可真实苦恼了我。

二、 要做的东西

我想要做的扫描器核心目的就是要使用简单,另外就是我可以随心所欲的修改;我希望是我只要给他一个URL地址,它就可以帮我扫描网站的漏洞,以及这个主机本身的漏洞

细致的拆解了一下,我觉得最需要的功能有这几个

  1. 能自动收集URL地址,爬虫收集和爆破收集
  2. 能从URL中提取主机IP
  3. 能快速检测常见的热门POC
  4. 能自动识别网站的指纹信息
  5. 能对IP进行端口快速扫描
  6. 能对端口的banner识别出服务
  7. 能检测出SQL注入漏洞
  8. 能检测出反射性XSS漏洞
  9. 能够通过指纹信息,使用对应的POC工具
  10. 能够快速扩展功能,且不影响整体逻辑

第一版本差不多就是这些功能吧,功能虽然不算多,但如果完全从头开始实现开发时间可不少。

三、思路分析

为了达到高效率的同时又能自主可控,我决定做一个有水平的缝合侠,简单理解就是我要把很多工具巧妙的融入到我开发的工具来,这里需要考虑的第一个问题是每个工具的使用方法、输入的参数、输出的结果都是不一样的,工具A的结果工具B不一定认识。

要解决这个问题,说简单也简单说难也难,总之我是摸着石头过河成功了;原理是自己给每个工具做一个壳,外部要调用工具A需要先调用工具A的壳,然后才会传到工具A,当工具A返回了结果,工具A的壳也会最先拿到,然后将结果解析出来并按照统一的格式输出就可以了。

通过这个简单的办法,我相当于把其他的安全工具变成了我得一个函数,我需要的时候调用这个函数就可以了。

按照我前面提到的需求,我梳理了一下要试用的工具有这几个:

序号

序号 需求 工具
1. 爬去URL的有 RAD
2. 爆破URL的有 DIRMAP
3. 提取主机IP 正则
4. 快速检测热门POC xray
5. 识别网站的指纹 dismap
6. 对IP端口快速扫描 masscan
7. 能对端口的banner识别出服务 nmap
8. 能检测出SQL注入漏洞 sqlmap
9. 能检测出反射性XSS漏洞 xsser

这些工具都是比较常见的工具,我第一步需要对他们的使用方法熟悉,以xray工具为例

xray的使用命令如下所示

./xray_linux_amd64 webscan --url "http://192.168.1.100/" --json-output /tmp/11.json

当xray执行完毕之后,他会将结果输出到指定位置,但是数据格式并不是我所期望的,我需要将它的格式读入,然后再转换成我所需要的格式。

这里我用PHP写了一个简单的脚本,他做了这几件事情:

  1. 定义了参数来源位置和结果输出位置
  2. 获取参数中的URL,并执行xray工具
  3. 获取xray的执行结果,并解析成自定义格式
  4. 将最终的结果写入到输出位置

代码示例如下所示

<?php
//获取输入的参数
$inputFile = "/data/share/input_".getenv("xflow_node_id").".json";
$outputFile = "/data/share/output_".getenv("xflow_node_id").".json";
//没有input,直接返回
if (!file_exists($inputFile)) {
    var_dump($outputFile, json_encode(['code' => 0, 'msg' => "{$inputFile}文件不存在", 'data' => []], JSON_UNESCAPED_UNICODE));
    return 0;
}
//读取上游数据
$inputData = json_decode(file_get_contents($inputFile), true);
$url = $inputData['url'];
$data = execTool($url);
//将结果写入到指定位置,供蜻蜓平台导入数据
file_put_contents($outputFile, json_encode($data, JSON_UNESCAPED_UNICODE));
//将工具执行
function execTool($url)
{
    $hash = md5($url);
    $resultPath = "/tmp/{$hash}/tool.json";
    //清理之上一轮的结果
    if (file_exists($resultPath)) unlink($resultPath);
    //创建文件夹
    if (!file_exists(dirname($resultPath))) {
        mkdir(dirname($resultPath), 0777, true);
    }
    $result = [];
    $toolPath = "/data/tools/xray";
    if (!file_exists($toolPath)) die("xray 工具目录不存在:{$toolPath}");
    $path = "cd $toolPath && ";
    // 通过系统命令执行工具
    $cmd = "{$path} ./xray_linux_amd64 webscan --url \"{$url}\" --json-output {$resultPath}";
    echo $cmd;
    exec($cmd, $result);
    $toolResult = file_exists($resultPath) ? file_get_contents($resultPath) : '[]';
    $toolResult = json_decode($toolResult, true);
    print_r($toolResult);
    return $toolResult;
}

再来sqlmap封装的例子,首先需要知道sqlmap的使用的方法,如下所示

sqlmap -u "http://192.168.1.100/index.php?id=1"  --batch  --random-agent

当sqlmap执行完毕之后,我需要知道他的执行结果在什么位置,并将结果解析出来,按照规范化的格式输出到指定地址。

这里我同样用PHP写了一个脚本,做了这几件事情:

  1. 定义了参数来源位置和结果输出位置
  2. 获取参数中的URL,并执行sqlmap工具
  3. 获取sqlmap的执行结果,并解析成自定义格式
  4. 将最终的结果写入到输出位置
<?php
//获取输入的参数
$inputFile = "/data/share/input_".getenv("xflow_node_id").".json";
$outputFile = "/data/share/output_".getenv("xflow_node_id").".json";
//没有input,直接返回
if (!file_exists($inputFile)) {
    file_put_contents($outputFile, json_encode([]));
    return 0;
}
//读取上游数据
$list = json_decode(file_get_contents($inputFile), true);
print_r($inputFile);
print_r($list);
$data = [];
//处理数据
foreach ($list as $val) {
    $url = $val['url'];
    $toolPath = "/data/tools/sqlmap/";
    print_r("开始扫描URL:{$url}".PHP_EOL);
    execTool($url, $toolPath);
    //录入检测结果
    $tempList = writeData($toolPath, $url);
    print_r("扫描URL:{$url}完成".PHP_EOL);
    print_r($tempList);
    $data = array_merge($data, $tempList);
}
print_r($data);
//将结果写入到指定位置,供蜻蜓平台导入数据
file_put_contents($outputFile, json_encode($data, JSON_UNESCAPED_UNICODE));
function writeData($toolPath, $url)
{
    $arr = parse_url($url);
    $file_path = $toolPath . 'result/';
    $host = $arr['host'];
    $outdir = $file_path . "{$host}/";
    $outfilename = "{$outdir}/log";
    //sqlmap输出异常
    if (!is_dir($outdir) or !file_exists($outfilename) or !filesize($outfilename)) {
        print_r("sqlmap没有找到注入点: $url");
        return [];
    }
    $ddd = file_get_contents($outfilename);
    print_r($ddd);
    exec("rm -rf $outdir");
    return [["raw" => $ddd]];
}
function execTool($v, $toolPath)
{
    $arr = parse_url($v);
    $blackExt = ['.js', '.css', '.json', '.png', '.jpg', '.jpeg', '.gif', '.mp3', '.mp4'];
    //没有可以注入的参数
    if (!isset($arr['query']) or (strpos($arr['query'], '=') === false)) {
        print_r(["URL地址不存在可以注入的参数".PHP_EOL, $v]);
        return false;
    }
    $file_path = $toolPath . 'result/';
    $cmd = "cd {$toolPath}  && python3 ./sqlmap.py -u '{$v}' --batch  --random-agent --output-dir={$file_path}";
    exec($cmd);
    return true;
}

通过前面xray和sqlmap两个工具封装的例子,你回发现其实每个工具封装的流程都差不多,差一点只是程序的输出结果解析而已,所以到现在位置我解决了扫描器的能力问题。

四、动手实践

现在只需要我把几个功能连接起来就行了,这里需要考虑一个新的问题;sqlmap所需要的参数确是具体的多个URL地址,也就是说在调用sqlmap之前,我需要把URL都收集好再调用sqlmap,这里就有数据依赖问题。

这个问题也好办,我们需要准备三张表: 目标表、功能依赖表、数据存放表。

目标表

ID URL create_time

功能表

ID tool_name pre_tool_name create_time

数据表

ID tool_name url result create_time

我们可以首先从目标表中获取一个要扫描的目标,然后读取所有的功能,for循环功能表,只需判断当前有没有依赖问题,或者依赖问题已经解决,那么就可以得到所需的依赖数据,直接执行功能即可。

执行完成结果可以在结果页面看见,这里是我的执行结果。

伪代码如下所示:

<?php
$id = getTarget();
$toolLst = getToolList();
foreach($toolList as $val){
    //判断当前工具上级依赖为空或者上级工具已执行 
    if($val['pre_tool_name'] == ''   or  上级工具已经执行){
        //开始使用工具对URL扫描
        scanUrl();
        //保存结果
        svaeResult();
    } else(){
        //上级工具还没执行完成,先跳过
        continue;
    }
}

这是我写好的脚本,大家可以简单改改应用,目前我写的脚本已经集成到了蜻蜓安全平台里面,你可以一键复制使用

http://qingting.starcross.cn/scenario/detail?id=1931

目前我已经集成了46常见的款工具,放在GitHub中开源,地址:https://github.com/StarCrossPortal/QingTing


作者:汤青松

日期:2022-11-29

微信:songboy8888

目录
相关文章
|
1月前
|
监控 安全 网络安全
解锁Micronaut安全秘籍:一剑封喉,让你的微服务无懈可击,抵御黑客侵袭的终极防护罩!
【9月更文挑战第10天】Micronaut作为高性能、轻量级的云原生Java框架,在微服务开发中备受青睐。本文详细探讨了Micronaut的安全特性,包括认证与授权、通讯加密、服务注册与发现、防火墙与反向代理及日志与监控等,通过示例代码展示了如何配置JWT验证,确保服务间安全通信,增强系统可靠性,并及时发现潜在安全问题。
44 5
|
2月前
|
存储 安全 测试技术
移动应用的安全测试与加固技术深度解析
【8月更文挑战第2天】随着移动互联网的发展,移动应用成为生活必需,但安全威胁也随之加剧。本文深入探讨移动应用的安全测试与加固技术,包括权限访问、数据加密、安全协议、组件安全测试及渗透测试等内容,同时覆盖源代码、运行时环境、数据传输存储及业务逻辑加固等方面,为开发者提供全面指导,以保护用户数据和企业资产安全。
122 12
|
2月前
|
存储 SQL 安全
【绝密攻略】Flask应用如何抵御黑客入侵?七大安全技巧助你构建固若金汤的Web防线!
【8月更文挑战第31天】安全性是Web应用开发中的关键部分。Flask作为一款轻量级且高度可定制的框架,虽灵活但需开发者确保应用安全。本文介绍如何通过具体措施加固Flask应用,包括更新依赖项、启用CSRF保护、使用HTTPS、安全存储密码、防止SQL注入及清理用户输入等。通过示例代码展示如何在实际开发中应用这些策略,帮助提升应用安全性,为用户提供更可靠的服务。
49 0
|
3月前
|
SQL 安全 中间件
网安零基础入门神书,全面介绍Web渗透核心攻击与防御方式!
Web安全是指Web服务程序的漏洞,通常涵盖Web漏洞、操作系统洞、数据库漏洞、中间件漏洞等。 “渗透测试”作为主动防御的一种关键手段,对评估网络系统安全防护及措施至关重要,因为只有发现问题才能及时终止并预防潜在的安全风险。 根据网络安全调查统计,75%的网络攻击行为都是来自Web应用层面而非网络层面。
|
3月前
|
存储 安全 数据安全/隐私保护
移动APP安全加固技术深度解析
【7月更文挑战第12天】移动APP安全加固技术是保障移动应用安全的重要手段。通过对Android和iOS两大主流平台的安全加固,可以有效防止逆向分析、动态调试、数据篡改等安全威胁。在实际应用中,我们需要结合静态层面、动态层面和数据层面的加固技术,全方位地提升APP的安全性。同时,随着技术的不断发展,我们也需要不断关注新的安全威胁和加固技术,确保移动应用的安全性和稳定性。
|
5月前
|
前端开发 网络安全
【XSS平台】使用,网络安全开发必学
【XSS平台】使用,网络安全开发必学
|
5月前
|
缓存 安全 Java
提高APP安全性的必备加固手段——深度解析代码混淆技术
提高APP安全性的必备加固手段——深度解析代码混淆技术
72 1
|
11月前
|
供应链 安全 Java
一文读懂RASP运行时防护平台及应用实践
本文将着重介绍针对「应用上线后安全防护」场景的软件供应链安全产品——RASP 运行时防护平台。
699 0
|
安全 Ubuntu 测试技术
|
安全 开发工具 git
开源 Swallow 代码审计系统体验
最近在哔哩哔哩看 到Swallow 代码审计系统的宣传,发现功能比较适合我目前的工作需要,安装使用了一下,简单做了一个笔记,分享给有需要的朋友.底层架构为蜻蜓编排系统,墨菲SCA,fortify,SemGrep,hema
182 0