0x00 shellcode
这段是楼主最近在看历史中的exp时发现的shellcode,功能是弹计算器,在09年时使用很广泛,但是没有找到相关的分析文献,准备有时间研究下。
0xdb 0xc0 0x31 0xc9 0xbf 0x7c 0x16 0x70 0xcc 0xd9 0x74 0x24 0xf4 0xb1 0x1e 0x58 0x31 0x78 0x18 0x83 0xe8 0xfc 0x03 0x78 0x68 0xf4 0x85 0x30 0x78 0xbc 0x65 0xc9 0x78 0xb6 0x23 0xf5 0xf3 0xb4 0xae 0x7d 0x02 0xaa 0x3a 0x32 0x1c 0xbf 0x62 0xed 0x1d 0x54 0xd5 0x66 0x29 0x21 0xe7 0x96 0x60 0xf5 0x71 0xca 0x06 0x35 0xf5 0x14 0xc7 0x7c 0xfb 0x1b 0x05 0x6b 0xf0 0x27 0xdd 0x48 0xfd 0x22 0x38 0x1b 0xa2 0xe8 0xc3 0xf7 0x3b 0x7a 0xcf 0x4c 0x4f 0x23 0xd3 0x53 0xa4 0x57 0xf7 0xd8 0x3b 0x83 0x8e 0x83 0x1f 0x57 0x53 0x64 0x51 0xa1 0x33 0xcd 0xf5 0xc6 0xf5 0xc1 0x7e 0x98 0xf5 0xaa 0xf1 0x05 0xa8 0x26 0x99 0x3d 0x3b 0xc0 0xd9 0xfe 0x51 0x61 0xb6 0x0e 0x2f 0x85 0x19 0x87 0xb7 0x78 0x2f 0x59 0x90 0x7b 0xd7 0x05 0x7f 0xe8 0x7b 0xca
放一张全景图:
这里使用3种方法转换shellcode:
1. windbg工具转换shellcode
2. linux下转换shellcode
3. ollydbg工具转换shellcode
0x01 windbg工具转换shellcode
基本思路
windbg作为windows调试神器,能以各种姿势调戏内存,将一段16进制的shellcode转化成汇编也不在话下。
先开辟一段内存空间,写入shellcode, 再反汇编这段数据,搞定。
调试过程
0:009> .dvalloc 1000 # 申请1000个字节的内存
Allocated 1000 bytes starting at 01190000 # 内存起始地址为01190000
# eb 用来写入shellcode到内存
0:000> eb 01190000 0xdb 0xc0 0x31 0xc9 0xbf 0x7c 0x16 0x70 0xcc 0xd9 0x74 0x24 0xf4 0xb1 0x1e 0x58 0x31 0x78 0x18 0x83 0xe8 0xfc 0x03 0x78 0x68 0xf4 0x85 0x30 0x78 0xbc 0x65 0xc9 0x78 0xb6 0x23 0xf5 0xf3 0xb4 0xae 0x7d 0x02 0xaa 0x3a 0x32 0x1c 0xbf 0x62 0xed 0x1d 0x54 0xd5 0x66 0x29 0x21 0xe7 0x96 0x60 0xf5 0x71 0xca 0x06 0x35 0xf5 0x14 0xc7 0x7c 0xfb 0x1b 0x05 0x6b 0xf0 0x27 0xdd 0x48 0xfd 0x22 0x38 0x1b 0xa2 0xe8 0xc3 0xf7 0x3b 0x7a 0xcf 0x4c 0x4f 0x23 0xd3 0x53 0xa4 0x57 0xf7 0xd8 0x3b 0x83 0x8e 0x83 0x1f 0x57 0x53 0x64 0x51 0xa1 0x33 0xcd 0xf5 0xc6 0xf5 0xc1 0x7e 0x98 0xf5 0xaa 0xf1 0x05 0xa8 0x26 0x99 0x3d 0x3b 0xc0 0xd9 0xfe 0x51 0x61 0xb6 0x0e 0x2f 0x85 0x19 0x87 0xb7 0x78 0x2f 0x59 0x90 0x7b 0xd7 0x05 0x7f 0xe8 0x7b 0xca
0:000> u 01190000 # 反汇编,默认一次输出8行汇编代码
01190000 dbc0 fcmovnb st,st(0)
01190002 31c9 xor ecx,ecx
01190004 bf7c1670cc mov edi,0CC70167Ch
01190009 d97424f4 fnstenv [esp-0Ch]
0119000d b11e mov cl,1Eh
0119000f 58 pop eax
01190010 317818 xor dword ptr [eax+18h],edi
01190013 83e8fc sub eax,0FFFFFFFCh
0:000> u # 继续反汇编
01190016 037868 add edi,dword ptr [eax+68h]
01190019 f4 hlt
0119001a 8530 test dword ptr [eax],esi
0119001c 78bc js 0118ffda
0119001e 65c9 leave
01190020 78b6 js 0118ffd8
01190022 23f5 and esi,ebp
01190024 f3b4ae rep mov ah,0AEh
0:000> u
01190027 7d02 jge 0119002b
01190029 aa stos byte ptr es:[edi]
0119002a 3a32 cmp dh,byte ptr [edx]
0119002c 1cbf sbb al,0BFh
0119002e 62 ???
0119002f ed in eax,dx
01190030 1d54d56629 sbb eax,2966D554h
01190035 21e7 and edi,esp
0:000> u
01190037 96 xchg eax,esi
01190038 60 pushad
01190039 f5 cmc
0119003a 71ca jno 01190006
0119003c 06 push es
0119003d 35f514c77c xor eax,7CC714F5h
01190042 fb sti
01190043 1b056bf027dd sbb eax,dword ptr ds:[0DD27F06Bh]
0:000> u
01190049 48 dec eax
0119004a fd std
0119004b 2238 and bh,byte ptr [eax]
0119004d 1ba2e8c3f73b sbb esp,dword ptr [edx+3BF7C3E8h]
01190053 7acf jp 01190024
01190055 4c dec esp
01190056 4f dec edi
01190057 23d3 and edx,ebx
0:000> u
01190059 53 push ebx
0119005a a4 movs byte ptr es:[edi],byte ptr [esi]
0119005b 57 push edi
0119005c f7d8 neg eax
0119005e 3b838e831f57 cmp eax,dword ptr [ebx+571F838Eh]
01190064 53 push ebx
01190065 6451 push ecx
01190067 a133cdf5c6 mov eax,dword ptr ds:[C6F5CD33h]
0:000> u
0119006c f5 cmc
0119006d c17e98f5 sar dword ptr [esi-68h],0F5h
01190071 aa stos byte ptr es:[edi]
01190072 f1 ???
01190073 05a826993d add eax,3D9926A8h
01190078 3bc0 cmp eax,eax
0119007a d9fe fsin
0119007c 51 push ecx
0:000> u
0119007d 61 popad
0119007e b60e mov dh,0Eh
01190080 2f das
01190081 8519 test dword ptr [ecx],ebx
01190083 87b7782f5990 xchg esi,dword ptr [edi-6FA6D088h]
01190089 7bd7 jnp 01190062
0119008b 057fe87bca add eax,0CA7BE87Fh
0x02 linux下转换shellcode
ubuntu环境
➜ ~ cat /etc/issue
Ubuntu 16.04.2 LTS \n \l
基本思路
将shellcode以二进制格式存储成文件,再使用工具(nasm)反汇编。
调试过程
安装工具
➜ ~ sudo apt-get install nasm
使用脚本生成shellcode二进制文件
➜ ~ python gen_shellcode.py
gen_shellcode.py源码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
a = "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1"\
"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30"\
"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa"\
"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96"\
"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b"\
"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a"\
"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83"\
"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98"\
"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61"\
"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05"\
"\x7f\xe8\x7b\xca"
with open("Shellcode.exe", 'wb') as fp:
fp.write(a)
查看生成的shellcode二进制文件
➜ ~ hexdump Shellcode.exe
0000000 c0db c931 7cbf 7016 d9cc 2474 b1f4 581e
0000010 7831 8318 fce8 7803 f468 3085 bc78 c965
0000020 b678 f523 b4f3 7dae aa02 323a bf1c ed62
0000030 541d 66d5 2129 96e7 f560 ca71 3506 14f5
0000040 7cc7 1bfb 6b05 27f0 48dd 22fd 1b38 e8a2
0000050 f7c3 7a3b 4ccf 234f 53d3 57a4 d8f7 833b
0000060 838e 571f 6453 a151 cd33 c6f5 c1f5 987e
0000070 aaf5 05f1 26a8 3d99 c03b fed9 6151 0eb6
0000080 852f 8719 78b7 592f 7b90 05d7 e87f ca7b
0000090
使用intel指令集反汇编shellcode
➜ ~ ndisasm Shellcode.exe -p intel
00000000 DBC0 fcmovnb st0
00000002 31C9 xor cx,cx
00000004 BF7C16 mov di,0x167c
00000007 70CC jo 0xffd5
00000009 D97424 fnstenv [si+0x24]
0000000C F4 hlt
0000000D B11E mov cl,0x1e
0000000F 58 pop ax
00000010 317818 xor [bx+si+0x18],di
00000013 83E8FC sub ax,byte -0x4
00000016 037868 add di,[bx+si+0x68]
00000019 F4 hlt
0000001A 8530 test [bx+si],si
0000001C 78BC js 0xffda
0000001E 65C9 gs leave
00000020 78B6 js 0xffd8
00000022 23F5 and si,bp
00000024 F3B4AE rep mov ah,0xae
00000027 7D02 jnl 0x2b
00000029 AA stosb
0000002A 3A32 cmp dh,[bp+si]
0000002C 1CBF sbb al,0xbf
0000002E 62 db 0x62
0000002F ED in ax,dx
00000030 1D54D5 sbb ax,0xd554
00000033 662921 sub [bx+di],esp
00000036 E796 out 0x96,ax
00000038 60 pushaw
00000039 F5 cmc
0000003A 71CA jno 0x6
0000003C 06 push es
0000003D 35F514 xor ax,0x14f5
00000040 C7 db 0xc7
00000041 7CFB jl 0x3e
00000043 1B05 sbb ax,[di]
00000045 6BF027 imul si,ax,byte +0x27
00000048 DD48FD fisttp qword [bx+si-0x3]
0000004B 2238 and bh,[bx+si]
0000004D 1BA2E8C3 sbb sp,[bp+si-0x3c18]
00000051 F73B idiv word [bp+di]
00000053 7ACF jpe 0x24
00000055 4C dec sp
00000056 4F dec di
00000057 23D3 and dx,bx
00000059 53 push bx
0000005A A4 movsb
0000005B 57 push di
0000005C F7D8 neg ax
0000005E 3B838E83 cmp ax,[bp+di-0x7c72]
00000062 1F pop ds
00000063 57 push di
00000064 53 push bx
00000065 6451 fs push cx
00000067 A133CD mov ax,[0xcd33]
0000006A F5 cmc
0000006B C6 db 0xc6
0000006C F5 cmc
0000006D C17E98F5 sar word [bp-0x68],byte 0xf5
00000071 AA stosb
00000072 F1 int1
00000073 05A826 add ax,0x26a8
00000076 99 cwd
00000077 3D3BC0 cmp ax,0xc03b
0000007A D9FE fsin
0000007C 51 push cx
0000007D 61 popaw
0000007E B60E mov dh,0xe
00000080 2F das
00000081 8519 test [bx+di],bx
00000083 87B7782F xchg si,[bx+0x2f78]
00000087 59 pop cx
00000088 90 nop
00000089 7BD7 jpo 0x62
0000008B 057FE8 add ax,0xe87f
0000008E 7BCA jpo 0x5a
ndisasm反汇编工具的其他选项还是可以探索下的,比如32位和64位,AT&T,AMD, Intel各种指令集的不同,对反汇编都有影响。
0x03 ollydbg工具转换shellcode
基本思路
将shellcode的16进制数据copy到ollydbg工具的反汇编窗口中,即可完成。
调试步骤
格式化shellcode
db c0 31 c9 bf 7c 16 70 cc d9 74 24 f4 b1 1e 58 31 78 18 83 e8 fc 03 78 68 f4 85 30 78 bc 65 c9 78 b6 23 f5 f3 b4 ae 7d 02 aa 3a 32 1c bf 62 ed 1d 54 d5 66 29 21 e7 96 60 f5 71 ca 06 35 f5 14 c7 7c fb 1b 05 6b f0 27 dd 48 fd 22 38 1b a2 e8 c3 f7 3b 7a cf 4c 4f 23 d3 53 a4 57 f7 d8 3b 83 8e 83 1f 57 53 64 51 a1 33 cd f5 c6 f5 c1 7e 98 f5 aa f1 05 a8 26 99 3d 3b c0 d9 fe 51 61 b6 0e 2f 85 19 87 b7 78 2f 59 90 7b d7 05 7f e8 7b ca
放一张全景图:
在ollydbg中打开任意一个exe文件
在反汇编窗口中选中足够的行数,鼠标右击-二进制-二进制粘贴。
结果如下:
004011CD DBC0 fcmovnb st,st ; |Style
004011CF 31C9 xor ecx,ecx
004011D1 BF 7C1670CC mov edi,0xCC70167C
004011D6 D97424 F4 fstenv (28-byte) ptr ss:[esp-0xC]
004011DA B1 1E mov cl,0x1E ; \CreateWindowExA
004011DC 58 pop eax ; kernel32.75A933CA
004011DD 3178 18 xor dword ptr ds:[eax+0x18],edi
004011E0 83E8 FC sub eax,-0x4
004011E3 0378 68 add edi,dword ptr ds:[eax+0x68]
004011E6 f4 hlt
004011E7 8530 test dword ptr ds:[eax],esi
004011E9 ^ 78 BC js short PEview.004011A7 ; /lParam
004011EB 65:c9 leave
004011ED ^ 78 B6 js short PEview.004011A5
004011EF 23F5 and esi,ebp
004011F1 f3:b4 ae rep mov ah,0xae
004011F4 7D 02 jge short PEview.004011F8 ; |pTemplate
004011F6 AA stos byte ptr es:[edi] ; |hInst
004011F7 3A32 cmp dh,byte ptr ds:[edx]
004011F9 1C BF sbb al,0xBF
004011FB 62ed bound ebp,ebp
004011FD 1D 54D56629 sbb eax,0x2966D554
00401202 21E7 and edi,esp
00401204 96 xchg eax,esi
00401205 60 pushad
00401206 F5 cmc
00401207 ^ 71 CA jno short PEview.004011D3
00401209 06 push es
0040120A 35 F514C77C xor eax,0x7CC714F5
0040120F FB sti
00401210 1B05 6BF027DD sbb eax,dword ptr ds:[0xDD27F06B]
00401216 48 dec eax ; kernel32.BaseThreadInitThunk
00401217 FD std
00401218 2238 and bh,byte ptr ds:[eax]
0040121A 1BA2 E8C3F73B sbb esp,dword ptr ds:[edx+0x3BF7C3E8]
00401220 7A CF jpe short PEview.004011F1
00401222 4c dec esp
00401223 4F dec edi
00401224 23D3 and edx,ebx
00401226 53 push ebx
00401227 A4 movs byte ptr es:[edi],byte ptr ds:[esi]
00401228 57 push edi
00401229 F7D8 neg eax ; kernel32.BaseThreadInitThunk
0040122B 3B83 8E831F57 cmp eax,dword ptr ds:[ebx+0x571F838E]
00401231 53 push ebx ; |hWnd = 7EFDE000
00401232 64:51 push ecx ; \SetWindowPlacement
00401234 A1 33CDF5C6 mov eax,dword ptr ds:[0xC6F5CD33]
00401239 F5 cmc ; \UpdateWindow
0040123A c17e 98 f5 sar dword ptr ds:[esi-0x68],0xf5
0040123E AA stos byte ptr es:[edi]
0040123F F1 int1
00401240 05 A826993D add eax,0x3D9926A8
00401245 3BC0 cmp eax,eax ; kernel32.BaseThreadInitThunk
00401247 D9FE fsin
00401249 51 push ecx
0040124A 61 popad
0040124B B6 0E mov dh,0xE
0040124D 2F das
0040124E 8519 test dword ptr ds:[ecx],ebx
00401250 87B7 782F5990 xchg dword ptr ds:[edi-0x6FA6D088],esi
00401256 7B D7 jpo short PEview.0040122F
00401258 05 7FE87BCA add eax,0xCA7BE87F
这里**留一个坑**shellcode的转汇编工作完成了,剩下的是要分析汇编具体是做什么的。
神奇的shellcode,有很多指令都没听过过。
0x04 参考文献
https://bbs.pediy.com/thread-192293.htm
https://bbs.pediy.com/thread-178808.htm
https://blog..net/nicehunt/article/details/39318993
https://stackoverflow.com/questions/44781847/how-to-disassemble-a-shellcode-into-assembly-instruction