Every year, DarkLab organises a Capture the Flag cybersecurity competition designed for undergraduate students aiming to raise the competency level of future talents to better prepare them for a meaningful career in cybersecurity.
HackaDay 2020 was held on 2 December 2020, and saw the Open University of Hong Kong’s YH team crowned as winning team, and the Hong Kong University of Science and Technology’s Machine Brickers as runners up.
The theme this year was “Security the Basics”, based on the experience and real life challenges that organisations in Hong Kong have faced in 2020 – as observed by our own Red Team and Incident Response professionals.
In this series of three blog posts, we want to provide the solution to the different challenges students faced. We hope that this will stimulate even more students to get their hands on the keyboard next year!
Web Challenge – With great power comes great responsibility!
Hackaday Chat System 1 (100 pts, 4 solves)
This challenge is meant to exploit the broken access controls of a website. After registering and login with an account, you will notice that there are several accounts created (i.e. operator_day1, admin_day1, admin_day2) from the “Select User” drop-down list. The account operator_day1 will be our target for this challenge.
The key element is the user’s UUID form in the user profile page. The user’s UUID for this system is crafted from MD5 hash of the user email. Using an md5 generator, we are able access the profile page of operator_day1 by entering /profile.php?uuid=14a7a7da8dfcba61a4af2b695a553cf0.
Inside operator_day1 profile page, we can retrieve the password SHA256 hash of the user. Using an online hash cracking site, we are able to recover the plaintext password of the operator’s account.
After logging in with the operator account, the flag will be displayed at the chat box.
Hackaday Chat System 2 (150 pts, 1 solve)
This challenge is an extension of the Chat System 1. This time, the account admin_day1 will be our target.
In the operator_day1’s profile, a new endpoint – updateUser.php – is available to update username or password. However, after clicking the button, an error message is prompted saying the naming function is in maintenance.
Using a web proxy tool, we can change the “from” data of the request to delete the name changing parameter. As the endpoint is also vulnerable to parameter injection, adding a new data field “role” would grant us the role of the user.
Here we crafted a request to change the role of operator_day1 to administrator, which is same as the role of admin_day1.
With administrator privileges, we can now change the password of admin_day1 to another one of our choice. (Note that UUID in the request is the one from the admin_day1 account)
After logging in to the system with admin_day1 account, we can retrieve the flag in the chat box.
OTP Member Portal (150 pts, 0 solves)
Description: Multi-factor authentication (MFA) is an electronic authentication method in which user is granted access to a website or application only after successfully presenting two or more pieces of evidence (or factors) to an authentication mechanism: knowledge (something only the user knows), possession (something only the user has), and inherence (something only the user is) – SUPER SAFE!
This challenge aims to bypass the password login process and brute force weak a MFA system.
Once you register an account in the system and complete a normal login process, you can notice that:
- You would need an account from Hackaday Chat System in order to receive OTP
- The OTP is 3-digit code from 100-999
- Account will be locked after 5 incorrect OTP login attempts
- You can send request to reset the fail counts and the OTP
- The target account of this challenge is firstname.lastname@example.org
- Exploiting the target account in Hackaday Chat System would not work since admins will not receive OTP from chat system
- The normal login process is represented in the below graph
The point of exploitation is from the password login. Due to broken access control, after the “password incorrect” message is prompted, we can still access the OTP login page directly with the target account information embedded in the PHP session.
You could therefore write a script to exploit the system by bruteforcing the OTP system:
- Login on the account email@example.com with random password
- After seeing the “password incorrect” message, directly access /OTPlogin.php
- Brute force the OTP at maximum 4 times
- Submit request to resend OTP if all attempts failed
- Repeat step 3 and 4 until the OTP login is successful
- Access member.php with the same PHP session
A sample program written in Go (otp-sample.go) is provided for reference.
After finishing the above steps, the flag will be displayed at profile.php.
OTP Admin Portal (100 pts, 0 solves)
This challenge aims to exploit the file uploading feature in the system. We are allowed to upload any files to the system with the only limitation being on file size. After uploading a .htaccess file with directory listing enabled (‘Options +Indexes’), we can find the flag with the link provided.
Simple Message Board (250 pts, 3 solves)
Description: I found a message board online and seems that there is a secret hiding which can be only access by the admin. Do you know how to get the secret?
This challenge is aimed at exploiting the message board system with Cross-site scripting (XSS) and/ or Cross-Site Request Forgery (CSRF).
In the message board system, we are given three functions: one for posting a message to the board, one for clearing the log, and one for getting the flag.
It is observed that:
- Someone (likely the admin) is frequently accessing the board and clearing logs
- Both name and message fields are vulnerable to XSS
- There is a hidden field (csrf_token) in the “Get Flag” form
- There are PHP session ID and a field named “Admin” in the cookie, changing the value of “Admin” field to “Admin” will not work also
The target of this challenge is to force admin to somehow click the “Get Flag” function or steal the session (cookies) from the admin.
To solve the challenge, we could write a script to force admin to access the “Get Flag” function:
var xhr = new XMLHttpRequest();
xhr.send("csrf_token=" + document.querySelector("input[name=csrf_token]").value);
The script will do the following procedures:
- Query the value of csrf_token in the page
- Send a form request to getflag.php to trigger the function
As there may be situations that the script run without csrf_token properly loaded, some time delay (such as using settimeout, onerror etc.) is required such that the script would be executed successfully on the admin side.
After sending the script to the board and wait for a second, the flag will be shown on the board.
To tackle the challenge, we could setup a listener (e.g. pastebin) for receiving http request and send the following script to the message board:
By using this script, if admin accessed the message board, a HTTP GET request will be sent to our requestbin service with all cookies logged.
After a short waiting, we will receive the above request with the information we need.
With the cookies of the admin account, we can now get the flag by clicking the “Get Flag” button.
Stay tuned for the second part of this blog series: Cloud challenge.