Orbital is a web challenge featuring a web application susceptible to SQL injection. After utilizing SQLi to bypass login as the admin
user, an LFI vulnerability that arises from the incorrect validation of filenames can be exploited to reveal the flag.
Starting the docker instance and visiting the IP brought up a login page:
Viewing entrypoint.sh
within the provided project code showed that there was an admin
user.
Within database.py
, the login
function directly passes the username in a SQL query without proper input validation, making it vulnerable to SQLi:
passwordVerify
shown below in util.py
is a function that converts the plaintext password inputted on the login page into an MD5 hash, then compares the generated hash to the MD5 hashed password stored in the database:
I attempted to login using the following SQL injection which leverages the md5
function within passwordVerify
to bypass login as admin
:
" -1 UNION SELECT "admin", md5("1234") AS password FROM users #-- -
When the statement gets executed by the server, the UNION SELECT
statement will concatenate the SQLi onto the original query and temporarily add a new row to the query's result set and return a record where the username is admin
and the password hash matches the MD5 hash of 1234
.
Therefore, when the password verification check in the login
function is called, it will return True
as long as the password field matches the MD5 hash of 1234
. This will result in a successful login as the admin
user by injecting a SQL query that retrieves the MD5 hash of a known password for that particular login attempt.
Based on database.py
, the server will read this statement as:
SELECT username, password FROM users WHERE username = "" -1 UNION SELECT "admin", md5("1234") AS password FROM users #-- -
username: " -1 UNION SELECT "admin", md5("1234") AS password FROM users #-- -
password: 1234
The SQLi worked and I successfully logged in as the admin
user.
The admin
user dashboard page didn't contain anything useful. But, intercepting the response for the successful login in Burp Suite provided the session cookie which could be used to make further requests as an authenticated user.
The code shown below for routes.py
has a local file inclusion vulnerability in the /export
route due to the way the communicationName
parameter in the JSON request is being passed directly within the send_file()
function to construct a file path on the server and retrieve the contents without any validation or sanitization.
Using the session cookie of the authenticated admin
user, I sent the following payload which traverses up one level of the file system to view the contents of the /etc/passwd
file:
{
"name":"../etc/passwd"
}
The flag was located in /signal_sleuth_firmware
:
I sent the following payload to reveal the flag:
{
"name":"../signal_sleuth_firmware"
}