22 октября в нашем офисе прошел очередной Security Meetup. На встрече было пять докладов, посвященных различным уязвимостям. Были раскрыты такие вопросы, как реверс-инжиниринг в Enterprise и связанные с ним бизнес-процессы (на примере платежной системы Qiwi), небезопасная десериализация данных в PHP, степень надежности двухфакторной аутентификации в мобильных приложениях, работа за деньги на bug bounty, а также возможность атаки с помощью «опасного» видеофайла.
Презентации спикеров:
«Опасное видео». Максим Андреев, Облако Mail.Ru.
Максим Андреев, программист команды Облака Mail.Ru, сделал доклад о том, как с помощью специально подготовленного видеофайла осуществить SSRF-атаку, и рассказал, как даже без запуска и просмотра «опасное видео» позволяет деанонимизировать отдельных пользователей и красть файлы с их компьютеров.
Видео выступления.
«Реверс-инжиниринг в Enterprise». Александр Секретов, Qiwi.
Александр Секретов – эксперт по информационной безопасности Qiwi. Он рассказал о бизнес-процессах, связанных с реверс-инжинирингом в enterprise, а также о том, как опыт анализа приложений позволяет повысить уровень безопасности инфраструктуры и приложений.
Видео выступления.
«When big brick wall becomes wooden fence» or «how to get 1kk on the Bug Bounty». Кирилл Ермаков, Qiwi.
Кирилл Ермаков, CISO группы компаний QIWI, рассказал о типичных ошибках, которые делают люди, мечтающие заработать миллион на bug bounty, и показал несколько интересных находок на примере популярных интернет-сервисов.
Видео выступления.
«Мобилки, деньги, два фактора». Дмитрий Евдокимов, DigitalSecurity.
Дмитрий Евдокимов, директор исследовательского центра компании DigitalSecurity, говорил о двухфакторной аутентификации, используемой, в том числе, и в мобильных приложениях.
Видео выступления.
«PHP Unserialize Exploiting». Павел Топорков, Лаборатория Касперского.
Павел Топорков из Лаборатории Касперского выступил с докладом о том, как эксплуатировать небезопасную десериализацию данных в PHP, и о том, что именно помогает использовать данную уязвимость в реальных условиях.
Видео выступления.
Фотографии с митапа смотрите по ссылке.
ValdikSS
«Опасное видео» — просто пушка. Я даже подумать не мог, что кто-то может вызывать ffmpeg в серьезных проектах напрямую, я не использовать libavcodec, libavformat и прочие библиотеки. Мой мир серьезных программистов, которые думают о последствиях, опять перевернулся.
cdump
А что в этом плохого, зачем для такой задачи писать/отлаживать/поддерживать из библиотек свой велосипед (причем совсем не простой, когда нужно сделать конфигурируемыми пару десятков параметров), если утилита ffmpeg с этим прекрасно справляется?
Другое дело, что почему-то некоторые сервисы не задумались о запуске ffmpeg в песочнице с урезанием всего, что явно не нужно (хотя бы доступа в сеть).
И я вообще не уверен, что использование библиотек вместо утилиты ffmpeg тут бы помогло, утилита ведь точно так же использует эти самые библиотеки, в которых точно так же могут быть уязвимости. Если говорить про пример с m3u8, то делать черный список форматов, которые не конвертировать — плохая идея, можно что-то не учесть, аналогично и с белым списком — не учтешь особенностей каждого из нескольких сотен вариантов, может где-то есть неявная возможность обращения к сети например.
На мой взгляд, именно изолированние любой обработки пользовательских данных — это то решение, которое необходимо *в первую очередь*, которое, кстати, помогло бы в данном случае.
ValdikSS
cdump
как раз наоборот — требуется довольно много настроек кодека + цепочка фильтров в нужном порядке со своими настройками + другие различные опции, и все это очень легко задается опциями утилиты ffmpeg.
Пример с system('sleep 10') лучше заменить на Конечно, и для моего примера использовать system() это не хорошо и не стоит так делать в большинстве случаев, но думаю мысль понятна.
Кстати, мне встречались биндинги для некоторых языков именно к утилите ffmpeg — т.е. идея запускать бинарник ffmpeg вместо использования библиотек именно в случае FFmpeg довольно распространена.
ValdikSS
Так и картинки вызовом imagemagick конвертируют, но что в этом хорошего-то?
cdump
Зачем, какие будут плюсы именно в задаче конвертирования видео?
Про некоторые минусы я уже говорил выше — время на написание/тестирование/поддержку, хотя по сути это будет копипаст бОльшей части ffmpeg.c. Затраты на fork()+exec() пренебрежимо малы со временем работы процесса конвертации.
Несколько плюсов модели «запуск отдельного процесса на каждую конвертацию»:
— конвертация не может повлиять на враппер — демон, который принимает решение о необходимости запуска процесса конвертации конкретного файла с конкретными параметрами
— возможность запуска из под отдельного пользователя, с более урезанными чем «демон-враппер» правами
— удобное управление лимитами — память, максимальное время работы (считаем, что в библиотеках могут быть баги)
Если согласиться с тем, что для конвертации все же лучше запускать отдельный процесс — то так ли важно, будет ли это ffmpeg или самописнная утилита на основе тех же самых библиотек?
И да, интерфейс у библиотек не сильно высокоуровневый, т.е. там нет функции
convert(const char *infile, const char *outfile, struct convert_params *params)
, а возможности, которые они за счет этого предоставляют (помимо тех, что есть в утилите ffmpeg) в задаче конвертирования не нужны.И по теме выступления — использование библиотек FFmpeg вместо утилиты ведь не должно спасти от такой аттаки, или есть мнение что должно?
ValdikSS
С библиотеками проще обрабатывать ошибки, вам не нужно парсить вывод в stderr, вы можете это сразу попробовать починить, не запуская процесс перекодировки с самого начала. С точки зрения безопасности, одинакового уровня безопасности можно достичь и с бинарником ffmpeg, либо вручную фильтруя фильтры и протоколы, либо скомпилировав ffmpeg самостоятельно, выкинув все ненужное и потенциально опасное, но, по моему мнению, вызывать бинарники, когда есть байндинги, да еще и не в собственном маленьком проекте, которым пользуется только автор, а в такой крупной компании, где следят за качеством кода, просто как-то неправильно. ffmpeg это не gstreamer, где практически нет вменяемых сообщений об ошибках, и хрен поймешь, почему pipeline не стартует, так что запуск бинарника нельзя оправдать плохим API.
cdump
см. мой комментарий выше:
Важно просто знать, успешной была конвертация или нет + была ли она прервана по таймауту или раньше.
Как может помочь выполнить конвертацию знание, что например файл начиная с 2млн байта полностью битый — я не понял.
Извините, но я пока не увидел ни одного довода, который смог бы меня убедить в утверждении «запускать бинарник ffmpeg для решения конкретной данной задачи — не правильно, а вот написать свой бинарник используя те же библиотеки и запускать его — лучше».
Для меня пока это выглядит как «не использовать goto в C, потому что это не правильно — ведь все же так говорят».
ValdikSS
Я не говорю, что это неправильно, это допустимо, и, видимо, в некоторых случаях это вполне приемлемо, но вам, вероятно, все же не приходилось сталкиваться с задачами, которые через бинарник решить можно, но через свои обращения к библиотеками решить проще и быстрее.
Скажем, загрузили на сервис перекодирования какой-нибудь vob или mpg, у которого звук начинается мегабайта с сотого, а ffmpeg не анализирует так много с начала файла по умолчанию. Вот, ffmpeg определил, что у нас в файле только видео, без звука, начинает кодировать видео, а потом выясняется, что у нас тут еще и звук есть. Все, бинарник не может ничего с ним сделать. Придется либо останавливать процесс кодирования, выбрасывая уже скодированное видео и запуская ffmpeg заново с увеличенными параметрами analyzeduration, либо дождаться кодирования видео, скодировать отдельно аудио и домуксовать в контейнер. Не знаю, насколько распространена загрузка mpg на видеосервис, наверное, вообще не распространена, но мне с таким приходилось сталкиваться не раз и не два. С использованием прямых вызовов libav проблему решить проще, можно, например, сразу закрыть тот файл, куда записывалось видео, скопировать получившийся битстрим в новый файл и продолжить с момента останова.
Или, например, загрузили файл с VFR. С «правильным» VFR, у которого каждую секунду разный фреймрейт. Как вы заранее определите, нужно ли вам копировать pts исходного файла, или нужно свои генерировать? Или вы убъете VFR и приведете файл к какому-то наиболее близкому constant framerate?
ValdikSS
valievkarim
libavcodec и ко — это не «ffmpeg в виде либы», это другой уровень абстракции.
Вот примеры кодирования видео с этими либами:
www.ffmpeg.org/doxygen/0.6/api-example_8c-source.html
ffmpeg.org/doxygen/trunk/doc_2examples_2decoding_encoding_8c-example.html
Вы действительно считаете, что такой кусок кода в проекте будет смотреться лучше вызова ffmpeg? :)
ValdikSS
Там нет ничего страшного, большую часть кода занимают комментарии, fopen и его проверки, malloc, сами посмотрите. Самих вызовов библиотек там буквально несколько, и все они понятны и просты.
valievkarim
Ок, так Вы считаете, что вот такой цикл по кадрам видео-дорожки будет в проекте смотреться лучше, чем вызов ffmpeg?
ValdikSS
Вы посмотрите ниже, для чего это. Это пример генерации своей собственной картинки для кодирования, поэтому так подробно и расписано.
Вот, посмотрите свежий пример использования Intel Quick Sync для декодирования:
ffmpeg.org/doxygen/2.8/qsvdec_8c-example.html
В нем используется функция avcodec_decode_video2, которая делает всю основную работу сама.
valievkarim
Что эта функция делает сама? Декодит один кадр?
Это точно будет смотреться в проекте лучше, чем вызов ffmpeg? :)
ValdikSS
Да, я уверен, для серьезных проектов, вроде сервиса заливки видео, это точно будет смотреться лучше, чем вызов бинарника.
valievkarim
Тут одно кодирование — 300 строк на C.
А в цепочке конвертации могут участвовать и другие утилиты: MP4Box, m3u8-segmenter, измерение громкости (r128gain). У некоторых из них вообще нет никакого api.
И разные параметры вызовов придется время от времени подкручивать. А еще ffmpeg иногда крешится.
ValdikSS
Вы что-то делаете утилитами, чего не может сам ffmpeg? Про mp4box не могу ничего сказать, т.к. контейнером почти не пользуюсь, вполне возможно, что в ffmpeg нет нужной функциональности, но m3u8-segmenter deprecated, как написано в его репозитории, и автор советует использовать муксер «hls» из ffmpeg:
r128gain не пользовался, но что-то мне подсказывает, что его можно заменить ladspa-плагинами, которые поддерживает ffmpeg, и сразу засунуть их в фильтры аудио.
valievkarim
Сейчас наверное ffmpeg уже все это умеет, но в 2012 когда я занимался этим — не умел.
MP4Box использовался для перекладывания индекса в начало файла.
Еще там был mediainfo, который был чем-то лучше чем ffprobe. И утилиты шифрования видео в wiidevine и f4fpackager.