关于汤青松:高效率开发Web安全扫描器之路一

一、背景

常常看到一些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/…

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


作者:汤青松
日期:2022-11-29
微信:songboy8888

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理