InjectCode for Win9x..
文章作者:Anskya
原文出处:看雪论坛
转载请保留版权~谢谢
现在注入方式很多,不过无外复三种:
1.使用映射代码然后创建远程线程
2.利用消息钩子插入DLL两种
3.使用调试API.GetThreadContext,SetThreadContext来改变线程的环境启动代码
4.不过基本上Win9x下差不多都是使用消息钩子挂钩模式
当然EliCZ叔叔发布的~EliRT可以让我们在Win9x下也可以使用
CreateRemoteThread注入函数...这里偶简单的说一下另外一种注入方式
利用系统内部函数进行创建远程线程.
这里我就不多说一大堆理论了~相关文献请参见EliCZ叔叔的文章...
当然这里使用的注入方式~他的文章中并没有提及...
1.原理
[1]定位目标
既然是夸进程的创建进程,首先我们怀疑的就是调试API
他们是如何作到调试远程进程的,比如DebugActiveProcess,
他是如何挂起目标进程的...所以对目标进程进行逆向分析..
(关于次问题请到...exetools里面查看相关文章吧...里面有讨论过)
(一下代码是反汇编DebugActiveProcess函数的...这里贴的是关键部分分析)
其实就在DebugActiveProcess下面几行的位置处...自己分析一下就知道了
; IDA output:
;.text:BFF9490D push 8 ; const
;.text:BFF9490F push edi
;.text:BFF94910 push offset sub_BFF9494D ; thread
;.text:BFF94915 push 0FFFFF000h ; tells kernel to allocate stack
;.text:BFF9491A push edi ; pdb
;.text:BFF9491B call CreateRemoteThread9x; arbitrary name
;0xE8 = call; 0x85 = push edi; 0xFFFF = higher part of 0xFFFFF000
特征码:0E857FFFFh(看不懂吗?自己反一下这个函数就知道了...16进制码...请问IDA这里怎么用???为显示不出...)
至少跟踪发现这个函数不是WIndows导出的函数所以我们不能直接调用这个函数
(至少无法通过GetProcAddress函数搜索出地址来...但是我们完全可以定位函数地址和传入参数...分析代码看下面的文章)
2.定位
知道原理了..开始逆向分析...这里分析的目标是国外的一款非常恐怖的"Trojan"程序
Spirit(反向连接+远程注入代码,上传DLL或者EXE并运行之...体积:1.55k,
还有注册表添加,自删除等功能...支持Win9x下进程插入--一开始就对他很好奇^_^)
关键函数逆向分析部分:OD反出来的...
00400158 68 40000000 push 40
0040015D 68 00300008 push 8003000
00400162 68 D5050000 push 5D5
00400167 57 push edi
00400168 FF15 42144000 call [401442] ; kernel32.VirtualAlloc
0040016E 68 08000000 push 8
00400173 57 push edi
00400174 50 push eax
00400175 57 push edi
00400176 68 D1040000 push 4D1
0040017B 8D15 0E114000 lea edx, [40110E] ;这个地址是需要插入的代码内存地址
00400181 52 push edx
00400182 50 push eax
00400183 56 push esi
00400184 FF15 32144000 call [401432] ; kernel32.WriteProcessMemory
0040018A FF15 3E144000 call [40143E] ; kernel32.GetCurrentProcessId
00400190 64:3305 3000000>xor eax, fs:[30]
00400197 31C3 xor ebx, eax
00400199 8B35 3A144000 mov esi, [40143A] ;kernel32.DebugActiveProcess
0040019F 46 inc esi
004001A0 813E FFFF57E8 cmp dword ptr [esi], E857FFFF ;比较是否是CreateRemoteThread9x内存特征
004001A6 ^ 75 F7 jnz short 0040019F ;不等继续跳转
004001A8 AD lods dword ptr [esi] ;搜索到以后开始获取地址(扫描两次)
004001A9 AD lods dword ptr [esi]
004001AA 01F0 add eax, esi
004001AC 68 00F0FFFF push -1000
004001B1 53 push ebx
004001B2 FFD0 call eax
004001B4 57 push edi
004001B5 50 push eax
004001B6 8B35 2A144000 mov esi, [40142A] ; kernel32.OpenProcess
004001BC 46 inc esi
004001BD 813E 50FF32E8 cmp dword ptr [esi], E832FF50
004001C3 ^ 75 F7 jnz short 004001BC
004001C5 AD lods dword ptr [esi]
004001C6 AD lods dword ptr [esi]
004001C7 01F0 add eax, esi
004001C9 53 push ebx
004001CA FFD0 call eax ;调用此函数
004001CC 61 popad
004001CD C3 retn
3.实现
不用说了吧~上面的代码逆向写一下就OK了...
既然注入代码我们就作全套...
[1]申请远程进程空间(C代码实现)
WinNT下我就不多说了~反正大家都知道的
关键说说Win9x
逆向分析一下中国黑客病毒
(CreateKernelThread创建线程...和
MoveDataToKnl函数(WHG自己写的具体看ChineseHacker代码))
不过他好像不能让我们将代码注入到别的进程内部...
好了Google搜了一下文章...发现Win9x内核下0x8000000以上空间都是透明的?
Why?你最好别问我,我也不知道..我很菜...
所以以上反汇编出来的代码是
00400158 68 40000000 push 40
0040015D 68 00300008 push 8003000
00400162 68 D5050000 push 5D5
00400167 57 push edi
00400168 FF15 42144000 call [401442] ; kernel32.VirtualAlloc
啊~好了...写一下具体代码好了
LPVOID My_VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD
flProtect)
{
if (GetVersion() > 0x80000000)
{
return VirtualAlloc(lpAddress, dwSize, 0x8000000 + MEM_COMMIT, PAGE_EXECUTE_READWRITE);
}else
{
return VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect);
}
}
BOOL My_VirtualFreeEx(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType)
{
if (GetVersion() > 0x80000000)
{
return VirtualFree(lpAddress, dwSize, MEM_RELEASE);
}else
{
return VirtualFreeEx(hProcess, lpAddress, dwSize, dwFreeType);
}
}
需要注意的是~在Win9x下申请空间和释放空间以前需要~~OpenProcess
一下....在Win9x下申请空间还有一种方法:SharedMemoryAlloc函数
直接的Windows头部里面好像没有...大家可以从ComCtl32.dll里面导出...
这个函数使用非常简单..就一个参数.申请空间长度...
创建远程线程代码在附件内....(把上面的OD反汇编代码写一遍就OK了~有必要吗???)
具体示例代码看:附件~注入代码到记事本....支持Win9x下注入
参考文献:
[1]EliCZ 的EliRT代码,主页.看雪上有友情连接
[2]y0da 的Invisibility代码,主页.看雪上有友情连接
文章作者:Anskya
原文出处:看雪论坛
转载请保留版权~谢谢
终于可以上传了~
;======================================================
;远程线程注入对话框演示 Ex By Anskya
;支持Win9x下代码注入..
;Email:Anskya@Gmail.com
;======================================================
.586
.model flat
locals @@
include \D.N.ASM\include\useful.inc
include \D.N.ASM\include\MZ.INC
include \D.N.ASM\include\PE.INC
.data
notepad db 'Notepad',0
injected:
;int 3
pushad
call @@delta
@@delta:
pop ebp
sub ebp,offset @@delta
push 0
lea eax,[ebp+offset cap]
push eax
lea eax,[ebp+offset msg]
push eax
push 0
call [ebp+__MessageBoxA]
@@Exit:
push 0
call [ebp+__ExitThread]
;_invoke [ebp+__ExitThread],0
popad
ret
;------------------使用数据----------------------------------
msg db "[*] Hello World Coder! (C) Anskya.",0dh,0ah,0
cap db "MsgBox By Anskya",0
k32_api:
db 'kernel32',0
__ExitThread dd 0058F9201h
__WinExec dd 028452C4Fh
__OpenProcess dd 033D350C4h
__WriteProcessMemory dd 00E9BBAD5h
dd 0
u32_api:
db 'user32',0
__MessageBoxA dd 0D8556CF7h
__FindWindowA dd 085AB3323h
__GetWindowThreadProcessId dd 07B46AF5Eh
dd 0
injected_size equ $-injected
.code
public c entry
entry:
;-------获取相关API函数
lea eax,k32_api
push eax
call get_apicrc
lea eax,u32_api
push eax
call get_apicrc
;-------获取完毕-------执行主函数部分
;call injected
push 5
push offset notepad
call __WinExec
push 0
push offset notepad
call __FindWindowA ;获取窗口句柄
push eax
push esp
push eax
call __GetWindowThreadProcessId
pop eax
mov ebx,eax
push eax
push 0
push 1f0fffh ;PROCESS_ALL_ACCESS
call __OpenProcess
mov ebp,eax
push 40h ;PAGE_EXECUTE_READWRITE
push 3000h ;MEM_COMMIT or MEM_RESERVE
push injected_size
push 0
push ebp ;pid
call RT32_VirtualAllocEx
mov edi,eax
push eax
push esp
push injected_size
lea eax,injected
push eax
push edi
push ebp
call __WriteProcessMemory
pop eax
push eax
push esp
push 0
push esi
push edi
push 0
push 0
push ebx
call RT32_CreateRemoteThread
pop ecx
ExitProc:
push 0
callw ExitProcess
ret
;-------使用函数地址
RT32_VirtualAllocEx:
pushad
mov ebx,[esp+8*4+4]
mov ebp,[esp+8*4+8]
mov edx,[esp+8*4+12]
mov esi,[esp+8*4+16]
mov edi,[esp+8*4+20]
call get_k32base
mov ecx,cs
xor cl,cl
jecxz @@os_nt
@@os_9x:
push edi
or esi,8000000h
push esi
push edx
push ebp
push 04402890Eh ;VirtualAlloc
push eax
call get_addr32crc
call eax
jmp @@finished
@@os_nt:
push 0DA89FC22h ;VirtualAllocEx
push eax
call get_addr32crc
push edi
push esi
push edx
push ebp
push ebx
call eax
@@finished:
mov [esp+pushad_eax],eax
popad
ret 4*5
RT32_CreateRemoteThread:
pushad
mov ebp,[esp+8*4+4]
call get_k32base
mov esi,eax
push ebp
push 0
push 1f0fffh ;PROCESS_ALL_ACCESS
push 033D350C4h ;OpenProcess
push esi
call get_addr32crc
call eax
mov ebx,eax
push 0CF4A7F65h ;CreateRemoteThread
push esi
call get_addr32crc
mov ecx,cs
xor cl,cl
jecxz @@os_nt
@@os_9x:
call get_obfs
xor ebp,eax
call search_crt9x
jnc @@error
mov esi,eax
mov edi,[esp+8*4+16]
mov eax,[esp+8*4+20]
push 8
push eax
push edi
push 0fffff000h
push ebp
call esi
push eax
call search_halloc9x
jnc @@error
mov edx,eax
pop eax
push 0
push eax
push ebp
call edx
jmp @@finished
@@os_nt:
; push dwo [esp+8*4+28+ 0]
; push dwo [esp+8*4+24+ 4]
; push dwo [esp+8*4+20+ 8]
; push dwo [esp+8*4+16+12]
; push dwo [esp+8*4+12+16]
; push dwo [esp+8*4+8 +20]
push 6
pop ecx
@@loop_push:
push dwo [esp+8*4+28]
loop @@loop_push
push ebx
call eax
@@finished:
mov [esp+pushad_eax],eax
popad
ret 4*7
@@error:
sub eax,eax
dec eax
mov [esp+pushad_eax],eax
popad
ret 4*7
get_obfs:
pushad
push 0EB1CE85Ch ;GetCurrentProcessId
call get_k32base
push eax
call get_addr32crc
call eax
mov ebx,eax
mov eax,fs:[30h]
xor eax,ebx
mov [esp+pushad_eax],eax
popad
retn
search_halloc9x:
pushad
call get_k32base
push 033D350C4h ;OpenProcess
push eax
call get_addr32crc
mov esi,eax
mov eax,0E832ff50h
jmp search_compare
search_crt9x:
pushad
call get_k32base
push 07FC598E3h ;DebugActiveProcess
push eax
call get_addr32crc
mov esi,eax
; IDA output:
;.text:BFF9490D push 8 ; const
;.text:BFF9490F push edi
;.text:BFF94910 push offset sub_BFF9494D ; thread
;.text:BFF94915 push 0FFFFF000h ; tells kernel to allocate stack
;.text:BFF9491A push edi ; pdb
;.text:BFF9491B call CreateRemoteThread9x; arbitrary name
;0xE8 = call; 0x85 = push edi; 0xFFFF = higher part of 0xFFFFF000
; mov eax,0fffff000h
mov eax,0E857FFFFh
; DEBUG: CloseHandle
; mov eax,0E8560002h
search_compare:
sub ecx,ecx
mov cl,255 ;approx. size of DebugActiveProcess, just in case
@@compare:
cmp eax,[esi]
jz @@save
inc esi
dec ecx
jecxz @@exit
jmp @@compare
@@save:
lodsd
lodsd ;eax = relative address of CreateRemoteThread9x()
add eax,esi ;absolute address
mov [esp+pushad_eax],eax
stc
@@exit:
popad
retn
;--------The End~~~[^_^]
get_apicrc:
pushad
mov esi,[esp+8*4+4]
call get_k32base
push 04134D1ADh ;LoadLibraryA
push eax
call get_addr32crc
push esi
call eax
mov ebx,eax
sub eax,eax
lodsb
test al,al
jnz $-3
mov edi,esi
@@loop:
lodsd
test eax,eax
jz @@end
push eax
push ebx
call get_addr32crc
stosd
jmp @@loop
@@end:
popad
retn 4
;void* get_addr32crc(DWORD base, DWORD crc32)
get_addr32crc:
pushad
mov ebx,[esp+8*4+4]
mov esi,[esp+8*4+8]
sub ebp,ebp ;counter
mov edx,ebx
add edx,[edx.mz_neptr]
mov edx,[edx.pe_exportrva]
add edx,ebx
mov eax,[edx.ex_numofnamepointers]
mov edi,[edx.ex_addresstablerva]
add edi,ebx
mov edi,[edx.ex_namepointersrva]
add edi,ebx
push edx
mov edx,edi
@@next:
mov edx,[edi]
add edx,ebx
inc ebp
pushad
mov esi,edx
sub ecx,ecx
lodsb
inc ecx
test al,al
jnz $-4
mov [esp+pushad_ecx],ecx
popad
@@cmpstr:
pushad
; mov edx,edx
sub eax,eax
call xcrc32
cmp eax,esi
popad
jz @@found
; push eax
; sub eax,eax
; scasb
; jnz $-1
; pop eax
add edi,4
dec eax
jz @@error
jmp @@next
@@found:
pop edx
dec ebp
mov ecx,[edx.ex_ordinaltablerva]
add ecx,ebx
movzx eax,wo [ecx+ebp*2]
mov ebp,[edx.ex_addresstablerva]
add ebp,ebx
mov eax,[ebp+eax*4]
add eax,ebx
@@error:
mov [esp+pushad_eax],eax
popad
ret 4*2
;void* get_k32base();
get_k32base:
pushad
sub eax,eax
mov eax,fs:[eax+30h]
test eax,eax
js @@os_9x
@@os_nt:
mov eax,[eax+0ch]
mov esi,[eax+1ch]
lodsd
mov eax,[eax+8]
jmp @@finished
@@os_9x:
mov eax,[eax+34h]
lea eax,[eax+7ch]
mov eax,[eax+3ch]
@@finished:
mov [esp+pushad_eax],eax
popad
retn
; zhengxi's crc32(): optimised by Vecna
; input: EDX=data, ECX=size, EAX=crc
; output: EAX=crc, EDX+=ECX, ECX=BL=0
xcrc32:
pushad
jecxz @@4
not eax
@@1:
xor al, [edx]
inc edx
mov bl, 8
@@2:
shr eax, 1
jnc @@3
xor eax, 0EDB88320h
@@3:
dec bl
jnz @@2
loop @@1
not eax
@@4:
mov [esp+pushad_eax],eax
popad
ret
end
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。