最近在分析惡意代碼的過程中,遇到了基于管道的后門,于是就學習了一下基于管道的shell后門原理,自己動手寫了一個簡單的shell后門。分享一下,供大家交流,如有錯誤之處,歡迎指出。聲明:本內容僅供用于分析惡意代碼時參考相關原理,請自覺遵守相關法律,嚴禁使用相關技術進行任何非法目的。否則,自行承擔后果。
原理
本次實現的是一個正向的shell,被控者作為服務器,在本地監聽一個端口,hacker作為客戶端,通過網絡來連接。整個原理如下圖所示:
hacker通過網絡來發送和接收數據,箭頭在這里表示數據流向,首先數據從hacker這里通過網絡套接字,傳入被控者的buffer區,然后buffer區通過一個管道寫入,CMD程序從該管道的另一端讀取,并作為CMD程序的輸入。
CMD程序執行完結果,將輸出寫入另一個管道,buffer區再從該管道的另一端讀取輸出,然后通過網絡套接字發送到hacker。
其中,CMD程序通過CreateProcess這個函數API來調用,在設置的時候,可以將程序的輸入輸出自行指定。
相關API
socket相關
關于socket相關的API,相信大家都很熟悉了,這里就簡單介紹一下創建TCP服務端程序的函數調用流程如下:
WSAStartup()->socket()->bind()->listen()->accept()->send()/recv()->closesocket()->WSACleanup()。
首先使用WSAStartup()來初始化Winsock庫,使用完畢后要調用WSACleanup()來釋放Winsock庫。然后使用socket()創建套接字,使用完畢后要調用closesocket()關閉套接字。對于WSAStartup()/WSACleanup()和socket()/closesocket()這樣的函數,最好在寫完一個函數后,就寫出另外一個函數,避免遺忘。創建完套接字后,就可以使用bind()、listen()、accept()、send()和recv()。其中為bind()函數指定地址和端口時,還涉及到sockaddr_in結構體,以及將主機字節序轉為網絡字節序的htons函數等。這些都是固定的流程,就不過多贅述了。
管道相關操作
管道是一種進程之間通信的技術,可以分為命名管道和匿名管道,匿名管道只能實現本地機器上兩個進程間的通信,常用來在一個父進程和子進程之間傳遞數據。我們這里使用匿名管道即可,因為匿名管道比命名管道相對簡單。
首先需要CreatePipe()創建管道,該函數的定義如下:
hReadPipe指向一個用來接收管道的讀取句柄的變量;
hWritePipe指向一個用來接收管道寫入句柄的變量;
lpPipeAttributes指向一個SECURITY_ATTRIBUTES結構的指針,它決定了返回的句柄是否可以由子進程繼承。如果lpPipeAttributes為NULL,則該句柄不能繼承。這里我們要將其設置為可繼承。SECURITY_ATTRIBUTES結構體比較簡單可以自行查閱MSDN設置。
nSize指定管道的緩沖區大小,以字節為單位。大小只是一個建議;系統使用值來計算一個適當的緩沖機制。如果此參數為零,則系統使用默認緩沖區大小。這里我們賦值為0即可。
向管道讀取或者寫入數據,直接調用ReadFile和WriteFile即可。在讀取數據前,可以先調用PeekNamePipe()查看管道中是否有數據,其定義如下:
hNamedPipe這個參數可以是一個命名管道實例的句柄,也可以是可以是一個匿名管道的讀取端的句柄。其他參數詳情可以查閱MSDN。
新建進程
相信大家對CreateProcess都不陌生,這里簡單回顧一下,函數定義如下:
在這里需要重點關注的是,設置lpStartupInfo結構體中的內容。該結構體如下:
重點是需要將hStdInput、hStdOutput、hStdError進行設置。設置為對應管道的讀寫句柄。
在本例中,hStdInput為管道1的讀句柄,hStdOutput、hStdError都設置為管道2的寫句柄。
編碼實現
創建套接字:
這里監聽的端口時888,任意IP地址都可連接。
創建管道:
創建子進程CMD:
設置死循環不斷的通過ReadFile()讀取管道中的內容,即CMD程序的執行結果,通過send()發送給hacker。然后不斷的通過recv()接收hacker發來的指令,通過WriteFile()寫入管道傳遞給CMD程序。
測試效果
hacker與buffer之間,不要直接用telnet,只能一次傳送一個字符。要通過netcat.exe發送數據:
先在被控端主機上運行,888端口已經監聽:
在另外一臺主機上使用nc連接:
連接成功后輸入dir,發現目錄已經發現改變,從D:\hacker變成了D:\受害者,列出的文件也是受害者主機上的,說明我們已經能夠成功在受害者的CMD程序執行命令了。
總結
總的來說,這次實驗用到了管道和socket等技術,重點在于處理好整個邏輯過程,這些Windows的API相對都不難。