[NDH 2016] [CRACKME 150 – Don’t be too Evil. Just a little bit.] Write Up

Description

Only true Evil people can access this flag!

Thank you, Steven M. Bellovin !

Score
150
Link
telnet://evil.wargame.ndh:3514

Resolution

We’re facing a cool crackme challenge 🙂

The first thing we did was:

$ echo lol | telnet evil.wargame.ndh 3514
Trying 172.16.16.52...
Sorry, only true evil can access this content!

After some research on Steven M. Bellovin, it seems like he was the author of a well-know april fools joke, in RFC 3514. It talks about the Evil bit, which refers to the Reserved bit int the IPv4 header flags.

Here is a schema of the IPv4 header:

IPv4 Header

We understood that we had to set this Evil bit to 1.
We searched for some C raw sockets code we could modify a little (it is possible to resolve the challenge like that), but laxa told us about scapy, a powerful python module we could use to build raw network packets.
We struggled to make a working script, and came up with this one:

#!/usr/bin/env python
# coding: utf-8

from scapy.all import *

getStr = 'petit poney'

syn = IP(dst='evil.wargame.ndh', flags=0x80 | 0x40) / TCP(dport=3514, flags='A')
syn_ack = sr1(syn)

request = IP(dst='evil.wargame.ndh', flags=0x80 | 0x40)/  TCP(dport=3514, sport=syn_ack[TCP].dport, seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='A') / getStr
reply = sr1(request)

We used tcpdump to sniff the response of the server, but we unfortunately didn’t have the reflex to save the data it dumped for this write up. All we know is that it kept responding Sorry, only true evil can access this content!.

flags=0x80 is the critical part of the code, which was supposed to set the evil bit to 1, according to the above schema. Maybe have you already noticed the error, but it so happens that at one point of the night beer suddenly became free and unlimited, hence our alcohol level rised a smigdin.

The schema refers to the value of the bit in the whole byte it is in. The evil bit is the most significant bit, therefore the value of the byte is 0x80. But the scapy’s flags in the IP layer refers to his value in the flag field, which is 3 bits long. The most significant bit in a 3 bit integer sets its value to 4 (2²).
We didn’t understand this during the Nuit du Hack, we simply copied and pasted a fragment of code on this webpage (ctrl + F evil).

The correct code was:

#!/usr/bin/env python
# coding: utf-8

from scapy.all import *

getStr = 'petit poney'

syn = IP(dst='evil.wargame.ndh', flags=0b100 | 0b010) / TCP(dport=3514, flags='A')
syn_ack = sr1(syn)

request = IP(dst='evil.wargame.ndh', flags=0b100 | 0b010)/  TCP(dport=3514, sport=syn_ack[TCP].dport, seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='A') / getStr
reply = sr1(request)

A packet containing the evil bit looks like that (local simulation), the 7th byte is set to 0xc0 (0x80 | 0x40):

$ sudo tcpdump -X "port 1337" -i lo 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
18:58:17.157097 IP localhost.ftp-data > localhost.1337: Flags [.], ack 0, win 8192, length 0
        0x0000:  4500 0028 0001 c000 4006 bccc 7f00 0001  E..(....@.......
        0x0010:  7f00 0001 0014 0539 0000 0000 0000 0000  .......9........
        0x0020:  5010 2000 8c85 0000                      P.......

The tcpdump command showed the response of the server, which contained a flag, w00t !

Flag was something like ndh2k16_764f2dac74f9d951436115417532b4fc !

Leave a Reply

Your email address will not be published. Required fields are marked *