由於svchost已經使用了StartServiceCtrlDispatcher來服務調度函數,因此我們在實現DLL實現時就不用了,這主要是因為一個行程只能使用一次StartServiceCtrlDispatcher API。但是需要用 RegisterServiceCtrlHandler 來註冊回應控制請求的函數。最後我們的DLL接收的都是unicode字元串。
由於這種服務啟動後由svchost載入,不增加新的行程,只是svchost的一個DLL,而且一般進行審計時都不會去HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost 檢查服務組是否變化,就算去檢查,也不一定能發現異常,因此如果增加一個這樣的DLL後門,偽裝的好,是比較隱蔽的。
4. 安裝服務與設定
要通過svchost使用來啟動的服務,就一定要在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost下有該服務名,這可以通過如下方式來實現:
1) 增加一個新的服務組,在組裡增加服務名
2) 在現有組裡增加服務名
3) 直接使用現有服務組裡的一個服務名,但本地機沒有安裝的服務
4) 修改現有服務組裡的現有服務,把它的ServiceDll指向自己
其中前兩種可以被正常服務使用,如使用第1種方式,啟動其服務要新增新的svchost行程;第2種方式如果該群組服務已經執行,安裝後不能立刻啟動服務,因為svchost啟動後已經把該群組訊息儲存在記憶體裡,並使用API StartServiceCtrlDispatcher() 為該群組所有服務註冊了調度處理函數,新增加的服務不能再註冊調度處理函數,需要重新啟動電腦或者該群組的svchost行程。而後兩種可能被後門使用,尤其是最後一種,沒有增加服務,只是改了註冊表裡一項設定,從服務管理控制台又看不出來,如果作為後門還是很隱蔽的。比如EventSystem服務,預設是指向es.dll,如果把ServiceDll改為EventSystem.dll就很難發現。
因此服務的安裝除了使用CreateService()新增服務之外,還需要設定服務的ServiceDll,如果使用前2種還要設定svchost的註冊表選項,在卸載時也最好移除增加的部分。
具體程式碼參見後邊的附例(使用的是方法3)。
註: ImagePath 和ServiceDll 是ExpandString不是普通字元串。因此如果使用.reg文件安裝時要注意。
5. DLL服務實現
DLL程序的編寫比較簡單,只要實現一個ServiceMain()函數和一個服務控制程序,在ServiceMain()函數里用RegisterServiceCtrlHandler()註冊服務控制程序,並設定服務的執行狀態就可以了。
另外,因為此種服務的安裝除了正常的CreateService()之外,還要進行其他設定,因此最好實現安裝和卸載函數。
為了方便安裝,實現的程式碼提供了InstallService()函數進行安裝,這個函數可以接收服務名作為參數(如果不提供參數,就使用預設的iprip),如果要安裝的服務不在svchost的netsvcs組裡安裝就會失敗;如果要安裝的服務已經存在,安裝也會失敗;安裝成功後程序會組態服務的ServiceDll為當前Dll。提供的UninstallService()函數,可以移除任何函數而沒有進行任何檢查。
為了方便使用rundll32.exe進行安裝,還提供了RundllInstallA()和RundllUninstallA()分別使用InstallService()及UninstallService()。因為rundll32.exe使用的函數原型是:
void CALLBACK FunctionName(
HWND hwnd,// handle to owner window
HINSTANCE hinst,// instance handle for the DLL
LPTSTR lpCmdLine, // string the DLL will parse
int nCmdShow// show state
);
對應的指令行是rundll32 DllName,FunctionName [Arguments]
DLL服務本身只是新增一個行程,該程序指令行就是啟動服務時提供的第一個參數,如果未指定就使用預設的svchostdll.exe。啟動服務時如果提供第二個參數,新增的行程就是和桌面交互的。
具體程式碼參見後邊的附例8,來源碼和DLL文件請到
http://www.binglesite.net下載。
//main service process function
void __stdcall ServiceMain( int argc, wchar_t* argv[] );
//report service stat to the service control manager
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress );
//service control handler, call back by service control manager
void __stdcall ServiceHandler( DWORD dwCommand );
//RealService just create a process
int RealService(char *cmd, int bInteract);
//Install this dll as a Service host by svchost.exe, service name is given by caller
int InstallService(char *name);
//unInstall a Service, be CARE FOR call this to delete a service
int UninstallService(char *name);
//Install this dll as a Service host by svchost.exe, used by RUNDLL32.EXE to call
void CALLBACK RundllInstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);
//unInstall a Service used by RUNDLL32.EXE to call, be CARE FOR call this to delete a service
void CALLBACK RundllUninstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);
//output the debug infor into log file(or stderr if a console program call me) & DbgPrint
void OutputString( char *lpFmt, ... );
6. 程式碼使用
C:\>tlist -s
0 System Process
8 System
240 services.exeSvcs:Browser,Dhcp,dmserver,Dnscache,Eventlog,lanmanserver,lanmanworkstation, LmHosts,PlugPlay,ProtectedStorage,TrkWks,Wmi
504 svchost.exe Svcs:RpcSs
1360 svchost.exe Svcs:EventSystem,Netman,RasMan,SENS,TapiSrv
C:\>rundll32 svchostdll.dll,RundllInstall abcd
SvcHostDLL: DllMain called DLL_PROCESS_ATTACH
you specify service name not in Svchost\netsvcs, must be one of following:
- EventSystem
- Ias
- Iprip
- Irmon
- Netman
- Nwsapagent
- Rasauto
- Rasman
- Remoteaccess
- SENS
- Sharedaccess
- Tapisrv
- Ntmssvc
- wzcsvc
C:\>rundll32 svchostdll.dll,RundllInstall IPRIP
SvcHostDLL: DllMain called DLL_PROCESS_ATTACH
CreateService(IPRIP) SUCCESS. Config it
Config service IPRIP ok.
C:\>sc start iprip "cmd /k whoami" 1
NT AUTHORITY\SYSTEM
SvcHostDLL: ServiceMain(3, IPRIP) called
SvcHostDLL: RealService called 'cmd /k whoami' Interact
SvcHostDLL: CreateProcess(cmd /k whoami) to 640
C:\>tlist -s
0 System Process
8 System
240 services.exeSvcs:Browser,Dhcp,dmserver,Dnscache,Eventlog,lanmanserver,lanmanworkstation, LmHosts,PlugPlay,ProtectedStorage,TrkWks,Wmi
504 svchost.exe Svcs:RpcSs
640 cmd.exe Title: C:\WINNT\System32\cmd.exe
1360 svchost.exe Svcs:EventSystem,Netman,RasMan,SENS,TapiSrv,IPRIP
C:\>net stop iprip
The IPRIP service was stopped successfully.
C:\>rundll32 svchostdll.dll,RundllUninstall iprip
DeleteService(IPRIP) SUCCESS.
7. 參考
Platform SDK: Tools - Rundll32
1) Inside Win32 Services, Part 2 by: Mark Russinovich, at:
http://www.winnetmag.com/Articles/In...leID=8943&pg=3
2) Platform SDK: Tools - Rundll32, at:
http://msdn.microsoft.com/library/en...s/rundll32.asp