Bugtraq mailing list archives

Analysis of jolt2.c (MS00-029)


From: mikael.olsson () ENTERNET SE (Mikael Olsson)
Date: Fri, 26 May 2000 13:18:13 +0200


For those interested, I've analyzed exactly what jolt2.c is
doing.

------------------------------------------------------------------
Subject: Analysis of jolt2.c
Date: 2000-05-26
Author: Mikael Olsson, EnterNet Sweden <mikael.olsson () enternet se>
------------------------------------------------------------------

There are two modes of operation:
- Illegaly fragmented ICMP ECHOs (pings)
- Illegaly fragmented UDP packets

They both send out a continous stream of identical
fragments (same offset, same frag ID, same everything)
where the fragments are constructed such that
- ALL fragments are sent with fragment offset 8190.
- 9 bytes of IP data are sent (total packet length 29)
- IP packet ID is 0x0455
- TTL is initially 255
- Source address is not spoofed
- Destination address is victim address
- IP checksum is set to zero (should be illegal)
- IP total length is set to 68 (IP+8+40) (illegal!)
- The IP MF flag is set to zero (last fragment)

The author has also gone to great lengths to ensure
that correct UDP/ICMP headers are sent, which is
kind of ludicrous, since no first fragment is sent.
Hence, no receiving computer will attempt to parse
the data sent as a sub-IP protocol header.

The ICMP header sent is an ICMP ECHO (ping) with
  code=0
  checksum=0
  unused 32-bit value = 0
  the one data byte = 0

The UDP header sent has dest port = user-specified,
  src port = user-specified (binary OR) 1235
  checksum = 0
  UDP total length = 9
  the one data byte = 'a'

Again: The recipient will never parse these headers.

Regarding the IP checksum being set to zero, I remember
reading somewhere that this was done to ensure that
one cannot attack victims more than one hop away. Any
sane router will discard the packet since the checksum
is invalid. (Setting the checksum to zero for "ignore"
is only valid for ICMP and UDP. IP is always required
to have a checksum).

I believe that this alone demonstrates a right-out ridiculous
failing in the MS IP stack. If a broken packet is received
(failing checksum tests), it shouldn't be able to damage
the recipient at all.

UNLESS ofcourse the problem here isn't fragmentation at all
but rather a resource exhaustion attack - maybe too many
packets are received for the MS stack to be able to handle
them all. Remember: there is no delay in sending the packets,
it's sending a continous stream of packets as fast as the
sender can handle.

Again, analyzing the structure of the fragments.

- The data _sent_ is 29 bytes (20 IP + 9 data), which is valid
  as it is a last fragment (MF=0).

- However, the data length reported by the IP header is 68
  bytes. This means that the packet should fail structural
  tests, if there are any. (However, we've learned from
  history that microsoft doesn't add structural integrity
  tests in the stack until there's a public exploit for
  a specific integrity violation. Nothing new here.)
  Receipt of a packet with a reported length being larger
  than the actual received length is a normal occurence,
  it'll happen any time a packet is truncated during transport.

- Fragments are flagged as being "last fragments".

------------------------------------------------------------------
CONCLUSIONS OF THE ATTACK
------------------------------------------------------------------

In conclusion, I see two ways that this could cause crashes:

1. It is really a network layer resource exhaustion attack
   rather than a fragmentation attack. The recipient should
   detect the broken packet at checksum verification time and
   discard it WITHOUT storing it for fragment reassembly.

2. Microsoft doesn't verify the checksum prior to storing it.
   Microsoft doesn't verify the structural integrity (the
     packet is truncated!)
   Microsoft stores all fragments received, perhaps triggering
   something very time-consuming for every packet received.
   (This is sort of odd however, since all fragments have
   the same offset, they should simply overwrite eachother?)
   The fragment will never reassemble.

I can see how 2) could cause problems. If there is some sort
of garbage collection mechanism, it would attempt to find
the "oldest" reassembly attempt and discard it when resources
are running low. However, all fragments belong to the
same reassembly. So, if the garbage collection route isn't
able to detect that there's something fishy with the "current"
reassembly and discard IT, we'd get resource exhaustion.

------------------------------------------------------------------
REFERENCES
------------------------------------------------------------------

The below header comes from jolt2.c:

/*
  * File:   jolt2.c
  * Author: Phonix <phonix () moocow org>
  * Date:   23-May-00
  *
  * Description: This is the proof-of-concept code for the
  *              Windows denial-of-serice attack described by
  *              the Razor team (NTBugtraq, 19-May-00)
  *              (MS00-029).  This code causes cpu utilization
  *              to go to 100%.
  *
  * Tested against: Win98; NT4/SP5,6; Win2K
  *
  * Written for: My Linux box.  YMMV.  Deal with it.
  *
  * Thanks: This is standard code.  Ripped from lots of places.
  *         Insert your name here if you think you wrote some of
  *         it.  It's a trivial exploit, so I won't take credit
  *         for anything except putting this file together.
  */

------------------------------------------------------------------
HOW DO FIREWALLS PROTECT AGAINST THIS ATTACK?
------------------------------------------------------------------

* In its current incarnation, any router would be able to
  protect against the attack, since the checksum is invalid.
  Unless ofcourse the router is broken and treats IP checksums
  of zero as "don't care".

IF the checksum is corrected, which it would probably be in
a live attack, a well-written (stateful) packet filtering
firewall should still be able to block it, since:

* The packet fails structural integrity tests. The reported
  length (68) is much larger than the received length (29).
  However: A broken router may decide to send 68 bytes when
  forwarding it (adding 39 bytes of random padding).
  I do not know what impact this will have on the receiving
  end.

* If the firewall has any sort of (pseudo)fragment reassembly,
  it shouldn't forward a single packet, since there are
  no valid fragments preceding the attack sequence.

* If the firewall maps fragments to open connections, it
  should detect that there is no open connection for this
  particular packet, thereby discarding it.

OR, for the second possibility (plain resource exhaustion).

* If this is simply a network level resource exhaustion attack,
  most people ought to be safe from Internet-based attack
  simply because their Internet connections are not powerful
  enough to cause damage to their computers. It is more likely
  that the Internet connection is completely flooded during
  the attempt.

------------------------------------------------------------------

Well, that's it for this time.

Regards,
Mikael Olsson


--
Mikael Olsson, EnterNet Sweden AB, Box 393, SE-891 28 ÖRNSKÖLDSVIK
Phone: +46-(0)660-29 92 00         Fax: +46-(0)660-122 50
Mobile: +46-(0)70-66 77 636
WWW: http://www.enternet.se        E-mail: mikael.olsson () enternet se



Current thread: