DCTF 2018 Writeup

Sep 24, 2018 15:18 · 916 words · 5 minute read ctf cyber-security write-up

Ransomware (Reverse - 50 pcts.)

Problem

Someone encrypted my homework with this rude script. HELP!

Author: Lucian Nitescu

Solution

There are two files for this challenge: ransomware.pyc and youfool!.exe.

By doing file on both files, we get this:

❯ file ransomware.pyc
ransomware.pyc: DBase 3 data file (1536068111 records)

~/Documents/ctf/2018/dctf/Ransomware
❯ file youfool\!.exe
youfool!.exe: data

So youfool!.exe is apparently encrypted and ransomware.pyc is the only one executable.

By using uncompyle6, we can then decompile the pyc file and get the source code:

# uncompyle6 version 3.2.3
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)
# [GCC 7.3.0]
# Embedded file name: ransomware.py
# Compiled at: 2018-09-04 13:35:11
import string
from random import *
import itertools

def caesar_cipher(buf, password):
    password = password * (len(buf) / len(password) + 1)
    return ('').join((chr(ord(x) ^ ord(y)) for x, y in itertools.izip(buf, password)))


f = open('./FlagDCTF.pdf', 'r')
buf = f.read()
f.close()
allchar = string.ascii_letters + string.punctuation + string.digits
password = ('').join((choice(allchar) for _ in range(60)))
buf = caesar_cipher(buf, password)
f = open('./youfool!.exe', 'w')
buf = f.write(buf)
f.close()
# okay decompiling ransomware.pyc

Just by looking at this code, we can see that youfool!.exe is, in fact, an encrypted pdf file, and the file is encrypted by xoring the original file with a key of 60 characters.

Now we just have to find the 60 characters xor key to decrypt the file since encryption and decryption is the same when it comes to xor.

We can get the first few bytes just by knowing that a pdf file starts with %PDF-1.5. After that, we can using a tool such as xortool or this to find the rest of the key. The result from these tools are not perfect, so I have to manually change a few bytes to make it correct (I know that ? in /DecodePa?ms is a r for sure).

In the end, we get a readable pdf that contains the flag.

Flag: DCTF{d915b5e076215c3efb92e5844ac20d0620d19b15d427e207fae6a3b894f91333}

Exfil (Misc - 330 pcts.)

Problem

An experienced hacker gained unauthorised access into a facility with limited options to exfiltrate data but he managed to launch a backdoor to solve this issue. However, he got arrested before intercepting the confidential data. Can you recover the information and maybe do some profits on his behalf? Flag format: DCTF{[A-Za-z0-9-]+} For this challenge you are allowed to scan using nmap, but it won’t help you too much :)

Target: 104.248.38.191

Author: Andrei A

Solution

For this challenge, we are given a ip with no running services for us to attack, but when you try to ping the server, you get this:

64 bytes from 104.248.38.191: icmp_seq=1 ttl=63 time=0.525 ms
64 bytes from 104.248.38.191: icmp_seq=2 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=3 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=4 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=5 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=6 ttl=63 time=0.595 ms
64 bytes from 104.248.38.191: icmp_seq=7 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=8 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=9 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=10 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=11 ttl=63 time=0.483 ms
64 bytes from 104.248.38.191: icmp_seq=12 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=13 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=14 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=15 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=16 ttl=63 time=0.368 ms
64 bytes from 104.248.38.191: icmp_seq=17 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=18 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=19 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=20 ttl=63 time=401 ms
64 bytes from 104.248.38.191: icmp_seq=21 ttl=63 time=0.408 ms
64 bytes from 104.248.38.191: icmp_seq=22 ttl=63 time=1000 ms
64 bytes from 104.248.38.191: icmp_seq=23 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=24 ttl=63 time=1001 ms
64 bytes from 104.248.38.191: icmp_seq=25 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=26 ttl=63 time=0.623 ms
64 bytes from 104.248.38.191: icmp_seq=27 ttl=63 time=0.478 ms
64 bytes from 104.248.38.191: icmp_seq=28 ttl=63 time=0.474 ms
64 bytes from 104.248.38.191: icmp_seq=29 ttl=63 time=0.480 ms
64 bytes from 104.248.38.191: icmp_seq=30 ttl=63 time=0.489 ms
64 bytes from 104.248.38.191: icmp_seq=31 ttl=63 time=400 ms
64 bytes from 104.248.38.191: icmp_seq=32 ttl=63 time=1000 ms
...

As you can see, the packet delay is following a pattern alternating between 0.5 ms, 400 ms and 1000 ms.

My first attempt is to decode the message as morse code; however, there are patterns that are not valid morse codes.

Later, I discovered that there is a 0.5 ms packet for every four other packets.

Then I just focused on the 400 ms and the 1000 ms packets and converted the list to packets to a binary string which yields the flag.

from pwn import *

# Hard-coded driver function to run the program 
def main(): 
    data = ''
    with open('log3') as f:
      for e in f.read().split('\n'):
        v = float(e.split(' ')[-2].split('=')[-1])
        if v < 300:
          data += ''
        elif v < 600:
          data += '0'
        else:
          data += '1'
    print data.split('     ')

    for e in data.split('     '):
      # result = decrypt(e.strip()) 
      # print (result) 
      result = ''
      for x in e.split(' '):
        if len(x) != 4:
          result += ''
        result += x
      print unbits(result)
      # print result
# Executes the main function 
if __name__ == '__main__': 
    main()

Tip: get a server in the continent where the CTF is hosted to minimized network delays and errors.

Flag: DCTF{EXF1LTRAT3-L1K3-4-PR0-1S-4W3S0M3}

Extra

My team, HATS Singapore, actually made it into the top 10 teams at the last minute, and we are now going to the final in Bucharest, Romania! :)

tweet Share