記一次粗淺的釣魚樣本分析過(guò)程

本文投稿作者:fatboyQ_Q
0x00 前言
一切的一切要從(盤古開天辟地)幾個(gè)月前的某大型網(wǎng)安活動(dòng)期間說(shuō)起。話說(shuō)當(dāng)時(shí)一位素未謀面的基友給在下發(fā)了一個(gè)疑似釣魚的樣本,說(shuō)是讓我試試看下能不能溯源出攻擊方。于是雖然作為一名萌新,此前也從未接觸過(guò)類似的工作,但想到既然是基友的請(qǐng)求,那也唯有欣然接受了。不過(guò)值得慶幸的是,最后雖然折騰了大半天,而且好像也沒(méi)幫上什么忙,但與樣本分析的初接觸過(guò)程中,還是學(xué)到了不少東西的。唯獨(dú)可惜的是,由于當(dāng)時(shí)的自己沉迷摸魚,沒(méi)有及時(shí)把過(guò)程記錄下來(lái)。如今偶然再想起,決定補(bǔ)寫一文章——但也只能力求復(fù)刻當(dāng)時(shí)的真實(shí)情況了。所以如果發(fā)現(xiàn)文中一些時(shí)間戳對(duì)不上的,請(qǐng)自動(dòng)忽略,個(gè)人認(rèn)為不影響文章的真實(shí)性。。。
0x01 投石問(wèn)路
因?yàn)闃颖臼腔阎苯影l(fā)給我的,所以樣本的發(fā)現(xiàn)過(guò)程這里按下不表,直奔主題吧。
拿到樣本,一個(gè)樸實(shí)無(wú)華的 exe 可執(zhí)行文件,再看這 exe 的圖標(biāo)更是已經(jīng)爛大街的了:

于是本著沒(méi)吃過(guò)豬肉也見過(guò)豬跑的道理,想起平時(shí)摸魚時(shí)也看過(guò)不少大佬們做過(guò)的免殺和樣本分析的文章,先草率地做出了一個(gè)最簡(jiǎn)單的猜想:很可能又是一個(gè)使用 rar 自解壓制作的釣魚樣本。
于是就草率地先嘗試使用 bandzip 打開,發(fā)現(xiàn)格式不對(duì):

顯然,這樣草率的猜想果然是不靠譜的,遂轉(zhuǎn)換思路。
于是又想到,正所謂他山之石可以攻玉,況且自己之前在這方面也幾乎零基礎(chǔ),那不妨先扔在線的分析網(wǎng)站跑一波吧,就算只搞到個(gè)大概的報(bào)告也可以供參考。于是將樣本拖進(jìn) VT,立等片刻后,得到結(jié)果:

只是瞧瞧這多引擎的檢測(cè)結(jié)果,居然還有點(diǎn)小意外?!于是這個(gè)情況頓時(shí)讓我對(duì)這個(gè)樣本又多了幾分好奇:看來(lái)有機(jī)會(huì)還是要搞清楚這個(gè)樣本是怎么制作的呀。再說(shuō)作為一條有理想的咸魚,一直這樣依賴工具也不是辦法,有機(jī)會(huì)還是要鍛煉下自己的動(dòng)手能力。于是決定為基友獻(xiàn)出自己的”第一次“,嘗試手動(dòng)分析下這個(gè)樣本,順便看看它這個(gè)查殺率是怎么做到的。
0x02 循序漸進(jìn)
說(shuō)是手動(dòng)分析,但一來(lái)自己經(jīng)驗(yàn)不足,二來(lái)身邊也沒(méi)有隨時(shí)可抱大腿的大佬來(lái)解疑答惑,那眼前 VT 的分析結(jié)果還是要參考下的,起碼起到風(fēng)向標(biāo)的作用。
VT 分析結(jié)果的前面幾項(xiàng)都沒(méi)有什么特別有價(jià)值的信息。直至切換到分析結(jié)果中的 BEHAVIOR 選項(xiàng)卡,發(fā)現(xiàn)樣本執(zhí)行過(guò)程釋放和加載了一個(gè)名為python27.dll
的動(dòng)態(tài)鏈接庫(kù)文件:

看到這,作為一名常年網(wǎng)上沖浪、已經(jīng)將喊666刻進(jìn)DNA里的資深菜雞,我的 privilege
又盡數(shù)體現(xiàn)了:根據(jù)經(jīng)驗(yàn),這大概又是一個(gè) PyInstaller 打包的 exe文件。
于是現(xiàn)學(xué)現(xiàn)賣,從搜索引擎得知:
PyInstaller 打包的文件可以使用一個(gè)名為 ?
pyinstxtractor.py
的 腳本 來(lái)進(jìn)行解包反編譯得到pyc
文件pyc
是 python 源代碼執(zhí)行編譯后得到的文件??墒褂?uncompyle6
等工具進(jìn)行反編譯,得到最終的 python源碼因此需準(zhǔn)備工具有:
pyinstxtractor.py
)(可github獲?。?、uncompyle6
(可直接使用pip install
安裝)
有了以上前置知識(shí)后,那么依葫蘆畫瓢——下載腳本并執(zhí)行: python pyinstxtractor ?flashplayerpp_install_cn.exe
:

幸運(yùn)的是,過(guò)程十分順利,在當(dāng)前目錄下生成了解壓文件夾:

然后,根據(jù)資料,在解壓目錄中找到可疑的 pyc
文件,名為 ?main
:

按照劇本,這里的 main
應(yīng)該就是 main.py
編譯之后得到的 pyc
文件。但實(shí)際操作中,無(wú)論是使用在線反編譯工具如 tools.bugscaner.com/decompyle/,還是本地的?uncompyle6
?和 EasyPythonDecompiler
,發(fā)現(xiàn)都無(wú)法反編譯成功。尤其是 uncompyle6
,執(zhí)行 uncompyle6 -o main.py main.pyc
后給出了詳細(xì)報(bào)錯(cuò):

根據(jù)報(bào)錯(cuò)信息不難發(fā)現(xiàn),報(bào)錯(cuò)與一個(gè) magic number
的概念有關(guān)。因此要想繼續(xù)分析流程,就必須先解決 magic number
的問(wèn)題。
于是繼續(xù)求助搜索引擎。得到解釋如下:
magic number
是pyc
文件結(jié)構(gòu)的一部分,其位于文件開頭的前 4 個(gè)字節(jié),代表了 python 的版本信息。出現(xiàn)
unknown magic number
錯(cuò)誤,很可能是制作樣本的釣魚佬對(duì)pyc
文件做了手腳。這種情況在 CTF 中也比較常見在知道 python 版本的情況下,可通過(guò)補(bǔ)全
magic number
信息來(lái)嘗試修復(fù)無(wú)法還原的pyc
文件
0x03 原來(lái)是虛晃一槍
老實(shí)說(shuō),看完上面收集回來(lái)的信息,我當(dāng)時(shí)的表情就是這樣的:

顯然,事情到這一步已經(jīng)超出了一個(gè)我這個(gè)菜雞的預(yù)期了。
所以說(shuō),要半途而廢嘛,也不是沒(méi)想過(guò)。。??蓺夥斩间秩镜竭@里了,不繼續(xù)下去好像也不太說(shuō)得過(guò)去的樣子。。。
于是,本著準(zhǔn)備手動(dòng)修復(fù) magic number
信息的想法, winhex 打開 main.pyc,卻驚喜地發(fā)現(xiàn):

main
文件里面的竟然是源碼明文?!!
這。。這。。。這是咋回事呢?跟說(shuō)好的劇本不一樣啊。。這樣難道不會(huì)影響打包的 exe 文件的運(yùn)行的嗎?難道這就是這個(gè)樣本被查殺率不高的原因?
于是本著知其所以然的心態(tài),本人又圍繞這這個(gè)問(wèn)題,嘗試找了不少資料。但可惜水平有限,最終也是沒(méi)找到相應(yīng)的解釋,對(duì)此還希望有知道的師傅能指教一二。。。
不過(guò)言歸正傳,既然拿到了 python 的源碼,那一切就好辦了。。
直接將 main.pyc
改名為 main.py
,用 sublime 打開,得到:

簡(jiǎn)單看了下源碼,發(fā)現(xiàn)執(zhí)行的過(guò)程如下:
1、
is_admin
?函數(shù)先判斷是否為管理員權(quán)限,如果不是,則調(diào)用 API 請(qǐng)求以管理員身份運(yùn)行該樣本2、如果當(dāng)前已經(jīng)是管理員權(quán)限,則執(zhí)行
NDdFrvsmTh
函數(shù)3、
NDdFrvsmTh
函數(shù)開辟兩個(gè)線程,一個(gè)線程執(zhí)行TFZWSTEcc
函數(shù)下載真正的 flash 安裝包到本地執(zhí)行安裝,另一個(gè)線程執(zhí)行TENRWCTE
函數(shù)加載 shellcode 使主機(jī)上線4、
TFZWSTEcc
函數(shù)先從遠(yuǎn)程地址 https://www.xxx.us/xxxxxyyyyyyvszzzzz 加載 CS 的shellcode,然后幾句cPickle.loads
分別為 shellcode 的執(zhí)行分配內(nèi)存空間、設(shè)置執(zhí)行權(quán)限、創(chuàng)建線程并最終執(zhí)行:

(PS:可能是我愚鈍,總之一番概覽下來(lái),好像除了從遠(yuǎn)程加載 shellcode 而不是硬編碼到代碼中去之外,也沒(méi)啥特別的。。。?所以至此 VT 的這個(gè) 6/64 的查殺率似乎也成了我的一個(gè)未解之謎。。:joy: :joy: ?:joy: )
同時(shí)既然已經(jīng)知道 shellcode 的遠(yuǎn)程下載地址,那么可直接嘗試獲取 shellcode 到本地進(jìn)行分析。編寫了個(gè)簡(jiǎn)單的腳本:

執(zhí)行后順利得到 shellcode.bin 文件:

最后簡(jiǎn)單使用 strings 即可得到 teamserver 的地址:

不過(guò)可惜的是,上了CDN:

明顯,這種情況,以本人的水平也暫時(shí)談不上什么反制了。最后將自己的分析過(guò)程打包給基友后就洗洗睡第二天繼續(xù)吃瓜去了。。。
0xFF 總結(jié)
本文主要記錄了本人在對(duì)一釣魚樣本進(jìn)行分析溯源學(xué)習(xí)時(shí)的踩坑經(jīng)過(guò)。整個(gè)過(guò)程可簡(jiǎn)單概況為以下幾部分:
使用
pyinstxtractor
反編譯 pyinstaller 打包的exe,得到 pyc 文件嘗試使用
uncompyle6
反編譯 得到的pyc
文件,進(jìn)一步得到 python 源碼未果根據(jù)
uncompyle6
使用過(guò)程中出現(xiàn)的問(wèn)題,尋找原因和解決辦法,嘗試手動(dòng)修復(fù)pyc
文件嘗試修復(fù)
pyc
文件時(shí)直接發(fā)現(xiàn) python 源碼(是資料中未提及過(guò)的情況,很驚奇,遂于尋找原因,但未果)分析 python 源碼,得到 teamserver 地址。最后能力有限,不會(huì)反制
最后本人技術(shù)粗淺,文章措辭輕浮,肯定有許多錯(cuò)漏之處,還望各位大佬大力斧正的同時(shí)輕噴。。。