Summary
- Noticing the open ports: DNS, Kerberos, LDAP & SMB, we know we’re up against a Windows Domain Controller.
- LDAP Enumeration reveals a base-64 encoded password which was embedded in a unique Active Directory user attribute.
- Decoding the password grants us access to the
r.thompson
user who happens to haveread
access to thedata
SMB share. - Exploring the share, we find a
VNC
-related.reg
file which contains an encrypted password in hexadecimal format. - We also find an e-mail about a deleted user (
TempAdmin
) who has a similar password to the normal (admin) user. - After we crack the VNC password with a tool called
vncpwd
, we gain access to thes.smith
user. - While enumerating SMB access for
s.smith
, we find that he hasread
access to theaudit
share. - The
audit
share contained ansqlite3
database file. When enumerating it, we find an encrypted password for thearksvc
user. - We also find two files
CascAudit.exe
andCasCrypto.dll
which we reverse to find the necessary information to decrypt thearksvc
password. - We authenticate as the
arksvc
user and find that he’s a member of a special group:AD Recycle Bin
. - Combining this information with the e-mail contents, we’re enticed to check the deleted AD users.
- Using PowerShell to fetch the deleted users with all their properties, we find the password for the
Administrator
account in a unique attribute of theTempAdmin
user. We use it to authenticate and we gain full access to the machine.
Nmap
PORT STATE SERVICE VERSION
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: 2022-05-06 11:02:19Z)
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
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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
49170/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:
| smb2-security-mode:
| 2.1:
|_ Message signing enabled and required
| smb2-time:
| date: 2022-05-06T11:03:13
|_ start_date: 2022-05-06T10:54:20
DNS + Kerberos + LDAP + SMB = Domain Controller :D
WinRM = Shell Access maybe :)
From nmap
version detection and scripts:
- OS: Windows Server 2008 R2 SP1
- Domain Name: Cascade.local
- Host name: CASC-DC1
Checkpoint: Listing Possible Enumeration/Exploitation Paths
Having the port data, we go over our game plan:
Down to business: RPC
enum4linux-ng
(https://github.com/cddmp/enum4linux-ng) is a really nice revamp of the old enum4linux
tool.
we run it using the -A
switch as well as -oY
to output into YAML format.
Command:
enum4linux-ng -A 10.10.10.182 -oY e4lng-output
we get a bunch of cool stuff:
- Usernames
- Groups
- Password Policy
This is great! We have a userlist that we can use to do ASREPRoasting and we can do Password Spraying without locking anyone out.
Time Saving #1: ASREPRoasting
To save time, we’re going to do the ASREPRoast first because it’s a quick check and has a high chance of giving us creds (if we crack the hash).
Command:
GetNPUsers.py -dc-ip 10.10.10.182 -request -debug -usersfile users.txt cascade.local/
Note: I generally prefer to use the -debug
flag with everything. It can save me a lot of time in troubleshooting.
We find no accounts that don’t require kerberoes preauthentication.
we also notice some accounts got another type of error: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
. more on those later :)
Time Saving #2: Password Spraying in the background
Since the password policy contained no user lockout, we’re good to go spraying :D
Command:
for i in $(cat /opt/Seclists/Passwords/Common-Credentials/500-worst-passwords.txt); do kerbrute passwordspray --dc 10.10.10.182 -d cascade.local users.txt $i | grep -oP '\[\+\].*'; done
what this does:
it will spray using common passwords and only show us the output if it catches something.
This is mainly to avoid filling up the screen with junk.
Note on the error we get when ASREPRoasting:
Upon spraying, we know that the users that got the KDC_ERR_CLIENT_REVOKED
were in fact locked out.
Another benefit of the verbosity with -v
:)
SMB Enumeration
While we leave our spray running, we’re going to enumerate SMB shares using crackmapexec
Notice that we test with the cascguest
user on the 3rd attempt.
This is because it was there in the enum4linux-ng
output.
LDAP
We’re going to enumerate LDAP and see if we can find something there.
Command:
ldapsearch -x -H ldap://10.10.10.182 -b 'dc=cascade,dc=local'
The output was huge (6k+ lines). So we saved it to ldap-output
we’re going to use a grep
with some Regex Kung Fu to get rid of any unnecessary information.
Regex: ^\w+:
English: Get us any line that starts (^
) with a bunch of characters (\w+
) followed by a semicolon (:
).
We then follow up with a sort
using the -u
flag to get only the signicant attributes.
100 lines is much better XD
While sifting through the attributes, we came across this:
Since it has an =
at the end, we try to decode it using base64 -d
This attribute belonged to the r.thompson
user.
Authentication succeded with it. But we didn’t get code execution with WinRM :/
Kerberoasting
Applying the same strategy as before, we’re going to kerberoast.
No results there.
SMB Access with R.Thompson
We’re going to use a crackmapexec
module called spider_plus
.
It essentially crawls the SMB
share and returns a list of files that we have access to.
Here’s what it found:
In the Data
share, the contents of the Meeting_Notes_June_2018.html
were interesting:
According to the mail, a user called TempAdmin
which has the same password as the normal admin (Administrator
probably) should be deleted at the end of 2018.
We note this down and make sure to be on the lookout for any information regarding that user.
When we look at the ArkAdRecycleBin.log
we get a confirmation that the TempAdmin
user has in fact been deleted.
We find something very intersting in the VNC Install.reg
file:
Cracking VNC Passwords
We’re interested in cracking this VNC password and reusing it.
Luckily, a tool called vncpwd
(https://github.com/jeroennijhof/vncpwd) can easily do that.
we clone the repo using git clone https://github.com/jeroennijhof/vncpwd
and follow up with a make
command to build it.
We then get the hex string, reverse it with xxd
using the -r
and -p
flags and decrypt it.
Password Reuse
Having a new password sT333ve2
, we’re going to to spray it all over the domain users we’ve collected.
As expected, the password belonged to the s.smith
user.
He also has WinRM access :D
The user flag is the only significant thing that we found using his shell access.
Running WinPeas didn’t pick up anything either. So we took a step back to check his SMB access.
Steve’s SMB access: The Audit$
Share
Using crackmapexec
with the --shares
flag, we get the below:
we mount the share with:
mount -t cifs -o 'username=s.smith,password=sT333ve2' //10.10.10.182/Audit$ /mnt
and list the files with:
find /mnt -type f 2>/dev/null
Checking the .bat
file, we find that the executable CascAudit.exe
runs with a database as an argument "\\CASC-DC1\Audit$\DB\Audit.db"
From the SQLite .dll
files, we infer that the .db
file is of that type.
We confirm that with file
:
DB Enumeration
We’re going to use the sqlite3
command-line utility to check out the database contents.
- we list the tables with:
.tables
- we get the schema using
.schema
- we select everything from the
Ldap
table after noticing thepwd
field. - no new data was found in
DeletedUserAudit
table. - same for the
Misc
table as well.
The password we found in the Ldap
table appears to be for the ArkSvc
user.
Decoding it as base-64 gives us strange output. It must be encrypted.
Reversing the CascAudit.exe
and .dll
files
Since the .bat
file showed the CascAudit.exe
processing the Audit database, we’re interested to know how it works.
The same goes for CascCrypto.dll
. Judging by its name, it’s very likely related to the encryption.
Doing a file
command against the CascAudit
files tells us they are built with .Net
Because of an amazing tool called DNSpy
(https://github.com/dnSpy/dnSpy), reversing .Net
is simple.
Opening the CascCrypto.dll
with DNSpy.exe
shows two important functions: EncryptString
and DecryptString
A great deal of information is present regarding the encryption:
- Type: AES
- Block Size: 128-bit
- Key Size: 128-bit
- Initialization Vector (IV):
1tdyjCbY1Ix49842
- Mode: CBC
We need just the key to be able to decrypt the ArkSvc
password found in the DB. Or so we hope :D
We find the it in the .exe
code
it’s “c4scadek3y654321”
Looking at the code, it seems that the .exe
reads the encrypted password from the database and decrypts it using the DecryptString
function before moving on to carry out its tasks.
AES-CBC-128 Decryption
Adding the details we found into an online decryption tool (https://www.devglan.com/online-tools/aes-encryption-decryption), we get the plaintext: w3lc0meFr31nd
ArkSvc and the AD Recycle Bin
The user ArkSvc
authenticates successfully with the w3lc0meFr31nd
password and also has WinRM
access.
While doing some basic privesc checks, we notice that the group membership of this user is unique:
s.smith
didn’t have this access.
The Recycle Bin of Active Directory is important in our case because it contains the TempAdmin
user.
We don’t know his password yet. But it might be similar to any of the ones we found.
We try restoring him using PowerShell
The command has 3 parts:
- Fetching all deleted objects:
Get-ADObject -ldapFilter:"(msDS-LastKnownRDN=*)" -IncludeDeletedObjects
- Selecting the last one (TempAdmin):
Select -Last 1
- Restoring It:
Restore-ADObject
But that fails :/
I scratch my head for a while…
But eventually get the idea of checking all the attributes for the TempAdmin
user.
Just in case his password was in one of them. Just like the r.thompson
user or something.
Command:
Get-ADObject -ldapFilter:"(msDS-LastKnownRDN=*)" -IncludeDeletedObjects -Properties * | Select -Last 1
Son of a … It was indeed the case XD
And of course, it was base-64 encoded.
We decode it and try it with the Administrator
user as mentioned in the email:
Username is TempAdmin (password is the same as the normal admin account password)
And we finally own the box after following all those breadcrumbs XD