天融信防火墻密碼恢復(fù)手記
天融信防火墻密碼恢復(fù)手記
公司在用的一款天融信防火墻,密碼意外遺失,無(wú)法登陸管理平臺(tái)。雖然防火墻可以正常工作,但卻無(wú)法修改配置,不能根增加和刪除訪(fǎng)問(wèn)列表中的IP地址,不能調(diào)整訪(fǎng)問(wèn)策略。防火墻默認(rèn)僅開(kāi)通https web管理界面,未開(kāi)啟telnet、ssh等其他管理通道。下面是學(xué)習(xí)啦小編跟大家分享的是天融信防火墻密碼恢復(fù)手記,歡迎大家來(lái)閱讀學(xué)習(xí)。
天融信防火墻密碼恢復(fù)手記
聯(lián)系天融信廠(chǎng)家尋求技術(shù)支持,被告知必須返廠(chǎng)更換芯片,費(fèi)用大約在2000元左右(網(wǎng)上搜了一下,幾乎所有密碼遺失的客戶(hù)最終都只能選擇返廠(chǎng))。公司用于該網(wǎng)絡(luò)聯(lián)網(wǎng)的僅此一臺(tái)防火墻設(shè)備,終端數(shù)量在500以上,無(wú)其他硬件備份方案。因用戶(hù)眾多,管理要求細(xì)致,防火墻配置非常復(fù)雜,保存的配置文件也不是最新的。若返廠(chǎng)維修的話(huà),則無(wú)法找到完備的替代方案。
于是決定先自己想辦法,開(kāi)啟密碼恢復(fù)之旅。Go!
猜測(cè)密碼,自動(dòng)驗(yàn)證
首先想到的是根據(jù)可能的密碼規(guī)則和常用組合,構(gòu)造一個(gè)密碼字典,通過(guò)編寫(xiě)簡(jiǎn)單的python腳本進(jìn)行登錄驗(yàn)證。萬(wàn)一不行的話(huà),就窮舉來(lái)嘗試暴力破解。
可是開(kāi)始跑腳本的時(shí)候發(fā)現(xiàn)想法實(shí)在太天真了,存在兩個(gè)致命的問(wèn)題:
防火墻白天負(fù)荷過(guò)重,Web響應(yīng)非常慢。有時(shí)候一個(gè)請(qǐng)求可能在半分鐘以上。
Web管理平臺(tái)有登錄次數(shù)限制,大約6次密碼錯(cuò)誤以后,就會(huì)鎖定賬號(hào)一段時(shí)間。
在嘗試了幾十個(gè)最可能出現(xiàn)的密碼組合后,徹底放棄了這條捷徑。
看來(lái)偷懶是不成了,必須得動(dòng)真格的。
搜尋漏洞,獲取控制權(quán)
nmap掃描發(fā)現(xiàn)防火墻只開(kāi)通了https端口。不是專(zhuān)業(yè)的安全研究人員,只能在網(wǎng)上搜索該款防火墻的漏洞資料,不(suo)幸的是,還真發(fā)現(xiàn)了不少。
找到的第一篇文章 《看我如何在2小時(shí)內(nèi)控制100+天融信安全設(shè)備的》 提到了Heartbleed漏洞,卻未對(duì)漏洞利用方式做過(guò)多解釋。需要更多學(xué)習(xí)資料,根據(jù)這個(gè)方向繼續(xù)搜索,又找到了一些文章:
NSA Equation Group泄露的天融信產(chǎn)品漏洞分析(一)
天融信率先發(fā)布BASH爆出高危漏洞規(guī)則庫(kù)
天融信防火墻openssl漏洞可能導(dǎo)致信息泄漏
天融信防火墻關(guān)于“方程式組織”漏洞處置公告
其中,NSA Equation Group那篇文章信息量最高,對(duì)漏洞的特征和產(chǎn)生的原因分析的非常透徹,利用方式也做了簡(jiǎn)要說(shuō)明。按照文章的提示,用Brup進(jìn)行Eligible Candidate漏洞測(cè)試(打算用Postman,但因chrome的https證書(shū)問(wèn)題放棄),漏洞果然還在!
懷著激動(dòng)的心情,嘗試了 ls -la />/www/htdocs/1、find / -type f>/www/htdocs/1 等指令,對(duì)防火墻文件系統(tǒng)的目錄結(jié)構(gòu)進(jìn)行初步了解,也看到了配置文件存放的位置。執(zhí)行cp /tos/conf/config>/www/htdocs/1,把配置文件down下來(lái)一看,果然是新鮮的味道。
啟動(dòng)telnetd服務(wù)并嘗試連接,報(bào)錯(cuò),估計(jì)是沒(méi)有加特定啟動(dòng)參數(shù)的緣故,沒(méi)做深入研究??磥?lái)暫時(shí)還是只能通過(guò)https漏洞方式跑命令了。
隨著執(zhí)行命令次數(shù)越來(lái)越多,Brup構(gòu)造請(qǐng)求的方式效率太低,于是寫(xiě)了簡(jiǎn)單的Python函數(shù)在IPython下面跑,終覺(jué)得靈活性不夠。最后決定采用HTTPie命令行的方式發(fā)送https請(qǐng)求(curl沒(méi)有httpie方便),后續(xù)所有命令都通過(guò)這種方式交互。
1 $ http --verify=no https://x.x.x.x/cgi/maincgi.cgi 'cookie: session_id=x`ls -la /tmp>/www/htdocs/1`'
文件上傳,執(zhí)行腳本文件
之前都是一次請(qǐng)求執(zhí)行一條命令,效率太低,也存在諸多限制。最好的方式是上傳一個(gè)sh腳本在防火墻上執(zhí)行,這就需要以某種方式傳送文件到防火墻上去。
另一方面,根據(jù)漏洞名稱(chēng)和Equation Group搜索到這篇文章:Equation Group泄露文件分析,才注意到這是國(guó)際頂尖黑客組織,也是NSA合作的方程式黑客組織(Equation Group),被另一個(gè)名為“The ShadowBrokers”的黑客組織攻下了,珍藏的系列高級(jí)工具被打包分享。這可是個(gè)好東西!趕緊下載解密,找到ELCA的漏洞利用代碼,運(yùn)行后卻發(fā)現(xiàn)沒(méi)有如逾期般的啟動(dòng)nopen遠(yuǎn)程管理軟件,原因未知,頗有些失望。不過(guò)在py源碼中看到了文件上傳的方式,其實(shí)就是利用了cgi文件上傳處理方式,它每次會(huì)在/tmp目錄下生成一個(gè)cgi*的臨時(shí)文件。ELCA利用代碼的流程是連續(xù)執(zhí)行多次指令,第一次 rm /tmp/cgi*清理tmp目錄,接著post上傳文件同時(shí)復(fù)制保存一份cp /t*/cg* /tmp/.a,再加執(zhí)行權(quán)限chmod +x /tmp/.a,最后執(zhí)行 /tmp/.a。
當(dāng)然,代碼并沒(méi)有直接上傳一個(gè)可執(zhí)行文件,而是巧妙(恕見(jiàn)識(shí)少,我知道*nix下經(jīng)常這樣干)的將需要的多個(gè)文件用tar打包后,附到sh腳本的最后。在sh腳本中用dd命令將tar包c(diǎn)opy出來(lái)再解壓運(yùn)行。下面是工具中stage.sh的部分代碼:
文件tar打包的Python代碼片段:
就我的需求而言,只是上傳腳本執(zhí)行,就不用做得那么復(fù)雜了。簡(jiǎn)單的post我的sh腳本,同時(shí)執(zhí)行sh /tmp/cgi*。前提是我的sh腳本中都做了清理工作rm /tmp/cgi*。
1 http --verify=no -b -f POST https://x.x.x.x/cgi/maincgi.cgi 'Cookie: session_id=x`sh /t*/cg*`' a@test.sh; http --verify=no https://x.x.x.x/1
HTTPie可以用 uploadfilename@localfilename 的方式很方便的實(shí)現(xiàn)文件上傳。之所以?xún)蓷l指令在一行是為了方便查看前一個(gè)腳本的輸出。
123456789101112 #!/bin/sh# 清除/tmp/cgi*,防止干擾下次運(yùn)行rm -f /t*/cgi* echo =============================== >/www/htdocs/1date >>/www/htdocs/1 echo "***************" >>/www/htdocs/1cd /tmpps>>/www/htdocs/1netstat -nltp >>/www/htdocs/1ls -la /tos/etc /data/auth/db /tmp >>/www/htdocs/1
上面的示例腳本就可以一次進(jìn)行多種操作,獲取進(jìn)程信息、網(wǎng)絡(luò)連接情況、目錄文件等多種信息,大幅減少交互次數(shù)提高效率。
逆向分析,尋找密碼
做了很多準(zhǔn)備工作,找到了比較便捷的腳本執(zhí)行方式。而且根據(jù)ps結(jié)果來(lái)看,指令是以root權(quán)限運(yùn)行的。接下來(lái)要開(kāi)始干正事了,tar cf /home/htdocs/1 / 打包文件系統(tǒng),down下來(lái)準(zhǔn)備逆向分析。因?yàn)閣eb登錄入口指向maincgi.cgi,就從它開(kāi)始。
逆向分析的過(guò)程相當(dāng)繁雜、漫長(zhǎng)、枯燥乏味,具有相當(dāng)?shù)奶魬?zhàn)性,所以需要堅(jiān)定的毅力和不時(shí)涌現(xiàn)的靈感。無(wú)數(shù)次調(diào)整思路和方向,無(wú)數(shù)次尋找新的突破口。
我現(xiàn)在也記不清當(dāng)初分析時(shí)的前因后果,就把一些分析的結(jié)果整理下,做一個(gè)簡(jiǎn)單的分享。
入口 maincgi.cgi
maincgi.cgi 位于 /www/cgi/ 目錄下。用IDA進(jìn)行逆向分析。
根據(jù)登錄form提交的 username 和 passwd 在string窗口搜索,x跟蹤調(diào)用情況分析,最終來(lái)到 000403D4 函數(shù)內(nèi)。
下面是更容易理解的C偽代碼(我開(kāi)始分析的時(shí)候沒(méi)找到可用的hexrays,這是事后撰寫(xiě)此文時(shí)找到的。:-( 工欲善其事必先利其器啊!):
可以看到,username和passwd參數(shù)都原封不動(dòng)的傳入到login函數(shù),想必沿著這個(gè)方向一定能找到密碼保存的地方。
跟進(jìn)發(fā)現(xiàn)login是import函數(shù),不在maincgi.cgi中實(shí)現(xiàn)。為了方便,我把lib和so目錄下所有文件的符號(hào)表都進(jìn)行了分析,結(jié)果保存在一個(gè)文件中備查。
1 $ nm -D tos/lib/* tos/so/* > symbols.txt
很快發(fā)現(xiàn) login 函數(shù)在 /tos/so/libwebui_tools.so 中實(shí)現(xiàn)。
入了RPC的坑
本以為找到 libwebui_tools.so 中的login實(shí)現(xiàn),一切皆可水落石出。誰(shuí)料還是 too young, too naive。
根據(jù)export表很快定位到login函數(shù)的實(shí)現(xiàn),開(kāi)始是TLS連接127.0.0.1:4000,接著是一堆錯(cuò)誤處理代碼。
其中有一個(gè) gui_send_reqx 函數(shù)的調(diào)用參數(shù) CFG_AUTH 引起了我的注意,猜測(cè)是一種自定義的類(lèi)RPC實(shí)現(xiàn)。
唉,還是C偽代碼看得清楚啊!再次哭暈在廁所 :-(
既然不是通過(guò)本地.so調(diào)用,那只有知道到底是誰(shuí)提供了這個(gè)rpc服務(wù),才能找到接下來(lái)的路。
好用的netstat
好在我們有執(zhí)行代碼的權(quán)限,好在防火墻里面有netstat命令。執(zhí)行netstat -nltp >>/www/htdocs/1 得到下面的結(jié)果:
一目了然。原來(lái)服務(wù)是 tos_configd 提供的呀!被ELCA漏洞利用腳本誤導(dǎo)了,以為是只是一個(gè)命令行shell,之前跟過(guò),但沒(méi)有細(xì)看。這不,還是要回頭找它。
百轉(zhuǎn)千回
tos_configd 分析過(guò)程并非一帆風(fēng)順。
根據(jù)RPC傳遞的參數(shù)CFG_AUTH作為線(xiàn)索進(jìn)行追蹤,看到RPC支持多個(gè)命令。當(dāng)命令為CFG_AUTH時(shí),將數(shù)字5寫(xiě)到參數(shù)傳入的內(nèi)存區(qū)域某個(gè)變量中。沒(méi)有其他更多的信息,看來(lái)只能根據(jù)caller向上一步步追了。
代碼回到rpc的消息處理thread中,經(jīng)過(guò)逐步分析,定位到消息處理函數(shù)中。
跟進(jìn)去,可以看到大致的處理流程。有一個(gè)switch過(guò)程,case 5后面就是CFG_AUTH的處理代碼。5就是前面第一個(gè)過(guò)程中設(shè)置的變量。topsec_manager_auth函數(shù)用于接管用戶(hù)密碼鑒權(quán)工作,它是一個(gè)import函數(shù),按照前面的方法查到它在 /tos/so/libmanager.so 中實(shí)現(xiàn)。
勝利的曙光
libmanager的export表非常簡(jiǎn)練,似乎每一個(gè)都讓人頗感興趣。
先看看我們的目標(biāo)函數(shù)topsec_manager_auth:
信息量很大,到這里基本上就看到了勝利的曙光。
首先看到的是用戶(hù)名+密碼的MD5,然后傳入到 j_match_manager_name 函數(shù)中進(jìn)行校驗(yàn)。這不就是經(jīng)典的用戶(hù)名密碼校驗(yàn)過(guò)程嘛(未加salt)。
需要說(shuō)明一下的是,上圖中看到的username參數(shù)名稱(chēng)是我綜合各類(lèi)分析得知內(nèi)容后改名的,并不是想當(dāng)然,更不是IDA智能更名。username+32是密碼明文,這也是在前面的分析過(guò)程中得出的結(jié)論。
跟進(jìn)match_manager_name函數(shù),并沒(méi)有立即發(fā)現(xiàn)直觀(guān)的密碼文件讀取過(guò)程。取而代之的是,內(nèi)存中存在最多500個(gè)struct,其中包含了用戶(hù)名和MD5值,鑒權(quán)過(guò)程就是與其一一進(jìn)行匹配比對(duì)。Local_db_dev_node是一個(gè)全局buffer,搞清楚它的數(shù)據(jù)來(lái)源就找到根源了。
按X查看Local_db_dev_node的reference,還真不少。
第一個(gè)read_dev_manager_file就很像,跟進(jìn)去看一下。
Bingo!就是它了! /tos/etc/Tos_dev_manager_info 其實(shí)這個(gè)文件之前也注意到,不過(guò)沒(méi)曾想它居然保存了鑒權(quán)信息,而且是用戶(hù)名密碼拼接MD5這么簡(jiǎn)單!
用hexdump查看之前下載的Tos_dev_manager_info進(jìn)行驗(yàn)證,大小104字節(jié),與分析得到的struct大小完全一致。再看用戶(hù)名和密碼的位置,和分析Local_db_dev_node結(jié)構(gòu)完全一致。
清除最后的障礙
終于找到密碼保存到文件了,三下五除二,自己設(shè)定一個(gè)密碼,計(jì)算MD5值,修改Tos_dev_manager_info對(duì)應(yīng)的區(qū)域。文件上傳,覆蓋,重啟,等結(jié)果……
12 import hashlibprint(hashlib.md5('superman' + '111111').hexdigest())
幾分鐘后,設(shè)備起來(lái)了,趕緊試一下密碼,錯(cuò)誤!!!
郁悶,怎么會(huì)呢?down下/tos/etc/Tos_dev_manager_info一看,還是老數(shù)據(jù)??磥?lái)是工作還沒(méi)到位。
想起 libmanager 不是有那么多可疑的函數(shù)嗎?挑感興趣的進(jìn)去看看,比如write_memdata2flash:
對(duì),就它了。一般網(wǎng)絡(luò)設(shè)備修改配置以后,不都還來(lái)一個(gè) wr mem 嗎?估計(jì) /data/auth/db/ 才是最終保存數(shù)據(jù)的地方,/tos/etc可能重啟的時(shí)候會(huì)重新copy覆蓋。
再重新上傳一次修改好的Tos_dev_manager_info文件,只不過(guò)這次同時(shí)覆蓋了幾個(gè)目錄下的文件。重啟,用設(shè)定的密碼登錄,搞定!!!
走過(guò)的彎路
當(dāng)然,我分析過(guò)的文件遠(yuǎn)不止上面這些,也不是按照本文的思路一步一步走下來(lái),走了不少?gòu)澛?。憑感覺(jué),或?yàn)榱藢ふ倚戮€(xiàn)索,或漫無(wú)目的地毯式搜索。除了上面列舉的部分之外,還分析過(guò)其他幾個(gè).so文件,跟蹤過(guò)上百個(gè)函數(shù),多數(shù)與我需要的東西關(guān)系并不太大。
逆向分析就是這樣,不可能一帆風(fēng)順,也沒(méi)有既定的方法和思路。就是要有一種執(zhí)著的精神,在不斷的嘗試、糾錯(cuò)和總結(jié)過(guò)程中達(dá)到目的地。成功后那一刻豁然開(kāi)朗的成就感一直是我所癡迷的。
關(guān)于MD5破解不得不說(shuō)的事
既然知道了算法,也有了MD5數(shù)據(jù),是不是可以真正的找回當(dāng)初的密碼呢?
和第一步猜測(cè)密碼類(lèi)似,用python按照一定規(guī)則,生成可能的密碼序列。調(diào)用hashlib.md5() 計(jì)算hash值與目標(biāo)進(jìn)行比對(duì),結(jié)果跑了一天沒(méi)結(jié)果。
想著這種計(jì)算密集型的程序,在python和c之間切換太頻繁可能影響效率。又在網(wǎng)上找到一個(gè) Fast MD5 hash implementation in x86 assembly 匯編實(shí)現(xiàn)的快速算法,并且根據(jù)實(shí)際需求做了一定的優(yōu)化。運(yùn)行,依然無(wú)結(jié)果。
不甘心,再到網(wǎng)上搜索資料,發(fā)現(xiàn)人家都用GPU跑字典。好吧,我也找來(lái)一個(gè) Hashcat,在 i5 8G內(nèi)存 的iMac 上試跑,的確速度非???。然而,由于密碼長(zhǎng),計(jì)算量過(guò)大,最終也沒(méi)跑出結(jié)果,就此作罷。
現(xiàn)在想想,如果沒(méi)有密碼長(zhǎng)度、規(guī)則等任何信息的話(huà),光憑暴力破解一個(gè)非典型密碼,幾乎是 Mission Impossible。
搞定,收工
很久沒(méi)寫(xiě)過(guò)長(zhǎng)文,也沒(méi)發(fā)過(guò)技術(shù)類(lèi)文章。上一次可能要追溯到2001年8月的時(shí)候,曾以打雞血似的飽滿(mǎn)激情寫(xiě)過(guò)一篇軟件逆向習(xí)作。
此次防火墻密碼成功恢復(fù),其漏洞功不可沒(méi)。對(duì)我而言,又重溫了一把當(dāng)初年少時(shí)對(duì)技術(shù)的執(zhí)著。
最后,小結(jié)一下:
軟件逆向分析是個(gè)體力活。
工欲善其事必先利其器。
安全問(wèn)題無(wú)時(shí)無(wú)刻不在。