如何把shellcode转换成exe文件分析

【转】http://www.freebuf.com/articles/web/152879.html


前言

在分析shellcode时,静态分析或者使用scdbg模拟分析都不够准确,如果转换成exe文件那么就可以用debugger或者IDA分析,会方便很多。

样本分析

这里以CVE-2013-3346
的样本为例,使用peepdf分析样本:

$ python peepdf.py -i -f ~/Downloads/sample.pdf                                                                                                                                                
File: sample.pdfMD5: 6776bda19a3a8ed4c2870c34279dbaa9SHA1: ad6a3564e125683a791ee98c5d1e66e1d9c6877dSize: 177511 bytesVersion: 1.1Binary: FalseLinearized: FalseEncrypted: FalseUpdates: 0Objects: 4Streams: 2Comments: 0Errors: 1Version 0:Catalog: 1Info: No

Objects (4): [1, 2, 3, 10]

Errors (1): [3]

Streams (2): [10, 3]

Encoded (0): []

Objects with JS code (1): [3]

Suspicious elements:

/AcroForm: [1]

/OpenAction: [1]

/XFA: [1]

/JS: [2]

/JavaScript: [2]

其中Objects with JS code (1): [3]可知对象3是一段js代码:

PPDF> object 3<< >>streamif(app.media.getPlayers().length >= 1) Q=~[];Q={___:++Q,$$$$:(![]+"")[Q],__$:++Q,$_$_:(![]+"")[Q],_$_:++Q,$_$$:({}+"")[Q],$$_$:(Q[Q]+"")[Q],_$$:++Q,$$$_:(!""+"")[Q],$__:++Q,$_$:++Q,$$__:({}+"")[Q],$$_:++Q,$$$:++Q,$___:++Q,$__$:++Q};Q.$_=(Q.$_=Q+"")[Q.$_$]+(Q._$=Q.$_[Q.__$])+(Q.$$=(Q.$+"")[Q.__$])+((!Q)+"")[Q._$$]+(Q.__=Q.$_[Q.$$_])+(Q.$=(!""+"")[Q.__$])+(Q._=(!""+"")[Q._$_])+Q.$_[Q.$_$]+Q.__+Q._$+Q.$;Q.$$=Q.$+(!""+"")[Q._$$]+Q.__+Q._+Q.$+Q.$$;Q.$=(Q.___)[Q.$_][Q.$_];Q.$(Q.$(Q.$$+"\""+"\\"+Q.__$+Q.$$_+Q.$$_+Q.$_$_+"\\"+Q.__$+Q.$$_+Q._$_+"\\"+Q.$__+Q.___+"\\"+Q.__$+Q.$$_+Q._$$+"\\"+Q.__$+Q.$_$+Q.___+Q.$$$_+(![]+"")[Q._$_]+(![]+"")[Q._$_]+Q.$$__+Q._$+Q.$$_$+Q.$$$_+"\\"+Q.$__+Q.___+"=\\"+Q.$__+Q.___+Q._+"\\"+Q.__$+Q.$_$+Q.$$_+Q.$$$_+"\\"+Q.__$+Q.$$_+Q._$$+Q.$$__+Q.$_$_+"\\"+Q.__$+Q.$$_+Q.___+Q.$$$_+"(\\\"%"+Q._+Q.___+Q.

...

这里要把从Q=~[]开始的加密代码拷贝到文件中。

这里的代码是用jjencode加密过的,使用peepdf自带的解密工具可以还原出js代码:

PPDF> js_jjdecode file /Users/seviezhou/Downloads/sample.js $> jsdecode

PPDF> js_analyse variable jsdecode $> shellcode

PPDF> show jsdecode

var shellcode = unescape("%u\00E8%u\0000%u\5D00%u\ED83%u\E905%u\008B%u\0000%u\5052%u\D231%u\C031%u\F980%u\7501%u\6604%u\EBAD%u\AC01%u\003C%u\0D74%u\613C%u\0272%u\202C%u\CAC1%u\010D%u\EBC2%u\39E3%u...

var executable = "";

var rop9 = "";

rop9 += unescape("%u\313d%u\4a82");

rop9 += unescape("%u\a713%u\4a82");

rop9 += unescape("%u\1f90%u\4a80");

...

...

PPDF> show shellcode

e8 00 00 00 00 5d 83 ed 05 e9 8b 00 00 00 52 50   |.....]........RP|

31 d2 31 c0 80 f9 01 75 04 66 ad eb 01 ac 3c 00   |1.1....u.f....<.|

74 0d 3c 61 72 02 2c 20 c1 ca 0d 01 c2 eb e3 39   |t.<ar., .......9|

da 58 5a c3 56 89 da b2 3c 31 c0 66 8b 02 01 d8   |.XZ.V...<1.f....|

8b 50 78 01 da 52 51 8b 4a 18 8b 42 20 01 d8 8b   |.Px..RQ.J..B ...|

38 01 df 53 8b 1e 87 f7 51 31 c9 e8 ae ff ff ff   |8..S....Q1......|

59 5b 87 f7 75 02 eb 08 83 c0 04 49 e3 22 eb df   |Y[..u......I."..|8b 42 18 29 c8 89 c1 8b 42 24 01 d8 66 8b 0c 48   |.B.)....B$..f..H|8b 42 1c 01 d8 c1 e1 02 01 c8 8b 00 01 d8 89 06   |.B..............|59 5a 83 c6 04 e2 ae 5e c3 31 d2 64 8b 52 30 8b   |YZ.....^.1.d.R0.|

...

js代码主要是shellcode的布置和堆喷射还有rop的构造,这里的shellcode利用CVE-2013-5065绕过了沙箱。将shellcode提取出来使用scdbg分析得到如下结果:

...401215  SetFilePointer(hFile=1a4, dist=0, 0, FILE_BEGIN) = 0401221  GetFileSize(1a4, 0) = ffffffff401215  SetFilePointer(hFile=1a8, dist=0, 0, FILE_BEGIN) = 0401221  GetFileSize(1a8, 0) = ffffffff401215  SetFilePointer(hFile=1ac, dist=0, 0, FILE_BEGIN) = 0401221  GetFileSize(1ac, 0) = ffffffff401215  SetFilePointer(hFile=1b0, dist=0, 0, FILE_BEGIN) = 0401221  GetFileSize(1b0, 0) = ffffffff401215  SetFilePointer(hFile=1b4, dist=0, 0, FILE_BEGIN) = 0401221  GetFileSize(1b4, 0) = ffffffff401221   83F8FF                          cmp eax,0xffffffff              step: 1647274  foffset: 221eax=ffffffff  ecx=0         edx=12fdbc    ebx=1b4

esp=12fdb0    ebp=2000      esi=12fdc8    edi=12fdb4     EFL 44 P Z

dbg> Disassemble address (default eip): (hex/reg) 0x401221401221Number of instructions to dump (max 100): (int/reg) 100100401221   83F8FF                          cmp eax,0xffffffff401224   74E3                            jz 0x401209   ^^401226   3D00100000                      cmp eax,0x100040122b   7CDC                            jl 0x401209   ^^40122d   89C5                            mov ebp,eax40122f   89E0                            mov eax,esp401231   31C9                            xor ecx,ecx401233   51                              push ecx401234   50                              push eax401235   6A04                            push byte 0x4401237   57                              push edi401238   53                              push ebx401239   FF5630                          call [esi+0x30]40123c   813F25504446                    cmp dword [edi],0x46445025401242   75C5                            jnz 0x401209   ^^401244   83C408                          add esp,0x8...

dbg> Set eip (VA or file offset) : (hex/reg) 0x401244401244401244   83C408                          add esp,0x8dbg>40125a  VirtualAlloc(base=0 , sz=1ffc) = 731000401265  ReadFile(hFile=1b4, buf=731000, numBytes=1ffc) = 04012b0  GetTempPathA(len=c8, buf=12fcfc) = 254012be  GetTempFileNameA(path=C:\Users\SEVIEZ~1\AppData\Local\Temp\, prefix=12fcf8, unique=0, buf=12f

cfc) = 429E

         Path = C:\Users\SEVIEZ~1\AppData\Local\Temp\429E.tmp4012e0  CreateFileA(C:\Users\SEVIEZ~1\AppData\Local\Temp\429E.tmp) = 8SafeMalloc Failed/refused to allocate 0x0 bytes exiting...

一开始分析就会陷入一个死循环,然后尝试改变eip得到了一些api的调用。

转换shellcode为exe

还是看不出什么,这里我们把shellcode转换成exe文件来分析,首先我尝试了shellcode2exe.py,可转换结果并不是一个合法的exe文件,这里讲一个通用的方法,这里要用到yasm.exegolink.exe,下载地址:

yasm-1.3.0-win64.exe

yasm-1.3.0-win32.exe

golink

下载对应位数的yasmgolink,分别重命名为yasm.exegolink.exe

然后用winhex等十六进制编辑器把shellcode保存为shellcode.bin:

$ hexdump shellcode.bin0000000 e8 00 00 00 00 5d 83 ed 05 e9 8b 00 00 00 52 500000010 31 d2 31 c0 80 f9 01 75 04 66 ad eb 01 ac 3c 000000020 74 0d 3c 61 72 02 2c 20 c1 ca 0d 01 c2 eb e3 390000030 da 58 5a c3 56 89 da b2 3c 31 c0 66 8b 02 01 d80000040 8b 50 78 01 da 52 51 8b 4a 18 8b 42 20 01 d8 8b

...

然后新建一个文件shellcode.asm,内容如下:

$ cat shellcode.asm

Global StartSECTION 'foo' write, execute,readStart:

incbin "shellcode.bin"

最后把yasm.exegolink.exeshellcode.asmshellcode.bin放在同一个目录下,以32位系统为例,依次执行如下命令:

yasm.exe -f win32 -o shellcode.obj shellcode.asmgolink /ni /entry Start shellcode.obj

最后可以得到shellcode.exe:

C:\Users\seviezhou\Desktop>yasm.exe -f win32 -o shellcode.obj shellcode.asmC:\Users\seviezhou\Desktop>golink /ni /entry Start shellcode.objC:\Users\seviezhou\Desktop>dir shellcode.exe

 驱动器 C 中的卷没有标签。

 卷的序列号是 0A63-F3E0
 C:\Users\seviezhou\Desktop 的目录2017/11/02  20:18             2,048 shellcode.exe               1 个文件          2,048 字节               0 个目录 49,720,483,840 可用字节

然后就可以放到debugger中调试:

00401000 > $ E8 00000000    CALL shellcod.00401005                   ; \shellcod.0040100500401005   $ 5D             POP EBP00401006   . 83ED 05        SUB EBP,500401009   . E9 8B000000    JMP shellcod.004010990040100E  /$ 52             PUSH EDX0040100F  |. 50             PUSH EAX00401010  |. 31D2           XOR EDX,EDX00401012  |> 31C0           /XOR EAX,EAX

可以看到入口点确实是shellcode的起始位置,单步跟随后可以在栈上找到程序使用的api:

0012FF54   7685214F  kernel32.ExitProcess0012FF58   76852FB6  kernel32.VirtualAlloc0012FF5C   7684A629  kernel32.DeviceIoControl0012FF60   7684CEE8  RETURN to kernel32.CreateFileA0012FF64   7684CAC4  kernel32.GetCurrentProcessId0012FF68   7685395C  kernel32.LoadLibraryA0012FF6C   7688E5FD  kernel32.WinExec0012FF70   76851400  kernel32.WriteFile0012FF74   7684CA7C  kernel32.CloseHandle0012FF78   76866A65  kernel32.GetTempPathA0012FF7C   7686695F  kernel32.GetTempFileNameA0012FF80   76840273  kernel32.GetFileSize0012FF84   768496FB  kernel32.ReadFile0012FF88   7684DB36  kernel32.SetFilePointer

然后就可以分析shellcode了,当然也可以放到IDA中分析。

也可以把上述两条命令写成shellcode2exe.bat文件:

@echo off

@if "%1"=="" goto help

@echo Global Start > shellcode.asm

@echo SECTION 'foo' write, execute,read >> shellcode.asm

@echo Start:       >> shellcode.asm

@echo incbin "%2"  >> shellcode.asm

@yasm.exe -f win%1 -o shellcode.obj shellcode.asm

@golink /ni /entry Start shellcode.obj

@dir shellcode.exe

@goto exit@:help

@echo Converts shellcode to exe

@echo Required Arguments:

@echo arg1 - architecture: 32 or 64 @echo arg2 - shellcode file name

@echo current dir is %cd%

@:exitecho.

运行结果:

C:\Users\seviezhou\Desktop>shellcode2exe.bat

Converts shellcode to exe

Required Arguments:

arg1 - architecture: 32 or 64arg2 - shellcode file name

current dir is C:\Users\seviezhou\DesktopC:\Users\seviezhou\Desktop>shellcode2exe.bat 32 shellcode.bin

 驱动器 C 中的卷没有标签。

 卷的序列号是 0A63-F3E0
 C:\Users\seviezhou\Desktop 的目录2017/11/02  20:26             2,048 shellcode.exe               1 个文件          2,048 字节               0 个目录 49,720,455,168 可用字节

成功得到exe文件。

总结

当分析shellcode时,可以结合多种方法分析,静态或者动态,才能更好的分析代码的行为,这时能够转换成可执行文件分析就是很好的方法。












本文转自fatshi51CTO博客,原文链接:http://blog.51cto.com/duallay/1979824 ,如需转载请自行联系原作者



上一篇:【Flutter】Flutter 拍照示例 ( Android 应用兼容 Android X | Gradle 版本号 | Gradle 插件版本号 | Android X 支持 | SDK 版本 )(二)


下一篇:FlutterBoost3.0发布preview版本