Hack The Box – DevOops Walkthrough

October 13, 2018


This week’s retiring box is DevOops.  Coming in at a difficulty rating of 4.3/10, it’s not an incredibly hard machine to root, but it does teach some valuable lessons in web application penetration testing and basic Linux privesc enumeration.  Let’s take a look at what a simple “oops” can mean for the bad guy.

Nmap scan:

Starting Nmap 7.70 ( https://nmap.org ) at 2018-09-29 23:24 EDT
Nmap scan report for
Host is up (0.041s latency).

22/tcp   open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 42:90:e3:35:31:8d:8b:86:17:2a:fb:38:90:da:c4:95 (RSA)
|   256 b7:b6:dc:c4:4c:87:9b:75:2a:00:89:83:ed:b2:80:31 (ECDSA)
|_  256 d5:2f:19:53:b2:8e:3a:4b:b3:dd:3c:1f:c0:37:0d:00 (ED25519)

5000/tcp open  http    Gunicorn 19.7.1
|_http-server-header: gunicorn/19.7.1
|_http-title: Site doesn't have a title (text/html; charset=utf-8).

Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.2 - 4.9 (95%), Linux 3.16 (95%), Linux 3.18 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 3.1 (93%), Linux 3.2 (93%), Linux 3.10 - 4.11 (93%), Oracle VM Server 3.4.2 (Linux 4.1) (93%), Linux 3.12 (93%), Linux 3.13 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 22/tcp)
1   39.93 ms
2   39.99 ms

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.55 seconds

So, we only have two ports open here:  SSH on 22 and a web server on 5000.  Given that this is a CTF, my first thoughts are we will likely use the web server to find SSH creds.  It’s almost a standard way of thinking on these lower difficulty machines.  Let’s first check out the web server:


Not a lot of info here.  Just an under construction page with an image for the feed.  I looked into the source of the webpage and investigated around where I could, but found nothing interesting.  Maybe there’s more directories.  Let’s do a dirb and find out:


Nice!  We found an upload page and a feed page.  The feed page is just the image from the home page, which was actually in the source code.  The upload page, however, is intriguing.  I always get excited when I see the word upload.  Let’s check it out:


So, we have the availability to upload an XML file it appears.  Does this ring a bell from your OWASP top 10 studies?  If you said XXE (XML External Entities), you are correct!


If you did not know the answer, I suggest you brush up on XXE here: https://www.owasp.org/index.php/Top_10-2017_A4-XML_External_Entities_(XXE)

In a nutshell, XXE is when we are allowed to upload malicious XML content to a web application.  We can use an XML upload to manipulate a server into giving us sensitive file information.  It looks like the server wants three elements: Author, Subject, and Content.  We can craft an exploit as such:


Since the system is a Linux system, I’ve requested the /etc/passwd file.  This file will allow us to see what users are on the machine.  Here is what came back when we uploaded the XML file to the server:


With passwd files, I like to start from the bottom and work my way up.  That’s typically where the system users are.  There are service accounts and such included in the passwd file that make reading it from top to bottom a much slower process.  From the bottom up, I see two accounts of interest: blogfeed and roosa.  We know we need an SSH private key in order to log in via SSH.  Private keys are typically stored in the /home/username/.ssh/id_rsa file.  I attempted to retrieve a key from both users and one worked.  Here is the payload:


Here is the result:


Dope.  This key looks pretty jacked up.  We’ll need to clean it up and make it pretty.  Here is what it looks like cleaned up:


We can then modify the key permissions with chmod (SSH keys require 600 permission settings) and attempt to connect:


WOOOOO.  We have a shell!  From here, we are able to retrieve the user flag.  The next task is to begin enumeration for privesc.  Among the first things I always check are sudo levels and bash history.  Sudo because you never know what permissions the user has and bash history because there might be some juicy information left behind.  There was nothing in terms of sudo permissions, but history?

roosa@gitter:~$ history 
1 ssh-keygen --help
2 ssh-keygen 
3 ls -altr .ssh/
4 cat .ssh/id_rsa.pub 
5 nano /etc/host
6 nano /etc/hostname 
7 sudo nano /etc/hostname 
8 exit
9 nano .ssh/id_rsa.pub 
10 exit
11 ssh git@localhost
12 exit
13 ssh git@localhost
14 clear
15 apt-get upgrade
16 exit
17 ls -altr
18 mkdir work
19 cd work
20 mkdir blogfeed
21 git init
22 git add .
23 git commit -m 'initial commit'
24 git config --global user.email "[email protected]"
25 git config --global user.name "Roosa Hakkerson"
26 git commit -m 'initial commit'
27 nano README-MD
28 nano README-md
29 nano README.md
30 git add README.md 
31 git commit -m 'initial commit'
32 git remote add origin git@localhost:/srv/git/blogfeed.git
33 git push origin master
34 exit
35 ps -Af
36 kill 27499
37 exit
38 sudo su -
39 exit
40 groups
41 exit
42 git push origin master
43 cd work/blogfeed/
44 git push origin master
45 cd ..
46 cd blogfeed/
47 cd ..
48 git add README.md 
49 git commit -m 'Initial commit'
50 git push
51 git log 
52 ls 
53 mkdir src
54 mkdir resources
55 cd resources
56 mkdir integration
57 mkdir integration/auth_credentials.key
58 nano integration/auth_credentials.key/
59 ls -altr
60 chmod go-rwx authcredentials.key 
61 ls -atlr
62 cd ..
63 ls -altr
64 chmod -R o-rwx .
65 ls -altr
66 ls resources/
67 ls resources/integration/
68 ls -altr resources/
69 ls -altr resources/integration/
70 rm -Rf resources/integration/auth_credentials.key
71 mv resources/authcredentials.key resources/integration/
72 git add resources/integration/authcredentials.key 
73 git commit -m 'add key for feed integration from tnerprise backend'
74 ls -altr resources/integration/
75 git push
76 ssh-keygen
77 ös -altr
78 ls .altr
79 ls -altr
80 cat kak
81 cp kak resources/integration/authcredentials.key 
82 git add resources/integration/authcredentials.key 
83 git commit -m 'reverted accidental commit with proper key'
84 git push

Now, let’s start from the beginning and try to make some sense of what’s happened.  The user is generating ssh keys and making a series of commits to their git repo.  On top of this, they are SSHing in and out of different accounts.  If we follow the story, we see that there is an SSH key that is committed to the git repo.  Later on, there is a revert on that key with the notes “reverted accidental commit with proper key”.  This reads to me like they accidentally used the wrong SSH key when they committed to the repo.  We can take a look at the git log history and see what happened.  The command is git log -p

A little bit of scrolling and we come across the following:


Would you look at that.  It’s a private RSA key.  Surely it’s not root’s:




Wanna chat? Add me on Twitter, YouTube or LinkedIn!
Veteran? Join our Slack!


  • Howdy, as the creator and designer of this machine I thank you for this walkthrough. You took the shortcut to the SSH 🙂

    There is another route which goes through the XXE to read the python source code (the file name was given) and from the source another endpoint can be found and then exploited to gain RCE on the machine. This way to get the SSH key was actually a unintentional side effect because the application is not running properly under an underprivileged account. More developer “oops” because you shouldn’t do that.

    But in the end, I thought that it doesn’t really matter that there different routes to gain access to the machine. Some people will take the harder road and learn some more things about uploading payloads to gain RCE 🙂

    • Hi Lokori,

      Thanks for the kind words. It is nice to hear some background on the box. I’ve heard about the pickle exploit since it retired, but have actually not given it a go. I will need to try that!

      Thanks for developing the box and providing back to the HTB community. It was great fun! 🙂