专栏首页信安之路MikroTik-SMB 测试之 Mutiny-Fuzzer

MikroTik-SMB 测试之 Mutiny-Fuzzer

Mutiny是由思科研究人员开发的一款基于变异的网络fuzz框架,其主要原理是通过从数据包(如pcap文件)中解析协议请求并生成一个.fuzzer文件,然后基于该文件对请求进行变异,再发送给待测试的目标。通过这种方式,可以在很短的时间内开始对目标进行fuzz,而不用关心相关网络协议的具体细节。

最近在对MikroTik设备的SMB服务进行分析测试时,在尝试采用基于生成方式的fuzzer没有效果后,试了一下Mutiny Fuzzer,意外地发现了 3 个漏洞。下面对该过程进行简要介绍。

这里主要采用黑盒测试的方式

Mutiny Fuzzer简介

Mutiny是一款基于变异的网络协议fuzz框架,其主要是采用Radamsa工具来对数据进行变异。内部的fuzz流程与其他的协议fuzz框架(如BoofuzzKitty)类似,也提供了在不同阶段对请求数据进行动态修改、对目标进行监控等功能。

master分支为例,主要模块的说明如下。

experiment分支加入了更多的特性,如自动生成PoC、反馈机制等。

mutiny-fuzzer
├── backend
│   ├── fuzzerdata.py // 与.fuzzer文件解析/生成相关
│   ├── fuzzer_types.py   // 定义fuzz中使用的相关消息类型及工具函数
│   ├── __init__.py
│   ├── menu_functions.py
│   ├── packets.py
│   └── proc_director.py
├── LICENSE
├── mutiny_classes  // (需要根据需求进行自定义)
│   ├── exception_processor.py
│   ├── __init__.py
│   ├── message_processor.py  // 提供对请求数据进行动态修改
│   ├── monitor.py  // 负责对测试目标进行监控,需自己实现
│   └── mutiny_exceptions.py
├── mutiny_prep.py  // 预处理:解析pcap文件,并生成.fuzzer文件
├── mutiny.py // fuzz主程序:基于生成的.fuzzer文件, 对请求进行变异, 然后发送给测试目标
├── radamsa-v0.6.tar.gz
├── readme.md
├── sample_apps
├── tests
└── util

MikroTik SMB测试

MikroTik设备支持SMB协议,相关的功能主要在/nova/bin/smb程序中。通过对程序代码进行分析,感觉其是由厂商自己实现的,未复用第三方库,考虑到SMB协议的复杂性,该程序似乎是一个不错的fuzz目标。默认情况下smb服务是关闭的,可通过如下命令开启。

/ip smb set enabled=yes

通常,对比较复杂的网络协议进行测试,笔者会优先考虑基于生成的fuzz方式,即根据协议格式去定义请求,然后对请求进行变异,保证变异后的请求仍然是"符合"协议格式的。因为如果协议比较复杂的话,协议之间的关联或约束会比较多,基于变异的方式很大可能会破坏请求的协议格式,无法通过程序内的校验,造成fuzz的效率低下。

在采用基于生成的方式进行fuzz后,并没有发现问题。想到之前有国外研究人员利用Mutiny工具在smb服务中发现了漏洞CVE-2018–7445,于是打算尝试下Mutiny工具。文章 Finding and exploiting CVE-2018–7445 (unauthenticated RCE in MikroTik’s RouterOS SMB) 详细介绍了作者从环境搭建、测试、漏洞分析到漏洞利用的整个过程,感兴趣的可以看一下。

在采用基于生成的方式进行fuzz时,笔者主要关注的是smb协议中无需认证的部分,因此只对部分请求进行了测试。

fuzzer文件生成

stable 6.44.2版本为例,在开启smb服务后,在win10下访问对应的共享文件夹,同时利用wireshark捕获数据包,部分请求如下。

根据SMB协议的交互流程,前面几个请求如Negotiate ProtocolSession Setup等是无需认证的,由于笔者主要关注无需认证的攻击面,因此打算仅对前面几个请求进行fuzz

在有了数据包之后,运行mutiny_prep.py对数据包进行处理,生成mutiny需要的.fuzzer文件。同时,可以根据自己的需求对生成的.fuzzer文件进行自定义修改,部分示例如下。需要说明的是,根据mutinyfuzz流程,建议为每个请求单独生成一个.fuzzer文件。

笔者曾问过关于mutiny的处理逻辑,可参考这里。

# Directory containing any custom exception/message/monitor processors
# This should be either an absolute path or relative to the .fuzzer file
# If set to "default", Mutiny will use any processors in the same
# folder as the .fuzzer file
processor_dir default
# Number of times to retry a test case causing a crash
failureThreshold 3
# How long to wait between retrying test cases causing a crash
failureTimeout 1
# How long for recv() to block when waiting on data from server
receiveTimeout 1.0
# Whether to perform an unfuzzed test run before fuzzing
shouldPerformTestRun 0
# Protocol (udp or tcp)
proto tcp
# Port number to connect to
port 445
# Port number to connect from
sourcePort -1
# Source IP to connect from
sourceIP 0.0.0.0
# The actual messages in the conversation
# Each contains a message to be sent to or from the server, printably-formatted
outbound fuzz '\x00\x00\x00\xee\xfeSMB@\x00\x01\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x05\x00\x01\x00\x00\x00\x7f\x00\x00\x00\xd1\xc5\x81\xc2\xec\x88\xea\x11\x83\xce4\x17\xeb\xc5\x0c{p\x00\x00\x00\x04\x00\x00\x00\x02\x02\x10\x02\x00\x03\x02\x03\x11\x03\x00\x00\x01\x00&\x00\x00\x00\x00\x00\x01\x00 \x00\x01\x00\xd4\xfa\xbc^\xc5g\x8a9\xeaP\xe6\xa0(\x13\xc7\xa9\xa9@\xf40\x0f\xc3\xe3\x98\x89\xc54\x1e\xb46h\xea\x00\x00\x02\x00\x06\x00\x00\x00\x00\x00\x02\x00\x02\x00\x01\x00\x00\x00\x03\x00\x0e\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00\x01\x00\x00\x00\x05\x00\x1e\x00\x00\x00\x00\x001\x009\x002\x00.\x001\x006\x008\x00.\x002\x000\x000\x00.\x001\x005\x002\x00'
inbound '\x00\x00\x00\xca\xfeSMB@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x01\x00\x02\x02\x00\x00\\\x91\xc5!\x89D\x11\xea\x85g\xc7#{2\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x95Q(Q\x1d\xd6\x01\x80\x96/\x1eQ\x1d\xd6\x01\x80\x00J\x00\x00\x00\x00\x00`H\x06\x06+\x06\x01\x05\x05\x02\xa0>0<\xa0\x0e0\x0c\x06\n+\x06\x01\x04\x01\x827\x02\x02\n\xa3*0(\xa0&\x1b$not_defined_in_RFC4178@please_ignore'

目标监控与环境恢复

在有了对应的.fuzzer文件后,运行mutiny.py脚本,就可以开始对目标进行fuzz了。

Mutiny框架的目的就是让使用者能尽可能快地开始对目标进行fuzz

$ ./mutiny.py -s 0.1 --logAll ./<path to .fuzzer file> <ip>

上面的命令会记录所有的输出,为了后续更方便地对畸形用例进行定位及重放,考虑增加对目标是否发生异常进行监控。由于smb服务会监听445/tcp端口,而当smb程序崩溃时,该端口会不可访问,因此可以通过探测445/tcp端口是否可访问的方式来监控目标是否发生异常,对应的代码可以添加在mutiny_classes/monitor.py中。这样,当目标出现崩溃时,日志中会记录崩溃对应的测试用例编号。

另外,虽然smb程序崩溃后会自动重启,但当发生多次异常后smb环境会出现小问题,同时为了保证每次smb程序重启后环境与最开始一样,考虑到整个mikrotik系统运行在vmware中,因此可以考虑借助vmware快照的方式保证环境的一致,即在最开始时拍摄快照,当目标发生崩溃后恢复快照,然后再继续进行fuzz。同样,对应的代码可以添加在mutiny_classes/monitor.py中。

现在可以开始对目标进行fuzz了。当然,如果直接采用最原始的.fuzzer文件,即直接对整个请求进行变异,发现崩溃的耗时可能会比较长。因为SMB协议中包含magic(·\xfe\x53\x4d\x42,以smb2为例)、command(0x0(Negotiate Protocol),0x01(Session Setup))等字段,如果这些字段不符合协议约定的话,生成的测试用例大概率会被程序丢弃。因此还是要借助对协议的理解和对程序进行逆向,了解程序内部协议的大概处理流程(比如校验哪些字段),然后对.fuzzer文件进行修改,指定哪些部分保持不变、对哪些部分进行变异等。

崩溃用例分析

在运行一段时间后,发现了多个测试用例会造成目标程序崩溃,通过对测试用例进行重放和分析,最终共有3个测试用例会造成不同的崩溃,其中的一个测试用例如下。

这个测试用例比较有意思的是,在正常的Negotiate Protocol请求之后,又多了一层NetBIOS Session Service数据包。由于是针对单个Negotiate Protocol请求进行fuzz,如果采用常规的基于生成的方式,即仅对协议内的字段进行变异,似乎很难生成这样的测试用例。而采用变异的方式,出乎意料的得到了这样一个测试用例,这可能得益于Radamsa工具的强大能力。当然,变异的方式也有其弊端,比如对前面某个字段进行变异,很可能由于这个字段违背了协议规约,造成其后面的字段全部被"破坏",牵一发而动全身。

小结

本文对Mutiny-Fuzzer框架进行了简要介绍,并针对MikroTik设备的smb服务进行了简单测试。当需要对复杂网络协议进行测试时,可以尝试一下Mutiny-Fuzzer框架,"快"就是优势,说不定会有意外收获。当然,在对协议和目标有了一定的了解后,可以对其进行改进,或者采用更有效的fuzz方式。

相关链接

mutiny-fuzzer:

https://github.com/Cisco-Talos/mutiny-fuzzer

Finding and exploiting CVE-2018–7445 (unauthenticated RCE in MikroTik’s RouterOS SMB:

https://medium.com/@maxi./finding-and-exploiting-cve-2018-7445-f3103f163cc1

本文分享自微信公众号 - 信安之路(xazlsec),作者:cq674350529

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • RFID 破解基础详解

    在我们平时生活中有各种各样的卡,比如 ID 卡、IC 卡、RFID 卡、NFC 卡、Mifare 系列卡(可能银行卡、公交卡、饭卡、水卡、门禁卡、电梯卡.......

    信安之路
  • 奇淫异巧之 PHP 后门

    早上看了一位小伙伴在公众号发的文章《php 后门隐藏技巧》,写的挺好,其中有一些姿势是我之前没见到过了,学到很很多。同时,这篇文章也引发了自己的一点点思考:“ ...

    信安之路
  • XXE 打怪升级之路

    其实 xxe 也是一类注入漏洞,英文全名即 Xml External Entity Injection, 即我们所说的 xml 外部实体注入攻击。

    信安之路
  • Redis 基于主从复制的 RCE 利用方式

    在2019年7月7日结束的WCTF2019 Final上,LC/BC的成员Pavel Toporkov在分享会上介绍了一种关于redis新版本的RCE利用方式[...

    Seebug漏洞平台
  • golang-101-hacks(13)——二维切片

    注:本文是对golang-101-hacks中文翻译。 Go支持多维切片,再此只对二维切片切片做介绍。日常生活中通常会使用到二维切片,而多维似乎并不多见。如果...

    羊羽shine
  • 翻译:使用红外传感器与Arduino进行简单动作与手势检测

    译注:昨天看 Adruino 的 Twitter 推了这篇项目,第一眼就觉得非常有趣,翻译给大家看看。文中的红外传感器比较高级,和淘宝上5块钱的那种只能输出0和...

    张高兴
  • 为了抓取弹幕,你需要知道的一些二进制数据常识

    文本不会讲具体某个网站的弹幕抓取方法。而是描述抓取到二进制的弹幕信息以后,如何进行处理。

    青南
  • CVE-2020-0796,又是一场补丁攻坚战

    每年真正比较有影响力的漏洞编号,其实并不多,而这个CVE-2020-0796,就是我们在疫情之下全面返岗伊始,最值得去重视的一个。

    Bypass
  • C语言数组结合位运算实战-位移与查表

    在嵌入式项目开发中,LED灯的操作是一定要会的,也是基础中的基础,比如用51单片机写个跑马灯,这不简单嘛,定义一个数组把那8个跑马灯存起来,然后搞个for循环...

    morixinguan
  • 漏洞告之:SMBv3协议远程代码执行漏洞(附自查脚本)

    北京时间3月10日23时微软发布安全通告称Microsoft Server Message Block 3.1.1(SMBv3)协议在处理某些请求的方式中存在代...

    Aran

扫码关注云+社区

领取腾讯云代金券