一、背景
我一直觉得自己是一个有梦想的人,我也想有一天自己的ID能出现在排行榜中,于是我凭借着自己那一点开发知识,认真研究了一下市面上的安全工具,以及怎么开发安全工具。
安全工具分析
作为一个只想挖漏洞的我,我更偏向于综合型的扫描器开发,可是综合型的扫描器开发难度真的很大,要清晰地了解各种漏洞的原理,而且还需要把他们使用代码去实现,如果是我一个人从头开发我压根做不到啊。
二、 要做的东西
我想要做的扫描器核心目的就是要使用简单,另外就是我可以随心所欲的修改;我希望是我只要给他一个URL地址,它就可以帮我扫描网站的漏洞,以及这个主机本身的漏洞
能自动收集URL地址,爬虫收集和爆破收集
能从URL中提取主机IP
能快速检测常见的热门POC
能自动识别网站的指纹信息
能对IP进行端口快速扫描
能对端口的banner识别出服务
能检测出SQL注入漏洞
能检测出反射性XSS漏洞
能够通过指纹信息,使用对应的POC工具
能够快速扩展功能,且不影响整体逻辑
三、思路分析
为了达到高效率的同时又能自主可控,我决定做一个有水平的缝合侠,简单理解就是我要把很多工具巧妙的融入到我开发的工具来,这里需要考虑的第一个问题是每个工具的使用方法、输入的参数、输出的结果都是不一样的,工具A的结果工具B不一定认识。
按照我前面提到的需求,我梳理了一下要试用的工具有这几个:
序号 | 需求 | 工具 |
---|---|---|
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_linux_amd64 webscan --url "http://192.168.1.100/" --json-output /tmp/11.json
当xray执行完毕之后,他会将结果输出到指定位置,但是数据格式并不是我所期望的,我需要将它的格式读入,然后再转换成我所需要的格式。
定义了参数来源位置和结果输出位置
获取参数中的URL,并执行xray工具
获取xray的执行结果,并解析成自定义格式
将最终的结果写入到输出位置
代码示例如下所示
<?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执行完毕之后,我需要知道他的执行结果在什么位置,并将结果解析出来,按照规范化的格式输出到指定地址。
定义了参数来源位置和结果输出位置
获取参数中的URL,并执行sqlmap工具
获取sqlmap的执行结果,并解析成自定义格式
将最终的结果写入到输出位置
<?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两个工具封装的例子,你回发现其实每个工具封装的流程都差不多,差一点只是程序的输出结果解析而已,所以到现在位置我解决了扫描器的能力问题。
四、动手实践
这个问题也好办,我们需要准备三张表: 目标表、功能依赖表、数据存放表。
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;
}
}
这是我写好的脚本,大家可以简单改改应用,目前我写的脚本已经集成到了蜻蜓安全平台里面,你可以一键复制使用
https://github.com/StarCrossPortal/QingTing