|
論壇說明 | 標記討論區已讀 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2003-12-21, 08:33 PM | #1 |
榮譽會員
|
SvcHost.exe的說明
Author: bingle
Email: bingle_at_email.com.cn Web: www.BingleSite.net 轉載請註明出處!! 1.多個服務共享一個 Svchost.exe行程利與弊 windows 系統服務分為獨立行程和共享行程兩種,在windows NT時只有伺服器管理器SCM(Services.exe)有多個共享服務,隨著系統內裝服務的增加,在windows 2000中ms又把很多服務做成共享方式,由svchost.exe啟動。windows 2000一般有2個svchost行程,一個是RPCSS(Remote Procedure Call)服務行程,另外一個則是由很多服務共享的一個svchost.exe。而在windows XP中,則一般有4個以上的svchost.exe服務行程,windows 2003 server中則更多,可以看出把更多的系統內裝服務以共享行程方式由svchost啟動是ms的一個趨勢。這樣做在一定程度上減少了系統資源的消耗,不過也帶來一定的不穩定因素,因為任何一個共享行程的服務因為錯誤退出行程就會導致整個行程中的所有服務都退出。另外就是有一點安全隱患,首先要介紹一下svchost.exe的實現機制。 2. Svchost原理 Svchost本身只是作為服務宿主,並不實現任何服務功能,需要Svchost啟動的服務以動態連接庫形式實現,在安裝這些服務時,把服務的可執行程序指向svchost,啟動這些服務時由svchost使用相應服務的動態連接庫來啟動服務。 那麼svchost如何知道某一服務是由哪個動態連接庫負責呢?這不是由服務的可執行程序路徑中的參數部分提供的,而是服務在註冊表中的參數設定的,註冊表中服務下邊有一個Parameters子鍵其中的ServiceDll表明該服務由哪個動態連接庫負責。並且所有這些服務動態連接庫都必須要匯出一個ServiceMain()函數,用來處理服務工作。 例如rpcss(Remote Procedure Call)在註冊表中的位置是 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcSs,它的參數子鍵Parameters裡有這樣一項: "ServiceDll"=REG_EXPAND_SZ:"%SystemRoot%\system32\rpcss.dll" 當啟動rpcss服務時,svchost就會使用rpcss.dll,並且執行其ServiceMain()函數執行具體服務。 既然這些服務是使用共享行程方式由svchost啟動的,為什麼系統中會有多個svchost行程呢?ms把這些服務分為幾組,同組服務共享一個svchost行程,不同組服務使用多個svchost行程,組的區別是由服務的可執行程序後邊的參數決定的。 例如rpcss在註冊表中 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcSs 有這樣一項: "ImagePath"=REG_EXPAND_SZ:"%SystemRoot%\system32\svchost -k rpcss" 因此rpcss就屬於rpcss組,這在服務管理控制台也可以看到。 svchost的所有組和組內的所有服務都在註冊表的如下位置: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost,例如windows 2000共有4組rpcss、netsvcs、wugroup、BITSgroup,其中最多的就是netsvcs=REG_MULTI_SZ:EventSystem.Ias.Iprip.Irmon.Netman.Nwsapagent.Rasauto.Rasman.Remoteaccess.SENS.Sharedaccess.Tapisrv.Ntmssvc.wzcsvc.. 在啟動一個svchost.exe負責的服務時,服務管理器如果遇到可執行程序內容ImagePath已經存在於服務管理器的映像庫中,就不在啟動第2個行程svchost,而是直接啟動服務。這樣就實現了多個服務共享一個svchost行程。 3. Svchost程式碼 現在我們基本清楚svchost的原理了,但是要自己寫一個DLL形式的服務,由svchost來啟動,僅有上邊的信息還有些問題不是很清楚。比如我們在匯出的ServiceMain()函數中接收的參數是ANSI還是Unicode?我們是否需要使用RegisterServiceCtrlHandler和StartServiceCtrlDispatcher來註冊服務控制及調度函數? 這些問題要通過檢視svchost程式碼獲得。下邊的程式碼是windows 2000+ service pack 4 的svchost反彙編片段,可以看出svchost程序還是很簡單的。 主函數首先使用ProcCommandLine()對指令行進行分析,獲得要啟動的服務組,然後使用SvcHostOptions()查詢該服務組的選項和服務組的所有服務,並使用一個資料結構 svcTable 來儲存這些服務及其服務的DLL,然後使用PrepareSvcTable() 函數新增SERVICE_TABLE_ENTRY 結構,把所有處理函數SERVICE_MAIN_FUNCTION 指向自己的一個函數FuncServiceMain(),最後使用API StartServiceCtrlDispatcher() 註冊這些服務的調度函數。 ; =============================== Main Funcion =========================================== .text:010010B8 public start .text:010010B8 start proc near .text:010010B8 push esi .text:010010B9 push edi .text:010010BA push offset sub_1001EBA ; lpTopLevelExceptionFilter .text:010010BF xor edi, edi .text:010010C1 call ds:SetUnhandledExceptionFilter .text:010010C7 push 1 ; uMode .text:010010C9 call ds:SetErrorMode .text:010010CF call ds:GetProcessHeap .text:010010D5 push eax .text:010010D6 call sub_1001142 .text:010010DB mov eax, offset dword_1003018 .text:010010E0 push offset unk_1003000 ; lpCriticalSection .text:010010E5 mov dword_100301C, eax .text:010010EA mov dword_1003018, eax .text:010010EF call ds:InitializeCriticalSection .text:010010F5 call ds:GetCommandLineW .text:010010FB push eax ; lpString .text:010010FC call ProcCommandLine .text:01001101 mov esi, eax .text:01001103 test esi, esi .text:01001105 jz short lab_doservice .text:01001107 push esi .text:01001108 call SvcHostOptions .text:0100110D call PrepareSvcTable .text:01001112 mov edi, eax ; SERVICE_TABLE_ENTRY returned .text:01001114 test edi, edi .text:01001116 jz short loc_1001128 .text:01001118 mov eax, [esi+10h] .text:0100111B test eax, eax .text:0100111D jz short loc_1001128 .text:0100111F push dword ptr [esi+14h] ; dwCapabilities .text:01001122 push eax ; int .text:01001123 call InitializeSecurity .text:01001128 .text:01001128 loc_1001128: ; CODE XREF: start+5Ej .text:01001128 ; start+65j .text:01001128 push esi ; lpMem .text:01001129 call HeapFreeMem .text:0100112E .text:0100112E lab_doservice: ; CODE XREF: start+4Dj .text:0100112E test edi, edi .text:01001130 jz ExitProgram .text:01001136 push edi ; lpServiceStartTable .text:01001137 call ds:StartServiceCtrlDispatcherW .text:0100113D jmp ExitProgram .text:0100113D start endp ; =============================== Main Funcion end =========================================== 由於svchost為該組的所有服務都註冊了svchost中的一個處理函數,因此每次啟動任何一個服務時,服務管理器SCM都會使用FuncServiceMain() 這個函數。這個函數使用 svcTable 查詢要啟動的服務使用的DLL,使用DLL匯出的ServiceMain()函數來啟動服務,然後返回。 ; ============================== FuncServiceMain() =========================================== .text:01001504 FuncServiceMain proc near ; DATA XREF: PrepareSvcTable+44o .text:01001504 .text:01001504 arg_0 = dword ptr 8 .text:01001504 arg_4 = dword ptr 0Ch .text:01001504 .text:01001504 push ecx .text:01001505 mov eax, [esp+arg_4] .text:01001509 push ebx .text:0100150A push ebp .text:0100150B push esi .text:0100150C mov ebx, offset unk_1003000 .text:01001511 push edi .text:01001512 mov edi, [eax] .text:01001514 push ebx .text:01001515 xor ebp, ebp .text:01001517 call ds:EnterCriticalSection .text:0100151D xor esi, esi .text:0100151F cmp dwGroupSize, esi .text:01001525 jbe short loc_1001566 .text:01001527 and [esp+10h], esi .text:0100152B .text:0100152B loc_100152B: ; CODE XREF: FuncServiceMain+4Aj .text:0100152B mov eax, svcTable .text:01001530 mov ecx, [esp+10h] .text:01001534 push dword ptr [eax+ecx] .text:01001537 push edi .text:01001538 call ds:lstrcmpiW .text:0100153E test eax, eax .text:01001540 jz short StartThis .text:01001542 add dword ptr [esp+10h], 0Ch .text:01001547 inc esi .text:01001548 cmp esi, dwGroupSize .text:0100154E jb short loc_100152B .text:01001550 jmp short loc_1001566 .text:01001552 ; ================================================= .text:01001552 .text:01001552 StartThis: ; CODE XREF: FuncServiceMain+3Cj .text:01001552 mov ecx, svcTable .text:01001558 lea eax, [esi+esi*2] .text:0100155B lea eax, [ecx+eax*4] .text:0100155E push eax .text:0100155F call GetDLLServiceMain .text:01001564 mov ebp, eax ; dll ServiceMain Function address .text:01001566 .text:01001566 loc_1001566: ; CODE XREF: FuncServiceMain+21j .text:01001566 ; FuncServiceMain+4Cj .text:01001566 push ebx .text:01001567 call ds:LeaveCriticalSection .text:0100156D test ebp, ebp .text:0100156F jz short loc_100157B .text:01001571 push [esp+10h+arg_4] .text:01001575 push [esp+14h+arg_0] .text:01001579 call ebp .text:0100157B .text:0100157B loc_100157B: ; CODE XREF: FuncServiceMain+6Bj .text:0100157B pop edi .text:0100157C pop esi .text:0100157D pop ebp .text:0100157E pop ebx .text:0100157F pop ecx .text:01001580 retn 8 .text:01001580 FuncServiceMain endp ; sp = -8 ; ============================== FuncServiceMain() end ======================================== 由於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下載。 程式碼略 =========================== 這個行程特別變態∼ 不信你們把所有的svchost.exe的行程都結束,就會 影響到RPC 我也碰到過,呵呵, Q: 不信你去試試 在衝擊波爆發前我就體驗過了 我發現xp下有很多 SVChost.exe的行程 以為有了病毒 因為2k只有2個 殺了半天 也沒找到 最後一想結束他不就好了 開始殺行程 殺到倒數第二個 就出60秒關機了 由於殺掉了svchost.exe使得RPC不能正常工作 就這樣 不信的自己去試試∼ A: 自動關機是機器服務策略設置原因,把RPC策略由重新啟動改為不操作一切OK。 Q: PS:如果看到一個行程叫SCVHOST的,一定要殺毒,那是個病毒,目的就是為了蒙蔽用戶,混淆視聽。 A: "安哥"(Hack.Agobot3)病毒分析報告 病毒名稱: Hack.Agobot3.aw 中文名稱: 安哥 威脅級別:3A 病毒別名:「高波變種3T」(Worm.Agobot.3.t) [瑞星] Backdoor.Agobot.03.aw [AVP] 病毒類型::黑客、蠕蟲 受影響系統:WinNT/Win2K/WinXP/Win2003 該病毒兼具黑客和蠕蟲的功能,利用IRC軟體開啟後門,等待黑客控制。使用RPC漏洞和WebDAV漏洞進行高速傳播。猜測弱密碼重點攻擊局域網,造成局域網癱瘓。 金山毒霸已於11月27日進行了應急處理,並在當天昇級了病毒庫。昇級到11月27日的病毒庫可完全處理該病毒及其變種。 技術細節 1、利用利用RPC DCOM漏洞和WebDAV漏洞在網路中高速傳播; 2、使用內部包含的超大型「密碼表」猜密碼的方式攻擊局域網中的電腦,感染整個局域網,造成網路癱瘓; 3、系統修改: A.將自身複製為%System%\scvhost.exe. B.在註冊表的主鍵: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run 中新增如下鍵值: "servicehost"="Scvhost.exe" C.在註冊表的主鍵: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicces 中新增如下鍵值:"servicehost"="Scvhost.exe" 4、中止許多知名反病毒軟體和網路安全軟體; 5、利用IRC軟體開啟後門; 6、試圖偷取被感染電腦內的正版軟體序列號等重要訊息; 7、該病毒可造成電腦不穩定,出現電腦執行速度和網路傳輸速度極劇下降,複製、貼上等系統功能不可用,OFFICE和IE瀏覽器軟體異常等現象。 解決方案 A、昇級金山毒霸病毒庫到11月27日的版本或下載「安哥」專殺工具,可完全處理該病毒;請到此鏈接下載專殺工具 http://www.duba.net/download/3/100.shtml B、為系統打上MS03-026 RPC DCOM漏洞修正檔(823980) 和MS03-007 WebDAV漏洞修正檔(815021),並為系統管理員帳號設置一個更為強壯的密碼。 MS03-026 RPC DCOM漏洞修正檔(823980)下載地址: http://support.microsoft.com/default.aspx?kbid=823980 MS03-007 WebDAV漏洞修正檔(815021)下載地址: http://support.microsoft.com/default.aspx?kbid=815021 C、手工清除 開啟行程管理器,找到名為"scvhost.exe"的行程,並將其結束;在註冊表中項:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run下刪除如下鍵值:"servicehost"="Scvhost.exe" 在註冊表中的項: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices 下刪除如下鍵值:"servicehost"="Scvhost.exe"刪除以下檔案:%System%\scvhost.exe |
送花文章: 3,
|