-
-
[原创]Bt5下payload默认加密方式初探
-
发表于: 2012-7-12 16:54 6782
-
Bt5下payload默认加密方式初探
下了个BT5,更新了半天metasploit竟然没成功,看着过期了几百天很是郁闷。算了给它彻底换掉,于是卸载了重装了一个。给几张截图:
现在心情好多了,来看一下它的payload都是怎么加密的吧!先准备一个shellcode.dat。
我们打开BT5, 把 shellcode.dat复制到桌面上(必须先安装vmware tools), 执行如下图的指令:
主要就是这几条
root@bt:/opt/metasploit-4.3.0/msf3# ./msfencode -h
Usage: ./msfencode <options>
OPTIONS:
-a <opt> The architecture to encode as
-b <opt> The list of characters to avoid: '\x00\xff'
-c <opt> The number of times to encode the data
-d <opt> Specify the directory in which to look for EXE templates
-e <opt> The encoder to use
-h Help banner
-i <opt> Encode the contents of the supplied file path
-k Keep template working; run payload in new thread (use with -x)
-l List available encoders
-m <opt> Specifies an additional module search path
-n Dump encoder information
-o <opt> The output file
-p <opt> The platform to encode for
-s <opt> The maximum size of the encoded data
-t <opt> The output format: raw,ruby,rb,perl,pl,bash,sh,c,js_be,js_le,java,dll,exe,exe-
small,elf,macho,vba,vba-exe,vbs,loop-vbs,asp,aspx,war
-v Increase verbosity
-x <opt> Specify an alternate executable template
root@bt:/opt/metasploit-4.3.0/msf3# ./msfencode -l -a x86
Framework Encoders (architectures: x86)
=======================================
Name Rank Description
---- ---- -----------
generic/none normal The "none" Encoder
x86/alpha_mixed low Alpha2 Alphanumeric Mixedcase Encoder
x86/alpha_upper low Alpha2 Alphanumeric Uppercase Encoder
x86/avoid_utf8_tolower manual Avoid UTF8/tolower
x86/call4_dword_xor normal Call+4 Dword XOR Encoder
x86/context_cpuid manual CPUID-based Context Keyed Payload Encoder
x86/context_stat manual stat(2)-based Context Keyed Payload Encoder
x86/context_time manual time(2)-based Context Keyed Payload Encoder
x86/countdown normal Single-byte XOR Countdown Encoder
x86/fnstenv_mov normal Variable-length Fnstenv/mov Dword XOR Encoder
x86/jmp_call_additive normal Jump/Call XOR Additive Feedback Encoder
x86/nonalpha low Non-Alpha Encoder
x86/nonupper low Non-Upper Encoder
x86/shikata_ga_nai excellent Polymorphic XOR Additive Feedback Encoder
x86/single_static_bit manual Single Static Bit
x86/unicode_mixed manual Alpha2 Alphanumeric Unicode Mixedcase Encoder
x86/unicode_upper manual Alpha2 Alphanumeric Unicode Uppercase Encoder
原数据
unsigned char buf[] =
"\x68\x6C\x61\x6E\x00\x68\x43\x6F\x72\x65\x89\xE3\x68\x61\x6E\x20"
"\x00\x68\x6F\x72\x65\x6C\x68\x62\x79\x20\x43\x68\x6E\x65\x64\x20"
"\x68\x6E\x20\x70\x77\x68\x20\x62\x65\x65\x68\x68\x61\x76\x65\x68"
"\x59\x6F\x75\x20\x89\xE1\x31\xC0\x50\x53\x51\x50\x50\xBE\x71\xEA"
"\xB7\x76\xFF\xE6\x31\xC0\x50\xB8\xCF\x2A\x20\x76\xFF\xE0;
第一次加密得到的数据:
unsigned char buf[] =
"\xd9\xc2\xb8\xbe\xf3\x6c\x57\xd9\x74\x24\xf4\x5e\x33\xc9\xb1"
"\x14\x31\x46\x19\x83\xc6\x04\x03\x46\x15\x5c\x06\x04\x3b\xc1"
"\x87\xd5\xab\x42\x37\xa4\x4e\xcd\x24\x20\xf0\xa3\x8a\xb1\x9a"
"\x54\xb9\xd4\x36\xc2\x5f\x6e\xe7\x51\xc8\xfe\x82\x31\x28\x97"
"\x22\x99\x58\x10\xd3\xf9\xfa\xbb\x46\x91\x92\x22\xff\x04\x0b"
"\xfc\x90\xb3\xeb\x77\x8f\x0a\x2c\xd7\x03\x3d\xfc\x88\x1d\xcc"
"\x16\x9f\x14\xd1\x01\xd1\x18\x7d\x76\xdd\xb3\x5d\xf0\x1d\x23";
第二次加密得到的数据:
unsigned char buf[] =
"\xba\x81\xf6\xc8\x1d\xd9\xec\xd9\x74\x24\xf4\x5d\x2b\xc9\xb1"
"\x14\x83\xc5\x04\x31\x55\x10\x03\x55\x10\x63\x03\xa0\x71\x02"
"\x82\x31\xe2\x87\x35\x40\x97\x8e\x29\xcc\x36\xfe\x8d\x0d\xd1"
"\x91\xbf\x68\x4d\x05\x22\x0a\xad\x96\xca\x82\xc8\x7c\x2b\x33"
"\x7d\x5c\x5b\xb4\xe9\xbc\xf9\x5f\x8f\xd4\x95\xfe\x39\x41\x0e"
"\x58\xa9\xfc\xee\xd3\xd4\xcf\x2e\xb3\x45\x7e\xff\x64\xd4\xf1"
"\x15\x33\x5e\x0e\x0f\x0d\x5f\xa0\x68\xa1\x75\x60\xff\xc1\x6a";
将第一次加密后的数据放入OD调试:
d9 c2 b8 be f3 6c 57 d9 74 24 f4 5e 33 c9 b1
14 31 46 19 83 c6 04 03 46 15 5c 06 04 3b c1
87 d5 ab 42 37 a4 4e cd 24 20 f0 a3 8a b1 9a
54 b9 d4 36 c2 5f 6e e7 51 c8 fe 82 31 28 97
22 99 58 10 d3 f9 fa bb 46 91 92 22 ff 04 0b
fc 90 b3 eb 77 8f 0a 2c d7 03 3d fc 88 1d cc
16 9f 14 d1 01 d1 18 7d 76 dd b3 5d f0 1d 23
00429377 > D9C2 fld st(2)
00429379 B8 BEF36C57 mov eax, 576CF3BE //key=576CF3BE
0042937E D97424 F4 fstenv (28-byte) ptr [esp-C]//栈顶放入shellcode起始地址00429377
00429382 5E pop esi //esi定位到shellcode起始处
00429383 33C9 xor ecx, ecx
00429385 B1 14 mov cl, 14 //解密长度0x14个dword
00429387 3146 19 xor dword ptr [esi+19], eax //xor key=576CF3BE
0042938A 83C6 04 add esi, 4 // 加密下一个dword数据
0042938D 0346 15 add eax, dword ptr [esi+15] //key=key+本次解密的数据
00429390 5C pop esp //待数据起始地址
00429391 06 push es
00429392 04 3B add al, 3B
00429394 C187 D5AB4237>rol dword ptr [edi+3742ABD5], 0A4
...........................
将第二次加密后的数据也放入OD调试:
ba 81 f6 c8 1d d9 ec d9 74 24 f4 5d 2b c9 b1
14 83 c5 04 31 55 10 03 55 10 63 03 a0 71 02
82 31 e2 87 35 40 97 8e 29 cc 36 fe 8d 0d d1
91 bf 68 4d 05 22 0a ad 96 ca 82 c8 7c 2b 33
7d 5c 5b b4 e9 bc f9 5f 8f d4 95 fe 39 41 0e
58 a9 fc ee d3 d4 cf 2e b3 45 7e ff 64 d4 f1
15 33 5e 0e 0f 0d 5f a0 68 a1 75 60 ff c1 6a
00429377 > BA 81F6C81D mov edx, 1DC8F681 //key=1DC8F681
0042937C D9EC fldlg2
0042937E D97424 F4 fstenv (28-byte) ptr [esp-C]
00429382 5D pop ebp //ebp定位到0042937C处
00429383 2BC9 sub ecx, ecx
00429385 B1 14 mov cl, 14 //解密长度0x14个dword
00429387 83C5 04 add ebp, 4
0042938A 3155 10 xor dword ptr [ebp+10], edx
0042938D 0355 10 add edx, dword ptr [ebp+10]//key=key+本次解密的数据
00429390 6303 arpl word ptr [ebx], ax
00429392 A0 71028231 mov al, byte ptr [31820271]
00429397 ^ E2 87 loopd short 00429320
00429399 35 40978E29 xor eax, 298E9740
//执行完 fstenv (28-byte) ptr [esp-C]后堆栈的情况
0012FF80 FFFF027F //027f是控制字
0012FF84 FFFF3800 //3800是状态字
0012FF88 FFFF3FFF
0012FF8C 0042937C //栈顶esp处为前一条FPU指令的地址
0012FF90 01EC001B
0012FF94 00000000
0012FF98 FFFF0023
0012FF9C 7FFD4000
0012FFA0 7786B4F9
0012FFA4 00000000
fstenv (28-byte) ptr [esp-C]这句前面必须先有一句任意的FPU指令,返回的数据从esp-C开始存放,确保栈顶处正好是前一条FPU指令的地址,以此定位解密数据的起始位置。
以第二个例子来说,前一条FPU指令为fldlg2,所以 pop ebp后,ebp的值距离shellcode起始偏移为5,而xor dword ptr [ebp+10], edx该句中ebp还要加上0x10,要想ebp能定位到shellcode偏移0x19处的加密数据,ebp必须再增加4,所以你看到这里出现了一句:
00429387 83C5 04 add ebp, 4
简单分析一下metasploit的payload的默认加密方式,它的异或key还是变化的,与前次解密数据有关。
以前这些东西都没有人讲到,我就随便说几句了,如有错误请大家指正,谢谢!
天易love
2012年7月12日
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!