Writeup Dr. Evil from Midnightsun CTF 2019 (Quals)

by: fhred (Jost Rossel)

Challenge description:

Categories: network | pwned!
Points: 893
Solves: 8

We have managed to intercept communications from Dr. Evil’s base but it seems to be encrypted. Can you recover the secret message.

Download: dr_evil.tar.gz (containing dr-evil.pcap)

The TAR archive contains a .pcap file of a TLS v1.2 connection between 10.0.2.15 (Client) and 52.15.194.28 (Server). The TLS connction uses the TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 cipher suite and the Server is authenticated with a DigiCert certificate. Therefore, an attack on the cryptography of this system did not seem reasonable.

That implies, that the flag must be hidden somewhere within the non-encrypted part of the communication (i.e. the package’s headers).

After a long time of try and error we’ve found, that the flags of some IP packages where declared as evil by Scapy; for example:

pkts = rdpcap('dr-evil.pcap')
print(pkts[100].show())

outputs

###[ cooked linux ]###
  pkttype   = unicast
  lladdrtype= 0x1
  lladdrlen = 6
  src       = 'RT\x00\x125\x02'
  proto     = IPv4
###[ IP ]###
     version   = 4
     ihl       = 5
     tos       = 0x0
     len       = 4420
     id        = 12338
     flags     = evil
     frag      = 0
     ttl       = 64
     proto     = tcp
     chksum    = 0x3748
     src       = 52.15.194.28
     dst       = 10.0.2.15
     \options   \
###[ TCP ]###
        sport     = https
        dport     = 56030
        seq       = 932620855
        ack       = 2065585991
        dataofs   = 5
        reserved  = 0
        flags     = PA
        window    = 65535
        chksum    = 0x1371
        urgptr    = 0
        options   = []

Scapy declares the flags as evil, if and only if the Reserved bit is set to 1, as that flag is defined as always 0 by the IP standard.
All these packages where send by the Server. Thus we extracted the bits of the Reserved bits flag of the server’s packages and printed them as ASCII.

That revealed the flag.

from scapy.all import *
import binascii

bitstream = ''

pkts = rdpcap('dr-evil.pcap')
for p in pkts:
    if p[IP].src == '52.15.194.28' and DNS not in p:
        if p[IP].flags == 'evil':
            bitstream += '1'
        else:
            bitstream += '0'

b = []
for i in range(0,len(bitstream),8):
    b.append(int(bitstream[i:i+8],2))
print(bytes(b))

Output:

b'Ladies and gentlemen, welcome to my underground lair. I have gathered here before me the world\'s deadliest assassins. And yet, each of you has failed to kill Austin Powers and submit the flag "midnight{1_Milli0n_evil_b1tz!}". That makes me angry. And when Dr. Evil gets angry, Mr. Bigglesworth gets upset. And when Mr. Bigglesworth gets upset, people DIE!!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'