修复一个shellcode

https://www.exploit-db.com/shellcodes/40245

Windows/x86 - MessageBoxA() Shellcode (242 bytes)

shellcode功能是使用MessageBox弹出一个对话框

这个shellcode 在xpsp3 与win10 上是调不通的,提示内存不能读,经过查看shellcode对应的汇编,发现作者在查找GetProcAdress这个函数式使用了错误的方法,代码片段如下:

xor ecx,ecx

mov eax,[fs:ecx+0x30] ;PEB

mov eax,[eax+0xc] ;PEB->Ldr

mov esi,[eax+0x14] ;PEB->ldr.InMemOrderModuleList

lodsd

xchg esi,eax

lodsd

mov ecx,[eax+0x10] ;kernel32 base address

xor ebx,ebx

mov ebx,[ecx+0x3c] ;DOS->elf_anew

add ebx,ecx

mov ebx,[ebx+0x78] ;DataDirectory->VirtualAddress

add ebx,ecx ;IMAGE_EXPORT_DIRECTORY

mov esi,[ebx+0x20] ;AddressOfNames

add esi,ecx

xor edx,edx

上面是通过PEB一路找到kernel32.dll的函数导出表,函数导出表结构中最后三个字段是:

函数地址表:AddressOfFunctions,存储的是导出函数的偏移

函数名称表:AddressOfNames,存储的是导出函数的名称

函数地址索引表:AddressOfNameOrdinals,存储的是函数地址表中的序号

g:

inc edx

lodsd

add eax,ecx

cmp dword [eax],'GetP'

jnz g

cmp dword [eax+4],'rocA'

jnz g

cmp dword [eax+8],'ddre'

jnz g

;执行到这里edx中存储的是函数GetProcAdress的索引,在AdressOfNameOrdinals表中同样的索引位置存储着AddressOfFunctions索引值+1。

mov esi,[ebx+0x1c] ;AddressOfFunctions

add esi,ecx

mov edx,[esi+edx*4]

;上面这一段作者直接用前面找到的索引值对AdressOfFunctions进行索引,这样做可能碰巧能获取到正确的值。修改后的代码如下:

mov eax,[ebx+24h];找到导出表中的AddressOfNameOrdinals RVA

add eax,ecx;生成VA

mov dx,word ptr[eax+edx*2];因为AddressOfNameOrdinals表示word类型,且与AddressOfNames的索引是对应的

;ax 中存放的值为GetProcAdress函数在AdressOfFunctions表中的位置

dec edx

mov eax,[ebx+1ch];找到导出表中的AddressOfFunctions的RVA

add eax,ecx;生成VA

mov edx,[eax+edx*4];找到GetProcAdress 在AdressOfFunctions 表中具体位置保存的RVA

add edx,ecx;生成VA

到这里edx中保存的就是GetProcAdress函数地址

完整的汇编代码如下,分号在汇编中表示注释:

xor ecx,ecx ; shellcod.00424B90

mov eax,dword ptr fs:[ecx+0x30]

mov eax,dword ptr ds:[eax+0xC]

mov esi,dword ptr ds:[eax+0x14]

lods dword ptr ds:[esi]

xchg eax,esi

lods dword ptr ds:[esi]

mov ecx,dword ptr ds:[eax+0x10]

xor ebx,ebx

mov ebx,dword ptr ds:[ecx+0x3C]

add ebx,ecx

mov ebx,dword ptr ds:[ebx+0x78]

add ebx,ecx

mov esi,dword ptr ds:[ebx+0x20]

add esi,ecx

xor edx,edx

;-------------------

;ecx kernel32.imagebase

;ebx kernel32.export_table.base

;-------------------

;获取GetProcAdress在导出表中的位置

getadd:

inc edx

lods dword ptr ds:[esi]

add eax,ecx

cmp dword ptr ds:[eax],0x50746547

jnz getadd

cmp dword ptr ds:[eax+0x4],0x41636F72

jnz getadd

cmp dword ptr ds:[eax+0x8],0x65726464

jnz getadd

;edx 为GetProcAdress在导出表的的索引值

;mov esi,dword ptr ds:[ebx+0x1C];这个是找到AddressOfFunctions的RVA

;add esi,ecx;生成VA

;mov edx,dword ptr ds:[esi+edx*4];使用找到的索引值在AdreessOfFuncitons 表中找RVA,但这是错误的

;add edx,ecx;生成VA

;edx 为找到的GetProcAdress的地址值,但是上面这个方法是错误的

;-------------------

;ecx kernel32.imagebase

;ebx kernel32.export_table.base

;-------------------

mov eax,[ebx+24h];找到导出表中的AddressOfNameOrdinals RVA

add eax,ecx;生成VA

mov dx,word ptr[eax+edx*2];因为AddressOfNameOrdinals表示word类型,且与AddressOfNames的索引是对应的

;ax 中存放的值为GetProcAdress函数在AdressOfFunctions表中的位置

dec edx

mov eax,[ebx+1ch];找到导出表中的AddressOfFunctions的RVA

add eax,ecx;生成VA

mov edx,[eax+edx*4];找到GetProcAdress 在AdressOfFunctions 表中具体位置保存的RVA

add edx,ecx;生成VA

;-------------------

mov esi,edx

mov edi,ecx

xor ebx,ebx

push ebx

push 0x41797261

push 0x7262694C

push 0x64616F4C

push esp

push ecx

call edx

add esp,0x10

xor ecx,ecx

push 0x42426C6C

mov byte ptr ss:[esp+0x2],cl

push 0x642E3233

push 0x72657375

push esp

call eax

add esp,0xC

xor ecx,ecx

push 0x4241786F

mov byte ptr ss:[esp+0x3],cl

push 0x42656761

push 0x7373654D

push esp

push eax

call esi

add esp,0xC

xor edx,edx

xor ecx,ecx

push edx

push 0x21216773

push 0x6D20656C

push 0x706D6153

lea edx,dword ptr ss:[esp]

push ecx

push 0x65726568

push 0x54206968

lea ecx,dword ptr ss:[esp]

xor ebx,ebx

inc ebx

push ebx

push edx

push ecx

xor ebx,ebx

push ebx

call eax

xor ecx,ecx

push 0x41737365

mov byte ptr ss:[esp+0x3],cl

push 0x636F7250

push 0x74697845

lea ecx,dword ptr ss:[esp]

push ecx

push edi

call esi

xor ecx,ecx

push ecx

call eax

nop

生成shellcode 如下:

include

include

char shellcode[]="\x33\xC9\x64\x8B\x41\x30\x3E\x8B\x40\x0C\x3E\x8B\x70\x14\xAD\x96\xAD\x3E\x8B\x48\x10\x33\xDB\x3E\x8B\x59\x3C\x03\xD9\x3E\x8B\x5B\x78\x03\xD9\x3E\x8B\x73\x20\x03\xF1\x33\xD2\x42\xAD\x03\xC1\x3E\x81\x38\x47\x65\x74\x50\x75\xF3\x3E\x81\x78\x04\x72\x6F\x63\x41\x75\xE9\x3E\x81\x78\x08\x64\x64\x72\x65\x75\xDF\x8B\x43\x24\x03\xC1\x66\x8B\x14\x50\x4A\x8B\x43\x1C\x03\xC1\x8B\x14\x90\x8B\xC1\x03\xD0\x8B\xF2\x8B\xF9\x33\xDB\x53\x68\x61\x72\x79\x41\x68\x4C\x69\x62\x72\x68\x4C\x6F\x61\x64\x54\x51\xFF\xD2\x83\xC4\x10\x33\xC9\x68\x6C\x6C\x42\x42\x36\x88\x4C\x24\x02\x68\x33\x32\x2E\x64\x68\x75\x73\x65\x72\x54\xFF\xD0\x83\xC4\x0C\x33\xC9\x68\x6F\x78\x41\x42\x36\x88\x4C\x24\x03\x68\x61\x67\x65\x42\x68\x4D\x65\x73\x73\x54\x50\xFF\xD6\x83\xC4\x0C\x33\xD2\x33\xC9\x52\x68\x73\x67\x21\x21\x68\x6C\x65\x20\x6D\x68\x53\x61\x6D\x70\x36\x8D\x14\x24\x51\x68\x68\x65\x72\x65\x68\x68\x69\x20\x54\x36\x8D\x0C\x24\x33\xDB\x43\x53\x52\x51\x33\xDB\x53\xFF\xD0\x33\xC9\x68\x65\x73\x73\x41\x36\x88\x4C\x24\x03\x68\x50\x72\x6F\x63\x68\x45\x78\x69\x74\x36\x8D\x0C\x24\x51\x57\xFF\xD6\x33\xC9\x51\xFF\xD0";

void main()

{

printf("shellcode lenght %ld\n",(long)strlen(shellcode));

_asm{

lea eax,shellcode

push eax

ret

}

}

运行截图如下:


图片.png

https://www.exploit-db.com/shellcodes/40246这个shellcode 是同样的问题

你可能感兴趣的:(修复一个shellcode)