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

33次阅读

共计 5293 个字符,预计需要花费 14 分钟才能阅读完成。

一、背景

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

正文完
 0