eqqn Security blog

CTF write-ups

Home

The NIXU CHALLENGE : PORTS

Image

The NIXU challenge is back again, this time harder than ever [citation needed]*

Difficulty: easy

Points: 50

THe challenge states: The ports might be interesting, is there a way to hide information into numbers?

That is pretty straightforward, they provide a pcap file for you to analyse ports.pcap It has 64 packets recorded with the same source and destination IP’s - but each of them have different source and destination ports. Source ports are pretty random, but destination ports are between 50 to 122 , conveniently fitting in the ASCII range.

Hypothesis - the destination ports is the hidden data.

For log analysis, scapy is indispensible tool when you need to write scripts to proccess data. Although 64 characters can be done by hand, in case the hypothesis is wrong, you can re-run it on other fields ( such as source port). Also scripting is good practice. I will be showing how to do it in Python.

>>> from scapy.all import *
>>> packets = rdpcap('ports.pcap')

First, we import the packet file, then we figure out which field we should take from the packet for output.

>>> packets[1].show()
###[ Ethernet ]###
  dst       = f8:4c:15:6f:bd:be
  src       = f4:5c:89:ad:de:71
  type      = 0x800
###[ IP ]###
     version   = 4
     ihl       = 5
     tos       = 0x0
     len       = 40
     id        = 1
     flags     =
     frag      = 0
     ttl       = 64
     proto     = tcp
     chksum    = 0xec5e
     src       = 10.32.5.175
     dst       = 51.15.75.147
     \options   \
###[ TCP ]###
        sport     = 27167
        dport     = 86
        seq       = 12345
        ack       = 0
        dataofs   = 5
        reserved  = 0
        flags     = S
        window    = 8192
        chksum    = 0x66c3
        urgptr    = 0
        options   = []

Now we have all the information we need to collect all the destination port numbers:

from scapy.all import *
import base64
import os

packets = rdpcap('ports.pcap')
print(packets)
outputstr=""
i=0

while i < len(packets):
    r=str(packets[i][TCP].dport)
    outputstr+=r+" "
    i=i+1
print(outputstr) 

you get this :

81 86 90 76 83 72 116 109 98 72 112 118 89 110 108 109 88 50 53 104 99 86 57 104 97 72 112 118 99 109 86 109 88 50 53 108 99 108 57 122 97 71  █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ 

convert to ascii you get

QVZLSHtmbHpvYnlmX25hcV9haHpvcmVmX25lcl9zaGFfZ2Jf███████████==

”==” is usually the ending of a Base64 string, so we decode that. There are many ways to decode it, just google “base64 decode” and your favorite language/environment or just use online decoder.

echo "QVZLSHtmbHpvYnlmX25hcV9haHpvcmVmX25lcl9zaGFfZ2Jf█████████==" | base64 -d
AVKH{flzobyf_naq_ahzoref_ner_███████████}

Lastly, you have a string that appears to be a caesar shift cipher ( a 13 shift version of it is known as ROT13) decode with ROT13: NIXU{symbols_and_numbers_are_fun██████████}

The more difficult version of the challenge is DNS exfiltration, almost identical to the root-me challenge under the same name.

*In 2017 I managed to deliver 5 flags and score a tour/interview in their awesome Otaniemi offices.