$ cat writeup.md…
$ cat writeup.md…
avitoctf
Task: A professor-only exam-answer endpoint requires a three-digit OTP and reCAPTCHA, while student submissions disclose correctness. Solution: Enumerate OTPs through validation-order leakage, recover all answers, then complete CAPTCHA manually.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Вы уже в аккаунте профессора Барсукова (задача Сопромёд: метро). Осталось открыть ответы итогового экзамена и сдать его! Но кнопка «Показать ответы» закрыта дополнительным кодом...
The challenge continues the earlier “Сопромёд: метро” stage. We already have Professor Barsukov's credentials and must reveal the protected final-exam answers, submit a perfect exam, and obtain the current challenge secret.
The credentials recovered in the preceding challenge still work:
prof_barsukov / b4dger_st34ls_h0ney
Login confirms a teacher account with OTP protection enabled. The minified frontend bundle reveals the relevant endpoint and request shape:
GET /api/teacher/tests/1/answers POST /api/teacher/tests/1/answers Content-Type: application/json {"token":"000","captcha":"..."}
The frontend restricts token to three digits. More importantly, the server checks the OTP before validating reCAPTCHA:
000 returns invalid_otp;captcha_required when the CAPTCHA value is absent or invalid.There is no effective rate limit. This creates a 1,000-value brute-force oracle. The flaw is also summarized by the wording of the recovered flag: the OTP check happens before the CAPTCHA check.
The professor dashboard also contained an older flag_note, represented here as avito{REDACTED}. It belonged to the preceding “метро” stage and was not the flag for this challenge.
The CAPTCHA could not be bypassed through ordinary parser tricks, so the exam itself provided another useful route. A newly registered student can call:
POST /api/student/tests/1/submit GET /api/student/submissions/{submission_id}
The submission detail returns is_correct separately for every answer. Since accounts are freely registered, each account provides a one-shot, five-question score oracle.
...
$ grep --similar