- PVSM.RU - https://www.pvsm.ru -
Мы, дети 90-х, любим добавить в задания NeoQUEST [1]что-нибудь олдскульное. В этом году нам вспомнились гремлины [2], и мы добавили их в легенду одного из заданий соревнования «Очной ставки» NeoQUEST-2017.
Однако, под внешне забавной легендой скрывается вполне себе реальная практическая задача: а что, если привычные ELF-файлы [3] — не просто исполняемые файлы, а контейнеры, открыть которые нам предстоит? Для этого придется испытать довольно-таки обширные возможности objcopy [4]и освежить в памяти организацию ELF-файла.
Чтобы вычислить подозрительные секции, необходимо представлять секционный и сегментный состав типичного ELF. Помимо этого, конечно, пригодится и опыт — например, общение с firmware embedded-систем вполне может подсказать подходящие идеи!
Думаете, готовы на 100%? Уверены, что гремлинам удастся вас удивить спрятанными архивами, попорченными таблицами символов, а также аудиофайлами, которые зазвучат только в руках умелого мастера! Под катом — исходники к заданию и прохождение, чтобы каждый читатель Хабра мог собственноручно попробовать пройти задание!
Легенда к заданию выглядела так:
Прибыв на место, мы обнаружили, что на базе полнейший хаос и разруха. Все это устроила парочка местных аборигенов, очень похожих на гремлинов из известного земного фильма. Один из них явно был главным в этой небольшой банде, более крупный, наглый и разговорчивый:
— Hehehehehehe, we had ate your message! Had ate this stupid gremlin! And will eat you!
Второй, мельче и скромнее, держался позади своего товарища и периодически выкрикивал:
— The Gremlins Are Coming!
Похоже, эти паршивцы не только устроили хаос и разруху, повредили оставленное нам сообщение, но еще и товарища своего слопали…
Исходные данные — три файла: greik [5], straip [6]и message [7].
Исходя из легенды, понимаем, что самый важный файл — message, и нужно его прослушать. Но, само собой, он не работает (иначе в чем смысл задания?). Если запустить его, получим следующую информацию:
Sorry, but i'm lost my prepare section...
Чтобы починить наше сообщение, надо «распотрошить» двух гремлинов, которые всё
«погрызли», в том числе, и своего товарища. Запустим каждый файл. После ./greik увидим:
The Gremlins Are Coming! (оригинальная цитата из фильма, между прочим!)
После ./straip:
Hehehehehehe, we had ate your message! Had ate this stupid gremlin! And will eat you!
То есть, всё то, что описано в легенде. Раз эти гремлины съели всё необходимое для прохождения задания, нужно посмотреть, что у них внутри! Применим утилиту readelf [8] на оба файла. Нас будут интересовать только секции файла и информация о них, поэтому
необходимо использовать флаги -SW. В результате получим для straip:

Обратим внимание на секцию 28, stomach (желудок!). Сдампим ее. Для этого можно
воспользоваться либо утилитой dd [9], высчитав все необходимые смещения, либо утилитой objcopy [10] следующим образом:
objcopy -O binary --only-section=.stomach --set-section-flags .stomach=alloc straip stomach
Аналогичные действия произведем для файла greik. Выдача readelf -SW:

Дампим секции 28 и 29 (.first_stuff и .second_stuff):
objcopy -O binary --only-section=.first_stuff --set-section-flags .first_stuff=alloc greik first_stuff
objcopy -O binary --only-section=.second_stuff --set-section-flags .second_stuff=alloc greik second_stuff
Посмотрим, что же мы тут наизвлекали. Для этого используем утилиту file [11] для каждого из извлеченных файлов. В результате получим:
stomach: Zip archive data, at least v2.0 to extract
first_stuff: data
second_stuff: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
Разархивируем stomach и, используя утилиту file, посмотрим, что за файлы мы получили:
sec1: data
piece2: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
key1: ASCII text
Ура, получили промежуточный ключ key1 («ISCJcPhB33cAvq9F9YkaZyU91SfwSObn»)! Остальные файлы необходимы для дальнейшего решения задачи. Исходный файл message сообщал, что у него потеряны секции, и из архива мы извлекли файл с именем sec1.
Применим утилиту readelf на message:

Видим, что имеется секция .extract (16) размером 0x50 (80). Также у нас есть один из извлеченных из гремлинов файлов размером 0x50 — first_stuff. Восстановим эту секцию:
objcopy --update-section .prepare=first_stuff message
Снова запустим message:
Preparing data for extract…
Preparing data successful
Sorry, but i'm lost my extract section...
Ему не хватает еще одной секции. По аналогии с предыдущей секцией восстанавливаем и эту:
objcopy --update-section .extract=sec1 message
Снова запускаем message:
Preparing data for extract…
Preparing data successful
Extracting key data…
Extracting complete successful
Все выполнилось. В результате получили аудио-файл message.mp3. Однако, если попытаться его прослушать, мы услышим лишь тишину, потому что данные нулевые. Вспомним, что straip
говорил нам, что они сожрали еще одного гремлина, и у нас осталось два неиспользованных файла в формате ELF.
Запуск их не даст ничего, кроме ошибки:
Failed to execute process './second_stuff'. Reason:
exec: Exec format error
The file './second_stuff' is marked as an executable but could not be run by the operating system.
Это все потому, что эти объектники необходимо слинковать друг с другом:
gcc second_stuff piece2 -o gremlin
В результате получим:
piece2: In function `main':
gizmo.c:(.text+0x5b): warning: the `gets' function is dangerous and should not be used.
gizmo.c:(.text+0x86): undefined reference to `get_back_function'
collect2: error: ld returned 1 exit status
И снова все не так, как должно быть! Используем утилиту readelf на наши «куски» гремлина, но на этот раз посмотрим таблицу символов (ключ -s). Для second_stuff:

Для piece2:

Видим, что в одном из них есть наша функция get_back_function, на которую ругался компилятор, а во втором есть некая функция с именем «a4f922hjd9843jd». Переименуем ее в get_back_function:
objcopy --redefine-sym a4f922hjd9843jd=get_back_function second_stuff
Попробуем повторить сборку файла:
gcc second_stuff piece2 -o gremlin
piece2: In function `main':
gizmo.c:(.text+0x5b): warning: the `gets' function is dangerous and should not be used.
Как видим, теперь все хорошо. Запускаем gremlin:
Hello… I tried saved your message, but forgot my name… Remember my name, plese and I can get back part of your
>>
Парниша вроде неплохой: пытался спасти наше сообщение, за что и пострадал. Готов все нам вернуть, да вот только своё имя забыл. Имя его Gizmo (оригинальное имя хорошего гремлина из фильма). Это можно увидеть как еще в процессе сборки, так и в любом HEX-редакторе в самом начале как исходных объектников, так и самого файла gremlin.
Введем его имя (с большой буквы, конечно!), ииии…
Hello… I tried saved your message, but forgot my name… Remember my name, please and I can get back part of your
>> Gizmo
Yes, yes! It's my name! Get back your part of file!
В результате получим еще один файл data_section. Легко догадаться, что и его мы запихиваем в исходный файл message:
objcopy --update-section .key=data_section message
Эту секцию .key можно было заметить еще когда мы исследовали утилитой readelf файл message. Во-первых, имя у нее говорящее, во-вторых, размер совпадает с тем, что вернул нам Gizmo.
Запустив файл message еще раз, мы уже получим нормальное сообщение, которое можно
прослушать [12]. Там сказано, что нам необходимо взять md5-хэш от этого файла и это будет ключом. Берём md5 и получаем ключ: 65935b0ae91b566c14c8b584ee8cf85d.
Оказывается, ELF-файл может быть далеко не просто исполняемым файлом, а контейнером для чего-либо. Это задание можно было пройти, выполнив реверс бинарников, но не реверсом единым сильны специалисты по инфобезу!
В данном варианте прохождения достаточно нескольких нехитрых манипуляций — и ELF-ский пазл успешно сложен, секции и таблицы символов восстановлены, архивы распакованы, а нашим гремлинам не остается ничего, кроме как сменить внушительное «The Gremlins Are Coming!» на белый флаг и выдать долгожданные ключи!
Автор: NWOcs
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/linux/261601
Ссылки в тексте:
[1] NeoQUEST : http://neoquest.ru/timeline.php
[2] гремлины: https://www.kinopoisk.ru/film/7114/
[3] ELF-файлы: https://ru.wikipedia.org/wiki/Executable_and_Linkable_Format
[4] objcopy : https://sourceware.org/binutils/docs/binutils/objcopy.html
[5] greik: https://yadi.sk/d/3hf-4RUW3KyMAo
[6] straip : https://yadi.sk/d/5fx4uaa83KyMF3
[7] message: https://yadi.sk/d/EAu4BnWU3KyMCr
[8] readelf: https://www.opennet.ru/man.shtml?topic=readelf&category=1&russian=1
[9] утилитой dd: https://www.opennet.ru/man.shtml?topic=dd&category=1
[10] утилитой objcopy: https://www.opennet.ru/docs/RUS/binutils/binutils-3.html
[11] утилиту file: https://www.opennet.ru/man.shtml?topic=file&category=1&russian=4
[12] прослушать: https://yadi.sk/d/xebbn_aA3Kyg3W
[13] Источник: https://habrahabr.ru/post/332918/
Нажмите здесь для печати.