01 隱蔽持久駐留
1.1 背景
持久化是一個攻擊鏈周期中非常重要的環(huán)節(jié),指用webshell、反彈shell、后門、rootkit長期控制失陷機器的一種技術(shù),可能會涉及到dns隧道、http、icmp 隧道以及加密流量,從而達到一直控制失陷機器而不被發(fā)現(xiàn)的目標。
在攻擊者利用漏洞獲取到某臺機器的控制權(quán)限之后,會考慮將該機器作為一個持久化的據(jù)點,種植一個具備持久化的后門,即使在設(shè)備重啟、憑據(jù)修改或其他可能破壞當前惡意活動的操作發(fā)生后,也能夠隨時連接該被控機器進行深入滲透。
1.2 持久駐留方法

1.2.1 隱藏啟動
1.2.1.1 Systemd啟動
System默認從目錄/etc/systemd/system/讀取配置文件。但是里面存放的大部分文件都是符號鏈接,指向目錄/lib/systemd/system/,真正的配置文件存放于這個目錄中。
一般系統(tǒng)手工創(chuàng)建的單元文件建議存放在/etc/system/system/目錄下。
1. 首先編譯提前配置好的后門文件。
2. 在/etc/目錄下創(chuàng)建demo.local(名稱),里面寫入直接執(zhí)行后門文件。
3. 修改權(quán)限。
4. 在/etc/system/system/目錄下創(chuàng)建一個demo.service文件。
5. 設(shè)置啟動鏈接。
6. 重啟獲得shell。
1.2.1.2二進制文件感染
基本流程
完成可用空間的后門代碼(添加區(qū)段);
劫持執(zhí)行流程;
注入后門代碼;
恢復執(zhí)行流程。
第一步:需要找到可用空間。
如何在PE文件中選擇合適的空間來插入后門代碼非常重要, 這將影響到后門被檢測到的風險系數(shù)。
借助于一個名為Cminer的工具,很容易枚舉二進制文件的所有代碼洞。
./Cminer putty.exe 300 命令枚舉Code Caves大于300字節(jié)。
在這種情況下,有5個好的Code Caves可以使用。起始地址給出了Caves的虛擬內(nèi)存地址(VMA)。這是Caves的地址,當PE文件加載到內(nèi)存中時,文件偏移量是以字節(jié)為單位的PE文件內(nèi)的Caves地址。
由此可見大部分Caves都在數(shù)據(jù)段內(nèi),因為數(shù)據(jù)段沒有執(zhí)行特權(quán)段標志, 這里需要更改。后門代碼大概400-500字節(jié)左右,所以5個Caves是足夠的。Caves的起始地址應該被保存,在將段特權(quán)更改為R/W/E后,第一步的后門過程就完成了。
第二步:通過修改目標可執(zhí)行文件的指令,將執(zhí)行流重定向到后門代碼。
這里有一個關(guān)于選擇將被修改的指令重要細節(jié), 所有二進制指令具有字節(jié)大小,為了跳轉(zhuǎn)到后門代碼地址,將使用5或6字節(jié)的長跳躍。因此,當修補二進制時,將被修補的指令需要與長跳轉(zhuǎn)指令的大小相同,否則上一條或下一條指令將被破壞。
在putty啟動后的界面中, 點擊 “Open” 按鈕會啟動一個檢查IP地址是否有效的功能。
如果IP地址字段值不為空并且有效,則它啟動嘗試連接給定IP地址的連接功能。如果客戶端成功創(chuàng)建SSH會話,將彈出一個新窗口并請求憑據(jù)。
此處是重定向發(fā)生的點,因為AV產(chǎn)品不能夠復制這種復雜的環(huán)境,植入的后門將不會被自動化沙盒和動態(tài)分析機制檢測到。
使用基本的逆向方法,搜索下面的字符串和字符串引用,不難找到連接函數(shù)的地址,方法如下:客戶端建立與給定IP的連接后,有一個字符串 “l(fā)ogin as:” 打印到出現(xiàn)的窗口。這個字符串可以幫助我們找到連接函數(shù)的地址,IDA Pro在這方面做得很好。
為了找到 “l(fā)ogin as:” 字符串, 在IDA上依次打開 Views->Open Subviews->Strings
找到字符串后,雙擊轉(zhuǎn)到所在位置,在數(shù)據(jù)節(jié)內(nèi)部IDA查找所有對字符串的交叉引用,按 “Ctrl+X”,顯示所有交叉引用,并這個引用在打印 “l(fā)ogin as:” 字符串的函數(shù)內(nèi)部。
這里是要修補的指令。在進行任何更改之前,請注意上下文的指令。
執(zhí)行后門代碼后指令將再次使用。
通過將PUSH 467C7C指令改為JMP 0x47A478,完成后門過程的重定向階段。需要注意的是下一個指令地址。它將在執(zhí)行后門代碼后用作返回地址。
第三步:后門代碼注入。
首先在執(zhí)行后門之前保存寄存器中的內(nèi)容。寄存器中的每個值對于程序的執(zhí)行都是非常重要的。通過在代碼的OEP(程序入口點)放置PUSHED和PUSHED指令,把所有寄存器內(nèi)的值和寄存器標志都存儲在堆棧中。這些值將在執(zhí)行完后門代碼之后彈出,以便程序可以繼續(xù)執(zhí)行不出錯。
使用的后門代碼是meterpreter反向TCP ShellCode。但是在ShellCode中需要做少量修改。通常反向TCP ShellCode會有嘗試連接到處理程序的次數(shù)或時間限定,如果連接失敗,則通過調(diào)用ExitProcess API調(diào)用關(guān)閉進程。
這里是問題所在,如果連接到處理程序失敗,putty客戶端的執(zhí)行將停止。改變幾行ShellCode使其每次連接失敗時ShellCode重試連接處理器,這樣也會相應的減少ShellCode的體積。
在匯編代碼中進行更改后,使用nasm -f bin stager_reverse_tcp_nx.asm命令進行編譯?,F(xiàn)在反向的TCP ShellCode已經(jīng)可以使用了,但是它不會被直接放置。我們的目標是在新線程上執(zhí)行ShellCode。
為了創(chuàng)建一個新的線程實例,需要另一個ShellCode,使CreateThreadAPI調(diào)用指向反向TCP ShellCode。這里使用Metasploit項目中創(chuàng)建線程的shellcode。
將 createthread.asm 文件中的代碼轉(zhuǎn)換為十六進制格式的ShellCode,使用nasm -f bin createthread.asm命令進行編譯。在這里,ShellCode準備插入到Caves中,但在插入ShellCode之前應該對其編碼,以便繞過AV產(chǎn)品的靜態(tài)/特征分析機制。因為Metasploit項目中的所有編碼器被大多數(shù)AV產(chǎn)品所知,所以強烈建議使用自定義編碼器。
在正確編碼ShellCode之后,就可以把它插入Code Caves。選擇在PUSHFD下的指令,然后在免調(diào)試器上按下 “Ctrl + E”,ShellCode將以十六進制格式粘貼。
使用xxd -ps createthread命令,以十六進制格式打印編碼創(chuàng)建線程的ShellCode或使用十六進制編輯器打開ShellCode并復制十六進制值。當將十六進制值粘貼到調(diào)試器時,需要注意字節(jié)限制,因為這些修補操作是用免試器進行的,免調(diào)試器在粘貼到編輯代碼窗口時有一個字節(jié)限制。粘貼的ShellCode可能會有遺漏。當所有ShellCode粘貼到Code Cave時后門代碼就插入完成。
第四步:恢復執(zhí)行流程。
在創(chuàng)建后門代碼線程之后,程序需要恢復到其正常執(zhí)行流程,這意味著EIP應該跳回到將執(zhí)行重定向到Cave的函數(shù)。但是在跳回到該函數(shù)之前,應該檢索所有保存的寄存器。
通過在ShellCode的末尾放置POPFD和POPAD指令,所有保存的寄存器都以相同的順序從堆棧中彈出。在檢索寄存器后,還有一件事要做,即執(zhí)行被劫持的指令。
為了將程序的執(zhí)行重定向到Code Cave, 我們將PUSH 467C7C指令替換為了JMP 0x47A478。把PUSH 467C7C指令放在最后,此時被劫持的指令也被檢索。現(xiàn)在可以返回到通過插入JMP 0x41CB73指令將執(zhí)行重定向到Cave的函數(shù)的時候,結(jié)果代碼應如下圖所示。
最后選擇所有修補和插入的指令,按右鍵單擊并復制到可執(zhí)行文件。此操作需要對已修改的每個指令執(zhí)行。當所有指令被復制并保存到文件時,關(guān)閉調(diào)試器并測試可執(zhí)行文件,如果可執(zhí)行文件運行順暢,則后門可以使用。
02 總結(jié)
隨著對抗手段日益復雜化,持久化技術(shù)也將演變得更加隱蔽,同時也對防守方提出了一個獨特的挑戰(zhàn),由于它們可以隱蔽執(zhí)行后門代碼,所以檢測和分析過程就更加具有挑戰(zhàn)性,需要采集大量的數(shù)據(jù)進行分析判別,如何在大量的日志中如何有效的進行檢測,避免過度消耗資源,都是安全運營人員要面臨的挑戰(zhàn)。
后續(xù)將繼續(xù)介紹隱蔽持久駐留的其他方法,敬請期待。
- 關(guān)鍵詞標簽:
- 天融信 檢測與防護 持久化