/Разборы задач
6 ноября 2026
Райтап на задачу «Морзянка на Arduino»
Считываем мигание светодиода на видео и автоматизируем расшифровку азбуки Морзе.5
5

Misc
Задача «Побег с помощью Brainfuck»
А также нам дан файл bf.py. Для начала подключимся по nc к хосту и посмотрим, что он вообще умеет:
Придётся разбираться, раз просто так не хочет отдавать флаг((
Мы видим, что обычные слова он не понимает, но понимает символы. Почему так — потому что теперь мы открываем тот файл, который нам был дан, и начинаем изучать, что в нём написано:
При открытии файла мы видим нашу серверную часть таска, выше написан пример, как работает его главный цикл. Он обрабатывает только символы BF. Если мы посмотрим в самый конец файла, то мы увидим нечто интересное:
Что же это нам даёт? Давайте вообще разберёмся, что тут написано. Сервер принимает нашу первую строку и интерпретирует её как программу BF (Brainfuck — ЯП, который состоит из 8 символов), а результат её работы записывает в переменную code. И тут кроется вся уязвимость — exec(code) позволяет нам выполнять наш пайтон-код (это из-за принципа работы функции exec(). Она позволяет выполнять строку как пайтон-код) и впоследствии прочитать флаг.
Давайте напишем BF-код, который будет читать и сразу же записывать наш пайтон-код — ,[.,]. Ну а теперь немного пояснения:
, (запятая) — даёт нам возможность прочитать символ в текущую ячейку;
[ (квадратная скобка) — пока ячейка не равняется 0;
. (точка) — вывести её;
, (запятая) — читает следующий символ;
] (квадратная скобка) — соответственно, конец нашего цикла.
Теперь мы обошли лимит, и всё написано на чистом BF. Всё, что будет записано после этой строки, уйдёт в exec().
Далее нам нужно написать сам Python-код, чтобы прочитать флаг. Он будет совсем простой, т. к. наш payload исполняется в каталоге скрипта, а рядом лежит flag.txt. Поэтому он будет выглядеть следующим образом: print(open('flag.txt').read()).
НО даже после такого у нас ничего не будет работать, т. к. нам нужно завершить наш цикл, который мы написали ранее. Для этого можно использовать EOT (End of Transmission) — это управляющий символ в кодировке ASCII (его код 0x04). После его отправления наш цикл перестаёт ждать новые входные данные и исполняет наш код)
Я предлагаю написать просто маленький скриптик в одну строчку, чтобы вывести флажок):
{ printf ',[.,]\n'; printf "print(open('flag.txt').read())\n"; printf '\x04'; } | nc 31.207.77.216 4028Теперь мы реализовали RCE и получили заветный флажок, можно радоваться!