$ cat writeup.md…
$ cat writeup.md…
avitoctf
Task: A localhost vsftpd service authenticates through a custom PAM module using TOTP and per-user counters. Solution: Overwrite the loaded TOTP secret, then use a signed out-of-bounds counter increment to mutate an enrolled username into admin.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Разведка медоедов обнаружила забытый служебный леток в Бюро пропусков. Через него пчёлы до сих пор обмениваются накладными по старому FTP, а после последних набегов прикрутили к шлюзу PAM и одноразовые коды. Каждый вход попадает в журнал посещений. За проходной находится закрытая администраторская сота с маршрутами медовых караванов. Помоги медоеду сойти за пчелу, получить пропуск и пробраться внутрь улья.
Initial SSH access as pamgate opened an interactive player shell inside the challenge container. The objective was to pass the custom PAM authentication used by the local FTP service and reach the administrator-only FTP root. No SSH password is needed by the exploit and none is reproduced here.
The relevant service was vsftpd listening on 127.0.0.1:30029. Its PAM stack loaded the supplied native module pam_pamgate.so. The initial user store contained:
guest:0:NBSWY3DPEHPK3PXQ
Authentication had two modes:
enroll, the module created a record, FTP directory, random Base32 secret, totp.txt, and stats.txt.Names were limited to 1–32 alphanumeric, underscore, or hyphen characters. The exact names admin and guest were reserved. Consequently, path traversal and direct administrator enrollment were unavailable.
The module SHA-256 was 537252fb4211dc37df239139e79e1cac58577d5e88a291d7b49f3e1331b1258c. Important recovered routines included pam_sm_authenticate at offset 0x195e, the TOTP routine at 0x1d40, name validation at 0x1ef9, record lookup at 0x2301, and enrollment at 0x2525.
Each parsed store record had this layout:
struct record { char name[34]; int16_t id; char secret[17]; };
The TOTP implementation was standard HMAC-SHA1 with a 30-second counter, dynamic truncation, and reduction modulo 1,000,000. It accepted only the current time step.
Two memory-safety errors combined into the exploit:
...
$ grep --similar