# SEC-T CTF 2018 - Writeup

It's been about two years since I last joined in a CTF. I participated in SEC-T CTF 2018 as a member of 'insecure.' I solved 7 challanges and got 357 point in total.

# Sanity check [Misc 51pts]

Flag is in the topic of #sect-ctf @ irc.freenode.net

The flag is written on the IRC.

# Ez dos [Rev 51pts]

They told me you were old-school, great! Have a look at this license-server as a warm-up
Service: nc 142.93.38.98 7777 | nc rev.sect.ctf.rocks 7777

The file contains 'ezdos.com' and it's an executable for MS-DOS.

$file ezdos.com ezdos.com: COM executable for MS-DOS Let's disassemble it. $ objdump -D -b binary -M intel -mi386 -Maddr16,data16 ezdos.com > disasm

As I looked over the assembly, I found it reads a file named 'flag' and shows its contents when the license key is correct. The following part is where we enter the license key.

   c:   b9 00 00                mov    cx,0x0
f:   bb 00 20                mov    bx,0x2000
12:   ba 0d 00                mov    dx,0xd
15:   b4 01                   mov    ah,0x1
17:   cd 21                   int    0x21
19:   3c 0a                   cmp    al,0xa
1b:   74 08                   je     0x25
1d:   88 07                   mov    BYTE PTR [bx],al
1f:   43                      inc    bx
20:   41                      inc    cx
21:   39 d1                   cmp    cx,dx
23:   75 f0                   jne    0x15

The license key we enter is stored at 0x2000.

  25:   b9 00 00                mov    cx,0x0
28:   bb 00 20                mov    bx,0x2000
2b:   b8 6b 02                mov    ax,0x26b
2e:   ba 04 00                mov    dx,0x4
31:   51                      push   cx
32:   31 c9                   xor    cx,cx
34:   8a 0f                   mov    cl,BYTE PTR [bx]
36:   93                      xchg   bx,ax
37:   8a 2f                   mov    ch,BYTE PTR [bx]
39:   93                      xchg   bx,ax
3a:   38 e9                   cmp    cl,ch
3c:   0f 85 87 00             jne    0xc7
40:   59                      pop    cx
41:   41                      inc    cx
42:   43                      inc    bx
43:   40                      inc    ax
44:   39 d1                   cmp    cx,dx
46:   75 e9                   jne    0x31

The address of the license key is loaded into BX and the value 0x26b is stored into AX. AX(0x26b) points to the data '1337SHELL'. This part is a loop and it compares the first 4 characters of the license key with '1337', so the license key begins with '1337'. And then, it checks whether the next character is '-' as shown below.

  48:   31 d2                   xor    dx,dx
4a:   8a 17                   mov    dl,BYTE PTR [bx]
4c:   80 fa 2d                cmp    dl,0x2d
4f:   75 76                   jne    0xc7

After checking '1337-', it checks the rest of the key character by character. The next character of the key and the data('S') is loaded into CL and CH respectively and compares CLCH with 0x66, which means the correct character is 'S'^0x66='5'.

  51:   43                      inc    bx
52:   31 c9                   xor    cx,cx
54:   8a 0f                   mov    cl,BYTE PTR [bx]
56:   93                      xchg   bx,ax
57:   8a 2f                   mov    ch,BYTE PTR [bx]
59:   93                      xchg   bx,ax
5a:   30 e9                   xor    cl,ch
5c:   80 f9 66                cmp    cl,0x66
5f:   75 66                   jne    0xc7

By restoring the rest of the key in the same way, I found the correct key is '1337-5115'. Connecting to the server with nc and entering the key, I got the flag.

# Matry0ska1 [Crypto 51pts]

Discrete logarithms are hard...
nc 178.128.171.133 4444 | nc crypto.sect.ctf.rocks 4444

The server tells a message like this:

    _
(("))  --- Gimme exponent pl0x
/   \
( (@) )
\__(__/

p = 122488473105892538559311426995019720049507640328167439356838797108079051563759027212419257414247
g = 2
g^x = 49865908605708412727604941701889315223850522668539772014048529597300749129536778697051808702829
:

What we have to do is find such that when and are given. The number [tex:gx] is variable but is fixed. can be factorized by using wolfram alpha. This means the discrete logarithm problem can be solved by applying the Pollard's rho algorithm for logarithms and the Pohlig-Hellman algorithm. However, I used the following service which solves the discrete logarithm problem.

It took a few tens of seconds to solve the problem. Sending the answer returned the flag.

# Section6 [Misc 51pts]

This file was recovered from a scavenger.

The given file contains a zip file. I guessed it's a word document since it has some directories such as Documents or _rels. Though I tried to open it with Libre Office, the document seemed broken. The contents of a word document basically exist in the Document directory. I found a file Documents/6/Pages/6.fpage which contains the text data. Since the text goes for several lines, I wrote a simple Python code which formats the text data.

import re

out = ""
with open("6.fpage", "r") as f:
for line in f:
found = re.findall("UnicodeString\=\"(.+)\"", line)
if found:
text = found[0]
print text


This program gave me the flag in ASCII art.

# Puppetmatryoshka [Misc 51pts]

Greetings Kusanagi, your mission is to find Puppet Master.

The given archive has a pcap file named matryoshka.

$file matryoshka matryoshka: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 262144) I found TCP packets in which contains a file compressed by bzip2. I extracted and decompressed it, which created a disk dump. $ file extracted
extracted: Linux rev 1.0 ext4 filesystem data, UUID=b72f5197-d45b-4079-b6e8-b9d1be583d67 (extents) (huge files)

There are some empty files and a 7-zip archive. I decompressed the archive and got an ASCII text file that seemed base64-encoded. Exhausting. Decoding the text made an Open Document file. Here is what is written in it:

Kusanagi, well done so far.

Try not to get compromized, we know he sometimes change metadata to cover his traces. Look for sign.

No flag here? It indicates the metadata, especially the signature is the key. I looked into META-INF/documentsignatures.xml and found the flag finally.

# Shredder [Misc 51pts]

We intercepted this floppy we believe belonged to the laughing man. We haven't found anything other than this shredder tool though.

The file floppy is a disk dump of FAT filesystem.

$file floppy floppy: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", root entries 112, sectors 2880 (volumes <=32 MB), sectors/FAT 9, sectors/track 18, serial number 0xb4d31337, unlabeled, FAT (12 bit), followed by FAT I mounted the disk and found a 64-bit ELF named shredder. Analysing the binary with using IDA reveals how it works. 1. Open and read a file 2. Generate a random byte as a key 3. XOR the whole file byte by byte with the key 4. Repeat step 2 and 3 for several times (It depends on the argument) No matter how many times it XORs the file, it's easy to recover the original one because we just have to try 255 keys. However, the problem is we don't have the XORed file because it deletes the file before exiting. Deleting a file on FAT filesystem means just changing some bits on the disk so the file itself is not deleted. The given disk image is so small that we can easily find the deleted file. (The deleted file is located at 0x8800.) I wrote a Python code which tries to recover the file. with open("floppy", "rb") as f: buf = f.read()[0x8800:] buf = buf[:buf.index("\x00\x00\x00\x00")] print repr(buf) for key in range(0x100): out = "" for c in buf: out += chr(ord(c) ^ key) print out  As I looked over the output, I found the flag when the XOR key is 108. # Batou [Misc 51pts] We manage to collect a dump from Batou's computer. Try to find info/notes that can help us Download: batou.tar.gz The file batou is a vmss image because the file begins with "d2 be d2 be 08." Let's use volatility to analyse this memory dump. At first, we have to determine the profile. imageinfo tells us the profile. $ vol.py -f batou imageinfo
INFO    : volatility.debug    : Determining profile based on KDBG search...
Suggested Profile(s) : Win7SP1x64, Win7SP0x64, Win2008R2SP0x64, Win2008R2SP1x64_24000, Win2008R2SP1x64_23418, Win2008R2SP1x64, Win7SP1x64_24000, Win7SP1x64_23418
AS Layer1 : WindowsAMD64PagedMemory (Kernel AS)
AS Layer2 : VMWareAddressSpace (Unnamed AS)
PAE type : No PAE
DTB : 0x187000L
KDBG : 0xf800028480a0L
Number of Processors : 2
Image Type (Service Pack) : 1
KPCR for CPU 0 : 0xfffff80002849d00L
KPCR for CPU 1 : 0xfffff880009ea000L
KUSER_SHARED_DATA : 0xfffff78000000000L
Image date and time : 2018-09-11 04:17:17 UTC+0000
Image local date and time : 2018-09-10 21:17:17 -0700

The process list can be obtained by psscan.

$vol.py -f batou --profile=Win7SP1x64 psscan Offset(P) Name PID PPID PDB Time created Time exited ------------------ ---------------- ------ ------ ------------------ ------------------------------ ------------------------------ 0x000000003de683c0 dwm.exe 1660 792 0x0000000014479000 2018-09-11 04:16:05 UTC+0000 0x000000003de72b30 explorer.exe 1720 1652 0x00000000154e2000 2018-09-11 04:16:05 UTC+0000 0x000000003df57b30 SearchProtocol 1040 1988 0x000000000d026000 2018-09-11 04:16:13 UTC+0000 0x000000003df77b30 SearchFilterHo 1140 1988 0x000000000d92f000 2018-09-11 04:16:13 UTC+0000 0x000000003df9f100 SearchProtocol 1340 1988 0x00000000106ca000 2018-09-11 04:16:13 UTC+0000 0x000000003dfaf4a0 iexplore.exe 1536 1720 0x000000000c130000 2018-09-11 04:16:15 UTC+0000 0x000000003dfe54f0 iexplore.exe 1636 1536 0x000000000be44000 2018-09-11 04:16:17 UTC+0000 0x000000003dfef570 StikyNot.exe 1872 1720 0x0000000006f04000 2018-09-11 04:16:20 UTC+0000 0x000000003e08d3a0 taskhost.exe 1728 460 0x0000000014187000 2018-09-11 04:16:05 UTC+0000 0x000000003e1da210 notepad.exe 204 1720 0x0000000028c02000 2018-09-11 04:16:31 UTC+0000 0x000000003e22bb30 svchost.exe 748 460 0x000000001ba0c000 2018-09-11 04:15:34 UTC+0000 0x000000003e23eb30 svchost.exe 792 460 0x000000001b619000 2018-09-11 04:15:34 UTC+0000 0x000000003e264890 svchost.exe 820 460 0x000000001b31f000 2018-09-11 04:15:34 UTC+0000 0x000000003e2b32a0 svchost.exe 944 460 0x000000001bf2a000 2018-09-11 04:15:35 UTC+0000 0x000000003e2eb890 svchost.exe 212 460 0x000000001bb38000 2018-09-11 04:15:35 UTC+0000 0x000000003e367b30 spoolsv.exe 300 460 0x000000001b064000 2018-09-11 04:15:35 UTC+0000 0x000000003e379b30 svchost.exe 968 460 0x000000001b8c6000 2018-09-11 04:15:36 UTC+0000 0x000000003e4de060 csrss.exe 316 308 0x000000002004a000 2018-09-11 04:15:32 UTC+0000 0x000000003e4f0b30 lsass.exe 468 372 0x000000001ea74000 2018-09-11 04:15:33 UTC+0000 0x000000003e5062b0 wininit.exe 372 308 0x000000001fc50000 2018-09-11 04:15:33 UTC+0000 0x000000003e510a00 winlogon.exe 400 356 0x000000001f19d000 2018-09-11 04:15:33 UTC+0000 0x000000003e551060 services.exe 460 372 0x000000001eb54000 2018-09-11 04:15:33 UTC+0000 0x000000003e55bb30 lsm.exe 476 372 0x000000001f47c000 2018-09-11 04:15:33 UTC+0000 0x000000003e5b7b30 svchost.exe 584 460 0x000000001e7c5000 2018-09-11 04:15:34 UTC+0000 0x000000003e612b30 svchost.exe 664 460 0x000000001b903000 2018-09-11 04:15:34 UTC+0000 0x000000003edbe2d0 SearchIndexer. 1988 460 0x000000000fe67000 2018-09-11 04:16:12 UTC+0000 0x000000003f41c750 smss.exe 232 4 0x0000000025ac0000 2018-09-11 04:15:30 UTC+0000 0x000000003febdb30 notepad++.exe 1568 1720 0x0000000005f4c000 2018-09-11 04:16:39 UTC+0000 2018-09-11 04:16:48 UTC+0000 0x000000003ffbdae0 System 4 0 0x0000000000187000 2018-09-11 04:15:30 UTC+0000 0x000000003ffc65f0 csrss.exe 364 356 0x000000001fb97000 2018-09-11 04:15:33 UTC+0000  As you can see from the list, notepad++ had terminated. I tried to dump the process but it didn't work. Maybe the flag is written to the disk by notepad++. filescan is useful when we want to survey the files. $ vol.py -f batou --profile=Win7SP1x64 filescan > filelist

I looked over the list and found curious lines in which notepad++ makes some backup files.

...
0x000000003fe9c930     16      0 R--rw- \Device\HarddiskVolume2\Users\Batou\AppData\Roaming\Notepad++\backup\new 2@2018-09-10_203737
0x000000003feacbc0      3      0 R--r-d \Device\HarddiskVolume2\Windows\SysWOW64\WindowsCodecs.dll
...
Those files can be dumped by dumpfile. The extracted file has the flag in hex :-)
$vol.py -f batou --profile=Win7SP1x64 dumpfiles --dump-dir="./" -Q 0x000000003fe9c930$ cat file.None.0xfffffa8000da35c0.dat
34 6c 6c 5f 79 6f 75 72 5f 4e 30 74 33 73 5f 34 72 33 5f 62 33 6c 30 6e 67 5f 74 30 5f 75 35