背景
CVE-2018-7445 漏洞存在于 MikroTik RouterOS < 6.41.3/6.42rc27 的 SMB 服务中,由堆栈溢出引发,漏洞时间线大致如下:
- 2018/02/15,MikroTik 官方在 Test Release 6.42rc27 版本中修复了该漏洞。
- 2018/02/19,Core Security 将该漏洞上报 MikroTik 官方(CVE-2018-7445)。
- 2018/03/12,MikroTik 官方在 Stable Release 6.41.3 版本中修复了该漏洞。
- 2018/03/15,Core Security 放出了某版本的 EXP【2】。
- 2019/03/06,网上公开了详细漏洞分析。
去年三月份的洞了,看了公开的分析文章发现也很详细,而且 EXP 也有了。不过文中使用 fuzz 发现漏洞的过程还是值得学习的,使用 fuzz 应该能发现不少漏洞,故打算实践一波。
环境搭建
在虚拟机中安装最新稳定版本 v6.44.0(默认凭证:admin/空)
使用 Winbox 配置一下网络,就可以使用 telnet 连接了。
推荐去官网申请个免费的 license 激活,不然只能使用 24 小时。
telnet 登录后的默认 shell 是个类似沙盒的环境,只能运行预设的一些命令,要研究漏洞的话就需要越狱。可以使用 Github 上的通用越狱工具【3】,2.9.8 到 6.41rc56 版本直接 exploit_backup/exploit_full.sh 一条命令搞定。6.41 及之后的版本需要借助一个 U 盘作为辅助,大致分为两个步骤:
准备一个空 U 盘,制作辅助工具。
确保 U 盘已经正确挂载到目标系统。
运行脚本,成功越狱。
发现只是个 ash,一无所有… ,利用 ftp 上传个功能齐全的 busybox【4】 和 gdbserver【5】。至此,环境搭建完成。
fuzz 入门
fuzz 又叫模糊测试,原理其实挺简单的,根据一定策略生成大量的输入,然后看对应服务是否有异常行为。fuzz 的对象一般是内存异常类漏洞,如常见的堆栈溢出。
拿前几天刚曝出的 Cisco 路由器 RCE 漏洞举个例子:
首先抓取正常的登录流量:
1 | # 正常数据包 |
IoT 设备的 Web 服务大多是 C 语言写的,很有可能存在溢出漏洞。根据经验,修改数据包如下:1
2# 修改后的包
curl -k -X POST -i "https://$IP/login.cgi" -d "submit_button=login&submit_type=&gui_action=&wait_time=0&change_action=&enc=1&user=admin&pwd=498836900e3cb4d343b96f3f1c578f4aAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&sel_lang=EN"
发送该数据包,路由器的 Web 服务会崩溃,然后就是调试开发 exp 了… 这个过程是一次典型的纯手动且目标明确的 fuzz 过程,有时候发送几千几万个包也不一定能打崩,效率很扎心。
那么能不能用代码自动化实现呢?将抓取的流量作为模版, 并根据一定的策略自动变异,自动发包并监控目标服务的运行状态,然后就可以去愉快上分了…
让我们在 RouteOS 最新版 6.44.0 的 SMB 服务上实践一下 ( ̄︶ ̄)↗
首先开启 SMB 服务。
选择 radamsa 【6】作为变异器,简单看下变异策略(左)和实际效果。
了解了基本原理之后,让我们来 fuzz RouterOS 的 SMB 服务。开启 wireshark 抓包:
提取建立 TCP 连接后的第一个 SMB 请求包的有效字节:
1 | \x00\x00\x00\xbe\xffSMBr\x00\x00\x00\x00\x18C\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\x00\x00\x00\x00\x00\x9b\x00\x02PC NETWORK PROGRAM 1.0\x00\x02MICROSOFT NETWORKS 1.03\x00\x02MICROSOFT NETWORKS 3.0\x00\x02LANMAN1.0\x00\x02LM1.2X002\x00\x02DOS LANMAN2.1\x00\x02LANMAN2.1\x00\x02Samba\x00\x02NT LANMAN 1.0\x00\x02NT LM 0.12\x00 |
将该流量作为模版,然后使用 radamsa 进行变异,可以选择变异整个流量,也可以只变异其中的某一个部分,生成大量的测试样例,如下:
然后循环发包并观察目标服务是否崩溃即可。
这里我们不重复造轮子了,直接使用 Cisco-Talos 团队开源的 mutiny-fuzzer 框架【7】,在我们指定了一个模版后,它会调用 radamsa 对其变异,自动发送这些数据包,并包含日志记录、中断恢复等功能。
预处理 wireshark 导出的流量:
生成的 fuzz 模版如下,fuzz 后面的就是待变异的部分。
也可以结合 sub 字段实现只变异特定部分,其中的单引号起连接作用。
由于对协议不熟悉,这里我们选择对整个数据包进行变异,kill 掉原来的 SMB 进程,在终端中重新运行,这样方便查看日志信息,随后开启 fuzz,发包时间间隔可以设置小一点。
五百年后 (●′ω`●),目标服务崩了,日志里显示段错误。
使用 -r 选项指定测试样例进行多次测试后,确认是 seed 10146 这个包引发的 crash,由于我们开启了 –logAll 日志记录,可以查看所有发出的数据包。
简化一下,PoC 如下,可以稳定的 crash。
1 | #!/usr/bin/env python |
在后续的 fuzz 过程中,我们发现了多个可以引起最新版 RouterOS SMB 服务异常崩溃的流量,其中两个 PoC 如下:
Crash 1:
1 | #!/usr/bin/env python |
Crash 2:
1 | #!/usr/bin/env python |
在 RouterOS 6.40.5、6.41.4、6.43.11、6.44.0 等多个版本测试,确认上述流量都可以打崩 SMB 服务。
CVE-2018-7445
有趣的是,后两个 crash 很像 CVE-2018-7445 漏洞。为啥这个官方已经修复过的漏洞能把最新版打崩,这引起了我的好奇。
漏洞及补丁分析
CVE-2018-7445 漏洞存在于 sub_8054607 函数中,a1 是目标缓冲区的地址,a2 指向请求数据的第 38 个字节,将形如 length1:payload1 length2:payload2
的数据拷贝到栈上,当 length 为 0 才结束拷贝,导致堆栈溢出。
只要构造 b’\x81\x00LENGTH’ + b’A’ * LENGTH, LENGTH > 0x43 就可以进入漏洞函数。
官方的修复方案如下,删掉了漏洞函数,重写了拷贝代码。构造数据 b’\x81\x00\x00\xfa’ + b’A’ 34 + b’\x20’ + b’a’ (0xfa - 35) 就可以进入拷贝的逻辑,但是 v7 限制了只能拷贝 32 字节,所以,凉凉…
因此 fuzz 出来的多个 crash 虽然流量相似,但是和 cve-2018-7445 不是同一个漏洞。
exp
漏洞和补丁分析完了,顺便说下 exp。网上公开的分析文章已经非常详细了,总结下利用链有以下几点:
利用堆栈溢出可以直接劫持 EIP, 只开了 NX 和 ASLR。
栈随机化,堆没有随机化,可在堆中固定地址找到请求数据,因此可以稳定的注入 shellcode。
构造 ROP 调用 mprotect() 修改堆的保护属性,使堆可执行,绕过 NX,最后控制 EIP 跳转到堆中执行 shellcode。
原 exp 是漏洞作者基于 x86 架构的云托管路由器开发的,只需要修改几个地址,就可以在虚拟机环境中使用。
修改后的 exp 如下:
1 | #!/usr/bin/env python |
总结
fuzz 还是很有意思的,跑的几个 crash 无法利用,提交 MikroTik 官方了… ( ゚д゚)つBye
参考链接
【1】: Finding and exploiting CVE-2018–7445 (unauthenticated RCE in MikroTik’s RouterOS SMB)
https://medium.com/@maxi./finding-and-exploiting-cve-2018-7445-f3103f163cc1
【2】:MikroTik RouterOS SMB Buffer Overflow
https://medium.com/@maxi./finding-and-exploiting-cve-2018-7445-f3103f163cc1
【3】:MikroTik RouterOS Jailbreak
https://github.com/0ki/mikrotik-tools
【4】:busybox binaries download
https://busybox.net/downloads/binaries/1.30.0-i686/
【5】:gdbserver
https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver
【6】: radamsa
https://gitlab.com/akihe/radamsa
【7】mutiny-fuzzer
https://github.com/Cisco-Talos/mutiny-fuzzer