Goby社区第16 篇插件分享文章
全文共:4955 字 预计阅读时间:13 分钟
前言:Goby 是一款优秀的漏洞验证和利用的工具,功能十分强大,具有丰富的指纹识别规则,扩展性也非常好,各种丰富的插件极大地简化了日常渗透的工作,初次编写插件的我,选择了一个较为简单的统计插件作为入门之作,编写过程中也学习了很多关于 js 的知识,同时参考了插件市场中许多的插件,也感谢编写期间 @go0p 师傅的指导。
01
02
作为一个 js 啥都没有接触过的小白,第一想法肯定是先去看看官方文档和模仿一下别的师傅写的插件。首先,我简单地对插件的需求进行了梳理,主要有以下几个要点:
-
插件基本配置
-
从扫描资产中提取信息
-
Windows 版本信息提取
-
提取 IP 和数量
-
展示
2.2 插件基本配置
通过对官方文档进行阅读,主要的是配置好 extension.js 中的注册函数,和 package.json 中的插件位置展示,详情如下:
function activate (content) {
goby.registerCommand('WindowsCount', function () {#WindowsCount以带要和package中的command值对应
let path = __dirname + "/os.html"#实现的代码文件路径
goby.showPage(path,false);#展示以页面方式展示
});
}
exports.activate = activate;
2.3 从扫描资产中提取信息
基本的配置都实现好之后,接下来我们就需要对功能的实现进行编码,首先我们需要将扫描的结果提取出来,这里需要用到的 API 是 goby.getAsset,参考官方文档说明:
我们首先需要编写一个简单的 debug 函数查看获取的信息:
goby.getAsset(goby.getTaskId(), getAssetData);//获取资产数据
function getAssetData(data) {
if (data.statusCode == 200) {
console.log(data);//打印出返回的data数据
}
}
2.4 Windows 版本信息提取
通过将 data 数据进行输出,我们可以很清晰地看到 Windows 的版本信息存储在 dcerpc 协议中的 product 字段中,故此我们可以根据协议为 dcerpc 并且 product 中包含 Windows 关键字作为过滤条件提取 Windows 版本类型,代码如下:
let ostypes = []; //存储系统类型
goby.getAsset(goby.getTaskId(), getAssetData); //获取资产数据
//去重函数
function unique(arr) {
return Array.from(new Set(arr));
}
function getAssetData(data) {
if (data.statusCode == 200) {
let ipinfo = data.data.ips
//获取OS类型
ipinfo.forEach((v, k) = >{
if (v.protocols) {
for (var i in v.protocols) {
if (v.protocols[i].protocol.search("dcerpc") != -1 && v.protocols[i].product.search("Windows") != -1) {
console.log(v.protocols[i].product)
ostypes.push(v.protocols[i].product);//将系统类型存入列表中
}
}
}
});
ostypes = unique(ostypes);//去重
}
}
执行结果
2.5 提取 IP 和数量
将系统版本提取完成后,我们需要将对应的版本的 IP 提取出来,然后将 IP 个数进行统计,这里是一个一对多的关系,我们需要建立一个字典,将系统类型作为 key,将 IP 放入到 list 中去,然后就可以将其关系对应起来,最后对 value 的数量进行统计既可以完成我们的需求,详细代码如下:
//根据OS类型生成dic
for (var i in ostypes) {
osinfo[ostypes[i]] = [];
}
//根据OS类型匹配对应的IP
for (var key in osinfo) {
ipinfo.forEach((v, k) => {
if (v.protocols) {
for (var i in v.protocols) {
if (v.protocols[i].port == 135 && v.protocols[i].product == key) {
osinfo[key].push(v.protocols[i].hostinfo.split(":")[0]);
}
}
}
});
}
console.log(osinfo)
执行结果
2.6 展示
展示就直接抄了 threatbook 插件的 html 代码,直接将源码复制修改一下即可,详细的可以参考如下代码:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Windows系统统计表</title>
<link rel="stylesheet" href="assets/lib/layui/css/layui.css">
</head>
<body>
<div>
<script>
</script>
</div>
<div>
<table id="os-table" class="layui-table" lay-even lay-skin="nob">
<thead>
<tr>
<th width="40" style="font-size: medium;" data-i18n="System type"></th>
<th width="55" style="font-size: medium;">IP</th>
<th width="55" style="font-size: medium;" data-i18n="Count"></th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
</div>
<script src="assets/js/jquery-3.3.1.min.js"></script>
<script src="assets/lib/layui/layui.all.js"></script>
<script src="assets/js/jquery.i18next.js"></script>
<script>
let osinfo = new Array();
let fs = parent.require('fs');
let ostypes = [];
let html = "";
goby.getAsset(goby.getTaskId(), getAssetData);
//去重函数
function unique(arr) {
return Array.from(new Set(arr));
}
function lang(){
//获取当前Languzge
let language = goby.getLang();
//判断翻译文件是否存在
let translateState = fs.existsSync(goby.__dirname + '/assets/translate/' + language+'/html.json');
//翻译文件存在则使用翻译文件,否则使用默认EN翻译
let lang = translateState?language:'EN';
let a = $.i18n.init({
lng: language, //指定语言
useCookie:false,
resGetPath: './assets/translate/'+lang+'/html.json',//语言包的路径
}, function(err, t) {
if(!err){
$('[data-i18n]').i18n(); // 通过选择器集体翻译
return;
}
goby.showErrorMessage(err)
});
}
lang();
//当lang改变时更新页面内容
goby.bindEvent('onChangeLang',()=>{
lang();
})
function getAssetData(data) {
if (data.statusCode == 200) {
let ipinfo = data.data.ips
//获取OS类型
ipinfo.forEach((v, k) => {
if (v.protocols) {
for (var i in v.protocols) {
if (v.protocols[i].protocol.search("dcerpc") != -1 && v.protocols[i].product.search("Windows") != -1) {
ostypes.push(v.protocols[i].product);
}
}
}
});
ostypes = unique(ostypes);
//根据OS类型生成dic
for (var i in ostypes) {
osinfo[ostypes[i]] = [];
}
//根据OS类型匹配对应的IP
for (var key in osinfo) {
ipinfo.forEach((v, k) => {
if (v.protocols) {
for (var i in v.protocols) {
if (v.protocols[i].protocol.search("dcerpc") != -1 && v.protocols[i].product == key) {
osinfo[key].push(v.protocols[i].hostinfo.split(":")[0]);
}
}
}
});
}
//输出数据
for (var os in osinfo) {
let ips = osinfo[os];
let nums = osinfo[os].length;
let tds = "";
for (var ip in ips) {
tds += ips[ip] + "</br>";
}
html += `<tr>
<td>${os}</td>
<td>${tds}</td>
<td>${nums}</td>
</tr>`;
}
$("#os-table tbody").html(html);
}
}
</script>
</body>
</html>
最后输出结果如下:
03
此次通过编写一个简单的插件,对 Goby 的插件编写有了一定了解和认识,并且从中收获了不少 js 的知识,也感谢 @go0p 师傅的指导;在编写过程中也发现 Goby 扫描的结果需要更加完善,目标是在 FOFA 找到的,FOFA 有的能识别出系统是 Windows 2000 或者 Windows 10 等,但是 Goby 好像只能识别出 2008 和 XP,其实 Goby 部分扫描结果是有识别到 Windows 的 NT 版本号的,根据版本号的范围也可以对系统做一个初步的判断,这个只是一个小 bug,可能需要以后版本更新去对一些规则进一步完善,希望 Goby 功能越来越强大,插件越来越丰富,gogo!
插件开发文档及Goby开发版下载:
https://gobies.org/docs.html
关于插件开发在B站都有详细的教学,欢迎大家到弹幕区合影~
-
https://www.bilibili.com/video/BV1u54y147PF/
• go0p | 可调用Goby API进行漏洞检测的Goby_exp
• zhzyker | 可进行Web漏洞扫描和验证的vulmap
• h1ei1 | 如何快速上手 Zookeeper 未授权漏洞
• Eyes | 调用 Python 脚本进行漏洞测试的 PythonCall
如果表哥/表姐也想把自己上交给社区(获取红队专版),戳这里领取一份插件任务?
https://github.com/gobysec/GobyExtension/projects
本文始发于微信公众号(GobySec):插件分享 | 一键统计 Windows 各版本数量的 Windows Count
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论