gh0st原始碼分析與遠控的編寫(三)
好久不見。距離上次寫gh0st來有好久了,一是期末考試,忙不開,二是後來電腦壞了,幾天沒能上網。
昨天總算是把電腦修好了,雖說沒到一切重頭開始的地步,但是也重灌各種東西花了很久。閒下來的時間,我就來繼續分析gh0st的原始碼吧。
上次我們把gh0st的上線給研究了一下,跟著老狼的視訊,繼續我們的步伐。開始實現gh0st中具體的功能。最簡單的一個是“終端管理”,就是一個cmdshell。
什麼是cmdshell,相當於是一個cmd命令列的後門,我在主控端中寫下cmd命令,然後傳給被控端,被控端執行後將結果再發給主控端。
這是整個遠控中比較簡單的部分,我們從被控端開始看起:(原始碼在附件中可以下載)
在MainDll工程中,開啟類檢視,找到CShellManager這個類,這就是我們“終端管理”功能用到的類。
在看程式碼之前,我先說一下cmdshell的原理。為什麼我們這個程式能執行cmd命令並且把執行結果得到並返回。這裡用到管道技術,管道是為了程序間通訊而存在的,如下圖:
我們在gh0st程序中,開啟一個cmd程序,並使用管道,向cmd.exe傳送資訊,而cmd.exe也利用管道將資訊傳送給gh0st的程序。管道通訊又分三種,雙管道、單管道與無管道。gh0st裡面用的雙管道後門,也就是說,我們在gh0st.exe和cmd.exe之間建立了兩根傳輸資料的管道,原因可想而知:a管道接受gh0st的命令,併發送給cmd,b管道接受cmd的執行結果,併發送給gh0st。
理解了這個就方便了。首先看到它的建構函式:
01 |
if (!CreatePipe(&m_hReadPipeShell, &m_hWritePipeDll, &sa, 0)) //該管道為程式寫,cmd讀 |
02 |
{ |
03 |
CloseHandle(m_hReadPipeShell); |
04 |
CloseHandle(m_hWritePipeDll); |
05 |
return ; |
06 |
} |
07 |
08 |
if (!CreatePipe(&m_hReadPipeDll, &m_hWritePipeShell, &sa, 0)) //該管道為cmd寫,程式讀 |
09 |
{ |
10 |
CloseHandle(m_hReadPipeDll); |
11 |
CloseHandle(m_hWritePipeShell); |
12 |
} |
建立了兩根管道,使用的API就是CreatePipe,m_hReadPipeShell其實就是一個控制代碼。CreatePipe這個API前兩個引數是該管道的讀控制代碼和寫控制代碼。讀控制代碼就是該管道的入口,寫控制代碼就是該管道的出口。管道這個名字很恰當,就像一根管子,資料從一個方向流入,從另一個方向流出。
sa是安全屬性的一個結構,沒有太大作用,初始化一下傳入地址進去就行了。
再往下看,