学习了[0day 安全]shellcode 记录一下分析
shellcode:
unsigned char shellcode[]= "\xfc\x68\x6a\x0a\x38\x1e\x68\x63\x89\xd1\x4f\x68\x32\x74\x91\x0c"
"\x8b\xf4\x8d\x7e\xf4\x33\xdb\xb7\x04\x2b\xe3\x66\xbb\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xd2\x64\x8b\x5a\x30\x8b\x4b\x0c\x8b"
"\x49\x1c\x8b\x09\x8b\x09\x8b\x69\x08\xad\x3d\x6a\x0a\x38\x1e\x75"
"\x05\x95\xff\x57\xf8\x95\x60\x8b\x45\x3c\x8b\x4c\x05\x78\x03\xcd"
"\x8b\x59\x20\x03\xdd\x33\xff\x47\x8b\x34\xbb\x03\xf5\x99\x0f\xbe"
"\x06\x3a\xc4\x74\x08\xc1\xca\x07\x03\xd0\x46\xeb\xf1\x3b\x54\x24"
"\x1c\x75\xe4\x8b\x59\x24\x03\xdd\x66\x8b\x3c\x7b\x8b\x59\x1c\x03"
"\xdd\x03\x2c\xbb\x95\x5f\xab\x57\x61\x3d\x6a\x0a\x38\x1e\x75\xa9"
"\x33\xdb\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6c\x8b\xc4\x53"
"\x50\x50\x53\xff\x57\xfc\x53\xff\x57\xf8";
分析:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
__asm {
jmp mainbegin
__emit 'B'
__emit 'E'
__emit 'G'
__emit 'I'
__emit 'N'
__emit '\0'
}
mainbegin:
_asm {
nop
nop
nop
nop
nop
CLD //clear flag DF 使字符串流操作向后递增处理
//store hash
push 0x1e380a6a //hash of MessageBoxA
push 0x4fd18963 //hash of ExitProcess
push 0x0c917432 //hash of LoadLibraryA
mov esi,esp //loadlibraryA hash
lea edi,[esi-0xc] //edi = addr to start writing function
//make some stack space (400h speace is enough)
xor ebx,ebx
mov bh,0x04
sub esp,ebx
mov bx,0x3233
push ebx
push 0x72657375 //'user32'
push esp //esp now is pointer to string 'user32' in stack.
//find base addr of kernel32.dll
//fs:[0]--> TEB
//fs:[30]--> PEB
//[PEB+0c]--> Ldr(ptr32 _PEB_LDR_DATA)
//[Ldr+1c]--> InInitializationOrderModuleList(LIST_ENTRY)
//[LIST_ENTRY] = second_LIST_ENTRY
//[second_LIST_ENTRY] = third_LIST_ENTRY
//[third_LIST_ENTRY+0x8]-->kernel32 module base address
xor edx,edx
mov ebx,fs:[edx+0x30] //PEB
mov ecx,[ebx+0x0c] //ldr
mov ecx,[ecx+0x1c] //IninitializationOrderModuleList
mov ecx,[ecx] //ntdll
mov ecx,[ecx] //kernel base
mov ebp,[ecx+0x08] //kernel32
find_lib_functions:
lodsd //从esi中读取dword送入eax中并esi+4
cmp eax,0x1e380a6a //hash of MessageBoxA
jne find_functions //开始eax 是 LoadLibrary(hash),所以转去执行find_functions
xchg eax,ebp //一开始保存当前MessageBox Hash到ebp中
call[edi-0x8] //LoadLibraryA
xchg eax,ebp //restore current hash, and update ebp
find_functions :
pushad
//ebp:module base address
mov eax,[ebp+0x3c] //PE header
mov ecx,[ebp+eax+0x78] //export table
add ecx,ebp //absolute addr of export table
mov ebx,[ecx+0x20] //export names table
add ebx,ebp //absolute addr of names table
xor edi,edi //counter of fun searched
next_function_loop:
inc edi
mov esi,[ebx+edi*4] //relative offset of current function name
add esi,ebp //absolute addr of current function name
cdq //dl will hold hash(we know eax is small)
hash_loop: //计算hash
movsx eax,byte ptr[esi]
cmp al,ah
jz compare_hash
ror edx,7
add edx,eax
inc esi
jmp hash_loop
compare_hash:
cmp edx,[esp+0x1c] //compare to the requested hash(saved on stack from pushad)
jnz next_function_loop //不是我们的目标函数就继续查看下一个导出函数
//目标函数
mov ebx,[ecx+0x24]
add ebx,ebp
mov di,[ebx+2*edi]
mov ebx,[ecx+0x1c]
add ebx,ebp
add ebp,[ebx+4*edi]
xchg eax, ebp
pop edi
stosd
push edi
popad //restore registers
//loop until we reach end of last hash
cmp eax,0x1e380a6a //如果不是MessageBox就回到find_lib_functions
jne find_lib_functions
//已经找到了所有的函数地址 并且存入栈中
function_call :
xor ebx,ebx
push ebx //'\0'
push 0x6e754673
push 0x4965646f
push 0x436c6c65
push 0x68530000
add esp,0x2
mov eax,esp //address of 'shellcode is fun'
push ebx
push eax
push eax
push ebx
call[edi-0x04]; //call MessageboxA
push ebx
call[edi-0x08]; // call ExitProcess
nop
nop
nop
nop
}
__asm {
jmp mainend
__emit 'E'
__emit 'N'
__emit 'D'
__emit '\0'
}
mainend:
return 0;
}
动态分析记录:
00401269 | EB 06 | jmp shellcode.401271 |
0040126B | 42 | ascii B |
0040126C | 45 | ascii E |
0040126D | 47 | ascii G |
0040126E | 49 | ascii I |
0040126F | 4E | ascii N |
00401270 | 0090 90909090 | add byte ptr ds:[eax-6F6F6F70],dl |
00401276 | FC | cld | 清除d[flag]
00401277 | 68 6A0A381E | push 1E380A6A | MessageBoxA's Hash
0040127C | 68 6389D14F | push 4FD18963 | ExitProcess's Hash
00401281 | 68 3274910C | push C917432 | LoadLibraryA's Hash
00401286 | 8BF4 | mov esi,esp |
00401288 | 8D7E F4 | lea edi,dword ptr ds:[esi-C] |
0040128B | 33DB | xor ebx,ebx |
0040128D | B7 04 | mov bh,4 |
0040128F | 2BE3 | sub esp,ebx | 提升堆栈
00401291 | 66:BB 3332 | mov bx,3233 |
00401295 | 53 | push ebx | push 'user32'
00401296 | 68 75736572 | push 72657375 |
0040129B | 54 | push esp |
0040129C | 33D2 | xor edx,edx |
0040129E | 64:8B5A 30 | mov ebx,dword ptr fs:[edx+30] |
004012A2 | 8B4B 0C | mov ecx,dword ptr ds:[ebx+C] |
004012A5 | 8B49 1C | mov ecx,dword ptr ds:[ecx+1C] |
004012A8 | 8B09 | mov ecx,dword ptr ds:[ecx] |
004012AA | 8B09 | mov ecx,dword ptr ds:[ecx] |
004012AC | 8B69 08 | mov ebp,dword ptr ds:[ecx+8] |
004012AF | AD | lodsd |
004012B0 | 3D 6A0A381E | cmp eax,1E380A6A | messagebox's hash
004012B5 | 75 05 | jne shellcode.4012BC |
004012B7 | 95 | xchg ebp,eax |
004012B8 | FF57 F8 | call dword ptr ds:[edi-8] |
004012BB | 95 | xchg ebp,eax |
004012BC | 60 | pushad |
004012BD | 8B45 3C | mov eax,dword ptr ss:[ebp+3C] | nt_header
004012C0 | 8B4C05 78 | mov ecx,dword ptr ss:[ebp+eax+78] |
004012C4 | 03CD | add ecx,ebp | export_directory
004012C6 | 8B59 20 | mov ebx,dword ptr ds:[ecx+20] |
004012C9 | 03DD | add ebx,ebp | address_of_names
004012CB | 33FF | xor edi,edi |
004012CD | 47 | inc edi |
004012CE | 8B34BB | mov esi,dword ptr ds:[ebx+edi*4] |
004012D1 | 03F5 | add esi,ebp | export fun_name address
004012D3 | 99 | cdq |
004012D4 | 0FBE06 | movsx eax,byte ptr ds:[esi] | eax:&"ALLUSERSPROFILE=C:\\ProgramData"
004012D7 | 3AC4 | cmp al,ah | judge string end
004012D9 | 74 08 | je shellcode.4012E3 |
004012DB | C1CA 07 | ror edx,7 |
004012DE | 03D0 | add edx,eax | eax:&"ALLUSERSPROFILE=C:\\ProgramData"
004012E0 | 46 | inc esi |
004012E1 | EB F1 | jmp shellcode.4012D4 |
004012E3 | 3B5424 1C | cmp edx,dword ptr ss:[esp+1C] |
004012E7 | 75 E4 | jne shellcode.4012CD | compare hash
004012E9 | 8B59 24 | mov ebx,dword ptr ds:[ecx+24] |
004012EC | 03DD | add ebx,ebp | Address of Names
004012EE | 66:8B3C7B | mov di,word ptr ds:[ebx+edi*2] | 取出导出序号
004012F2 | 8B59 1C | mov ebx,dword ptr ds:[ecx+1C] |
004012F5 | 03DD | add ebx,ebp | Address of Functions[0]
004012F7 | 032CBB | add ebp,dword ptr ds:[ebx+edi*4] | The Functions address
004012FA | 95 | xchg ebp,eax | eax:function pointer
004012FB | 5F | pop edi |
004012FC | AB | stosd |
004012FD | 57 | push edi |
004012FE | 61 | popad |
004012FF | 3D 6A0A381E | cmp eax,1E380A6A | eax:&"ALLUSERSPROFILE=C:\\ProgramData"
00401304 | 75 A9 | jne shellcode.4012AF |
00401306 | 33DB | xor ebx,ebx |
00401308 | 53 | push ebx |
00401309 | 68 77657374 | push 74736577 |
0040130E | 68 6661696C | push 6C696166 |
00401313 | 8BC4 | mov eax,esp |
00401315 | 53 | push ebx |
00401316 | 50 | push eax | eax:&"ALLUSERSPROFILE=C:\\ProgramData"
00401317 | 50 | push eax | eax:&"ALLUSERSPROFILE=C:\\ProgramData"
00401318 | 53 | push ebx |
00401319 | FF57 FC | call dword ptr ds:[edi-4] |
0040131C | 53 | push ebx |
0040131D | FF57 F8 | call dword ptr ds:[edi-8] |
00401320 | 90 | nop |
00401321 | 90 | nop |
00401322 | 90 | nop |
00401323 | 90 | nop |
00401324 | EB 04 | jmp shellcode.40132A |
00401326 | 45 | ascii E |
00401327 | 4E | ascii N |
00401328 | 44 | ascii D |