经过实战打磨内网自动化引擎-gogo 介绍

admin 2022年11月17日09:45:55评论577 views字数 5051阅读16分50秒阅读模式

0x00 repo

项目链接

本体: https://github.com/chainreactors/gogo

规则库: https://github.com/chainreactors/gogo-templates (将在一周内设置为public)

本文只介绍一些特性, 具体的使用以及使用文档请见项目仓库

0x01 诞生

在红队最开始的两年, 并没有相关的工具, 外网扫描端口使用的还是nmap, masscan. 内网则几乎无能为力, 有人使用C写的一些小工具, 有人通过python写了单文件的allin, 也有人打包了单文件版本的nmap与masscan.

之后有了serverscan, 不过老版本缺少维护, 在设计上存在缺陷, 新版本一直没有公开, 在扫描少量目标时效果不错, 目标一大, 则速度难以接受并且会时不时的崩溃.

也因为此, 开始编写自己的扫描器, 很快就在同事手中诞生了第一个demo, 最开始的定位大概是一个没有bug的serverscan, 那时候叫getitle, 还真的只能get title. 但写着写着就收不住了, 最终变成了一个能网段发现, 端口扫描, 指纹识别, 漏洞探测的扫描引擎. 几乎覆盖了内网扫描相关的绝大多数场景.

再后来诞生了kscan, fscan等类似定位的工具, 在迭代的过程中, gogo从ladon, kscan, cube,nuclei等地方借鉴了一些思路, 也复制了一些代码(主要是特殊端口的扫描插件).  

现在的gogo, 定位已经不同于serverscan, fscan等工具, 它是一个内网的自动化引擎, 保留了极强的可控性与可拓展性, 能对付fscan, kscan,netspy等都无能为力的复杂使用场景.

在红队项目与hw中不断迭代了100多个版本, 近1000个commit, 慢慢加入了非常多功能与奇思妙想 以及实战中的经验积累.

gogo在设计上会有一些取舍, 一些其他工具有的功能, gogo不一定会都去实现, 但一定会提供其他解决方案. 这主要是为了保证gogo足够便携, 足够优雅以及设计上的统一.

0x02 特点

经过接近两年的实战打磨,  尽可能地优化用户体验与各种细节. 但随着功能越来越复杂, 依旧是一个学习成本相对较高的工具.

启发式扫描

在nmap,masscan那个年代, 对内网的扫描很少会超过c段, 更别说a段这种在当时几乎不可能完成的任务. 就算是现在的fscan, 或者相关特化的工具netspy也不能很好的实现, 只停留在勉强能用的阶段.

而现在, 对b段的扫描测绘已经是轻而易举, 我们可以把目光放到对a段甚至对全网的测绘.

gogo在很早就集成了根据经验公式的递归下降去发现网段. 并且通过生成器对扫描逻辑解耦, 可以任意组合不同的扫描阶段. 最终实现对任意网段的智能探活与测试

例如

  • 想绘制一下当前入口点能通的网络拓扑 (大约30分钟)

  • 只想看看10段内网里有多个B段被使用了 (大约30秒)

  • 只想看看10网段中有多少ip存活 (大约30分钟)

  • 想扫描下10段中的资产 (看前两阶段存活的资产数量, 大约1-2小时)

  • 不仅想扫描资产, 还想识别下指纹, 探测下漏洞 (基本和探测资产时间相同, 采用最小发包原则,探测指纹与漏洞不会多耗时多少, 大约多20-30%耗时)

  • 我想一口气把10,172,192内网全探测了, 并输出报告 (看资产数量, 大约1-2小时)

  • ......

当然, 这里的网段可以自定义, 不一定是10.  大致可以理解为fscan与netspy的结合, 实际上会更加复杂一点.

用命令行构造这些场景较为复杂, 经过不少朋友试用吐槽后, 添加了workflow, 只需要一个参数即可覆盖绝大多数常见的使用场景. 具体的使用说明见仓库中的README.md与设计文档.

便捷的端口配置

刚才提到的启发式扫描, 主要是在扫描逻辑上的配置, 而对于具体端口资产, gogo也提供了极其方便的端口预设,

例如我要扫描常见的http服务, 指定-p top3-p top2 即可. 如果要扫描数据库, 则是-p db

如果我同时要使用多个预设, 那么-p top3,db,win

如果我要使用多个预设, 又要指定某个区间网段. 那么 -p top3,db,win,40000-50000

通过name与tags的交叉管理, 能快速配置各种使用场景.

如果要添加预设, 可以在github的gogo-template中的port.yaml提交pr.

指纹识别

gogo的指纹与漏洞都将完全以dsl的方式实现, 说人话就是 通过yaml配置.

指纹是我自行设计的规则库格式与引擎, 因为并没有找到一个完全能满足我需求的规则库与引擎, 所以只能自己写一个, 整合了fofa的规则库, 以及fingerprinthub, fscan, kscan, allin中的一部分规则.  

指纹识别看起来简单, 但我们在实战中遇到了一个接一个预期外的问题. 指纹识别并不是只匹配关键字就能做好.

例如, 某个http站, 访问会通过30x跳转,  但是跳转过去的站是个404页面(默认配置的蓝凌oa).

又例如, 某个http站, 直接访问80端口返回的是一个通过js进行跳转的页面, 这种情况指纹匹配不一定能生效.

再例如, 某个http站, 一访问就会下载文件, 那个文件可能有几百M大小,

如果是非http协议的端口, 那情况就更多了.

例如, 某些服务, 建立完握手就会返回banner, 如果你发送了它无法识别的数据, 他就会reset tcp链接(SSH).

又例如, 如果对某些服务发送了他无法识别的数据, 他不会断开tcp链接, 但是不再会返回数据(MSSQL).

再例如, 某些协议有各种各样的发行版, 每个发行版的banner都不同, 并且没有明显的规律(FTP与TELNET).

好在nmap已经解决了服务指纹的大部分问题, 只是如果直接使用nmap的指纹库, 过于庞大的指纹库会带来不必要的性能消耗.  某些扫描器就直接使用nmap的指纹库, 导致指纹匹配的时间大于扫描的时间. 让我能把注意力集中在http指纹识别上.

光是http指纹识别的特殊情况甚至超过了gogo能处理的范围, 如果加上这些功能, gogo不可避免的会变得臃肿, 因此, 部分http指纹识别的功能, 特别是主动指纹探测相关功能, 我将其移植到另一款工件中.  只在gogo中保留最基本的主动识别. 在内网绝大多数情况, 漏报一两个指纹并不会影响我们的后续操作. (毕竟就算漏报了, 对普通用户来说也是没有感知的lol)

漏洞探测

漏洞扫描相关功能从nuclei学到了不少东西, dsl语法也直接使用了nuclei, 但为了更加适配内网场景, 做了不少改动, 并不能完全兼容.  考虑到了内网环境, 我删除了一部分不必要的功能(动态dsl, oast等), 以简化二进制文件大小.   也添加了一些功能, 详情见github仓库中的poc.md,

绝大多数poc都可以从nuclei中移植poc, 只需要做一些简单修改与测试便可以快速加入到gogo中.  不过为了保证poc质量以及内网使用场景, 加入到gogo中的漏洞需要一定的筛选.

这里的考量是, 红队场景中, 对于各种oa, cms, 不少人都手握0day, 只需要做指纹识别与版本识别, 需要打poc的情况不太多. 对于一些设备, 开源组件 手动一台一台测试弱口令不太现实, 需要自动化探测默认密码以及开源组件的nday.

因此, gogo的漏洞库不会是一个大而全的漏洞库, 如果有大而全的需求, 可以直接使用nuclei.

我想通过兼容nuclei的生态, 让自己维护poc库省力一些, 现在基本处于有人反馈常见什么poc, 我就添加对应的poc, 经过一段时间的维护, 基本上常见的poc都能适配好. 需要各位大哥帮我实现.

这里你也会发现, 内网除了自动化打一些poc, 还可以把默认口令这部分给实现了, 一些常见的网络设备web端, web应用, 不再需要手动测试. 与其维护一个默认口令库, 不如直接自动化探测.

自动化

假设这样一个场景, 内网中扫描发现了上百个weblogic, 然后通过其中一台漏洞解开了明文的weblogic密码. 这个时候, 就需要写一个自动化脚本. 而gogo提供了可复用的脚本支持.

第一步, 从扫描结果中过滤出weblogic

gogo -F result.dat --filter frame::weblogic -o json -f weblogic.dat

第二步, 调用poc,并替换相关参数实现批量爆破

gogo -l weblogic.dat -E weblogic-login --payload username=test --payload password=test

如果是某些相对罕见的设备. 则只需要抓包并编写一个简单的nuclei poc.

参考其他poc, 编写对应的yaml文件, 然后通过yaml2json.py转为base64编码的json格式, 使用gogo动态加载poc

gogo -l target.dat --ef [base64] -E custom_poc --payload username=test --payload password=test

通过nuclei poc与gogo结合, 可以实现绝大部分场景的内网web自动化探测. 并每一次的积累都将变成可复用的能力, 以待下一次遇到相同的场景提高效率.

为什么没有服务的口令爆破

刚才提到了, 对web端默认口令的爆破gogo可以实现, 但有很多人问我, 为什么不把ssh, mysql之类的爆破也做进去?

最初我也是这么想的, 但是考虑到加上了这些功能, 二进制文件和代码会变得臃肿, 并且这些功能其实可以以另一种形式实现. 最终我们决定另起炉灶, 维护了另外一个工具 zombie, 主要用于批量的服务弱口令爆破与利用. gogo与zombie可以联动, gogo导出的zombie可识别的格式, 然后再通过代理或者上传zombie本体进行爆破.

这也是变相鼓励使用者不要在内网进行大规模的服务弱口令爆破, 大多数厂商的流量设备对服务弱口令爆破是很敏感的, 大多数都是严重或者高危的告警. gogo默认情况下只进行高速率的http发包, 不会发送poc, 经常会被其他告警淹没而忽略了gogo的扫描行为. 实际使用体验 因为高速率发包而被发现的情况较少.

通过gogo的筛选功能与zombie的自定义功能, 可以对想要爆破的密码本与目标进行精准管控, 尽量减少不必要的发包以规避流量设备的检测. 如果有可能, 最好只进行密码喷洒, 而非爆破.

在我们的规划中, zombie能做的不仅仅是口令的爆破, 还可以实现一些自动化的利用, 比如mysql爆破之后, 判断下是否是root, 有多少数据, 自定义的命令批量执行等等功能. 批量的rce更不是梦, 只不过因为工作量问题, 这部分只能一小块一小块的实现, 目前的zombie已经支持了十几种协议, 能覆盖到90%以上的hw使用场景. 让护网不再是一个一个登录上去截图, 而是gogo与zombie的快乐联动, 内网刷分, 一行命令!

可以发现gogo与zombie的场景也不完全一致, zombie完全可以放在外网, 通过代理接入, 减轻zombie引入大量库的免杀压力.

在未来, 我打算编写一个gui界面的结果解析器与联动工具, 也可以是与c2 webshell的联动, 进一步简化操作, 让gogo与zombie的联动无缝衔接.


gogo的未来展望

  1. 集成到自动化外网信息收集工具, 与图数据库相结合 (已经做了一部分)

  2. 自动收集结果, 以可视化报告的形式呈现 (已经做了一部分)

  3. 与webshell, c2工具联动, 实现图形化 一键使用 (已经做了一部分)

  4. 与maitai(暂未公开的代理工具)联动, 实现gogo流量的高性能转发.

  5. 内网分布式部署, 多点同时扫描

  6. agent化, 特殊网络环境下, 可以只上传tiny agent (通过maitai实现, todo)


其他

gogo最核心的几块功能就是我刚才提到的, 但实际上还有不少细节我没有一一介绍, 使用者可以在实战中慢慢体会, 或者阅读仓库中的设计文档(不过写得不太好, 会慢慢整理修改), 也欢迎提出新的需求以及pr.

具体的使用请看README.md 与--help.

gogo是整个计划版图中发布的第一块拼图, 也是目前最成熟的部分. 祝各位用的开心!

其他工件会在整理完成后逐步开放.

如果有不清晰的文档与用法, 欢迎在issue中提出, 我看到后会及时回复.

在最近对许多模块进行了调整与重构, 一些原本正常的功能, 也许会因为不充分的测试出现bug, 如果出现与预期不符的结果, 请提交issue, 我们会马上处理.


经过实战打磨内网自动化引擎-gogo 介绍

(高级说法, 面向未来编程. 低级说法, 画饼)


原文始发于微信公众号(开普勒安全团队):经过实战打磨内网自动化引擎-gogo 介绍

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年11月17日09:45:55
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   经过实战打磨内网自动化引擎-gogo 介绍https://cn-sec.com/archives/1411237.html

发表评论

匿名网友 填写信息