Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

articles:linux-unpack-review [2017/09/05 02:55] (текущий)
Строка 1: Строка 1:
 +====== linux-unpack-review ======
 +<​sub>​{{linux-unpack-review.odt|Original file}}</​sub>​
 +
 +====== обзор упаковщиков исполняемых файлов под UNIX ======
 +
 +крис касперски ака мыщъх, no-email
 +
 +**упаковщики исполняемых файлов часто используются для затруднения анализа программы и препятствия взлому,​ но _ни_ _один_ упаковщик не свободен от ошибок,​ которые высаживают пользователей на конкретный геморрой,​ вынуждая распаковывать программу только затем, чтобы ее было можно запустить! покажем,​ как "​снимаются"​ наиболее популярные упаковщики:​ ****ELFCrypt****,​ ****UPX****,​ ****Burneye**** и ****Siva****.**
 +
 +===== введение =====
 +
 +Долгое время единственным упаковщиком исполняемых файлов,​ существующим в UNIX, был легендарный UPX, содержащий встроенный декомпрессор и распаковывающий файлы без труда. Но сейчас ситуация изменилась и упаковщики прут как грибы после дождя. Ими охотно пользуются разработчики коммерческих программ с закрытым кодом, не задумываясь о том, какие проблемы они причиняют своим пользователям.
 +
 +Упакованный файл потребляет намного больше оперативной памяти,​ а на некоторых UNIX-клонах вообще отказывается запускаться или работает нестабильно. В первую очередь это касается *BSD (основная масса упаковщиков ориентирована на LINUX), и экзотических систем с экспериментальными ядрами наподобие Hurd. В результате — от упаковщиков/​протекторов стремятся избавится даже тот, кто вообще не собирался ничего ломать!
 +
 +В этой статье,​ ориентированной на продвинутых пользователей,​ мы покажем как победить наиболее популярные упаковщики не будучи хакером и не имея навыков в дизассемблировании или отладке.
 +
 +===== ELFCrypt =====
 +
 +**происхождение**:​ создан индийским студентом по прозвищу JunkCode (junkcode@yahoo.com). Распространяется в исходных текстах на бесплатной основе:​ __www____.____infogreg____.____com____/​____source____-____code____/​____public____-____domain____/​____elfcrypt____-____v____1.0.____html__.
 +
 +{{linux-unpack-review_Image_0.png}}
 +
 +Рисунок 1 страничка создателя ELFCrypt'​а на programmer'​sheaven
 +
 +**описание:​ **простейший шифровщик (не упаковщик!) elf-файлов,​ шифрующий файл по XOR случайно генерируемым ключом. Присваивает кодовой секции атрибут writable и не убирает его после завершения расшифровки (что может приводить к некорректной работе программ,​ закладывающихся на невозможность модификации кодовой секции). Остальные секции (и секция данных в том числе!) остаются незашифрованными и все имеющиеся в них текстовые строки видны "​как есть"​. Не содержит никаких антиотладочных приемов,​ но подкладывает две больших свиньи дизассемблерам:​ "​забывает"​ скорректировать метку _start и размещает свой код в секции extern, истинное содержимое которой IDA Pro отображает только в режиме ручной загрузке при выбранной опции: "​ForceusingofPHTinsteadofSHT"​.
 +
 +**распаковка:​** загружаем файл в hiew, двойным нажатием ENTER'​а переходит в режим дизассемблера,​ давим <F8> для отображения заголовка и переходим в точку входа по <F5>, видим следующий код:
 +
 +.080495DC: EB02jmps.0080495E0;​ переходим на расшифровщик
 +
 +.080495DE: 06pushes; \ мусор, оставленный...
 +
 +.080495DF: C6???; / ...транслятором ассемблера
 +
 +.080495E0: 60pushad; сохраняем все регистры в стеке
 +
 +.080495E1: 9Cpushfd; сохраняем флаги в стеке
 +
 +**.080495****E****2:​ ****BEC****0820408****mov********esi****,​ 0080482****C****0 ; начало расшифровываемого фрагмента**
 +
 +.080495E7: 8BFEmovedi, esi; EDI := EDI (расшифровка на месте)
 +
 +**.080495****E****9:​ ****B****978000000****mov********ecx****,​ 000000078 ; кол-во двойных слов для расшифровки**
 +
 +**.080495****EE****:​ ****BBBD****03****CC****09****mov********ebx****,​ 009****CC****03****BD**** ; ключ расшифровки**
 +
 +.080495F3: ADlodsd; читаем очередной двойное слово <-----+
 +
 +.080495F4: 33C3xoreax,​ebx;​ расшифровываем через xor |
 +
 +.080495F6: ABstosd; записываем результат на место ​ |
 +
 +.080495F7: E2FAloop.0080495F3;​ мотаем цикл -------------------------+
 +
 +.080495F9: 9Dpopfd; восстанавливаем флаги из стека
 +
 +.080495FA: 61popad; восстанавливаем все регистры
 +
 +**.080495****FB****:​ ****BDC****0820408****mov********ebp****,​ 0080482****C****0;​ адрес оригинальной точки входа (****OEP****)**
 +
 +.08049600: FFE5jmpebp; передаем управление расшифрован. коду
 +
 +Листинг 1 дизассемблерный листинг окрестной точки входа программы,​ зашифрованной ELFCRypt'​ом
 +
 +Запоминаем (записываем на бумажке):​ **адрес начала расшифровываемого фрагмента** (грузится в регистр ESI), **кол-во расшифровываемых двойных слов** (грузится в регистр ECX), **ключ расшифровщика** (грузится в регистр EBX) и **адрес оригинальной точки входа** (грузится в регистр EBP).
 +
 +Нажимаем <F5> (goto) и вводим адрес начала расшифровываемого фрагмента с точкой впереди (точка указывает hiew'​у,​ что это не смещение внутри файла, а виртуальный адрес),​ в данном случае — "​.80482C0"​. Переходим в hex-режим двойным нажатием ENTER'​a,​ разрешаем редактирования по <F3> и нажимаем <F8> (xor) – hiew запрашивает маску шифрования,​ которую необходимо вводить в hex-виде с учетом обратного порядка байт на x86, в результате чего 09CC03BDh превращается в BD 03 CC 09 (а совсем не в DB 30 CC 90, как иногда поступают начинающие),​ после чего нажимаем <F8> ECX раз. Чтобы не сбиться,​ можно отталкиваться от адресов начала и конца блока, прекращая давать <F8> только тогда, когда курсор сместиться на ECX двойных слов (не байт!) относительно начальной позиции.
 +
 +{{linux-unpack-review_Image_1.png}}
 +
 +Рисунок 2 расшифровка файла, обработанного ELFCrypt'​ом в hiew'e
 +
 +Пара ремарок:​ при входе в режим редактирования hiew перестает отображать виртуальные адреса,​ переходя на физические смещения внутри файла, в результате чего 80482C0h превращается в 00002C0h, но пусть нас это не смущает. Конечное смещение расшифровываемого блока вычисляется тривиально 00002C0h +sizeof(DWORD)*78h == 4A0h.
 +
 +К сожалению,​ hiew не позволяет расшифровывать более одного экрана на раз и когда курсор подходит к последней строке,​ hiew пищит, но отказывается прокручивать файл, поэтому необходимо сохранить изменения по <F9>, нажать <​Page own>,​ вновь вернуться в режим редактирования клавишей <F3> и продолжить заниматься расшифровкой.
 +
 +Остается только скорректировать адрес точки входа. Нажимаем <F5> и переходим по смещению 18h относительно начала файла. Записываем число из EPP, не забывая про обратный порядок байт на x86 (т. е. в данном случае это будет выглядеть так: C0 82 04 08). Нажимаем <F9> для сохранения и выходим. Атрибуты кодовой секции можно, в принципе,​ и не восстанавливать.
 +
 +Запускаем расшифрованный файл, чтобы убедиться,​ что он работает. На этом процедуру распаковки можно считать законченной.
 +
 +===== UPX =====
 +
 +**происхождение**:​ созданный тройкой магов Markus F.X.J. Oberhumer, László Molnár и JohnF. Reiser, UPX относится к древнейшим распаковщикам,​ поддерживающим огромное количество форматов исполняемых файлов,​ среди которых есть и elf. Собственно говоря,​ аббревиатура UPX именно так и расшифровывается "​UltimatePackerforexecutables"​. Свежую версию вместе с исходными текстами можно бесплатно скачать с "​родного"​ сайта проекта:​ __www.upx.org__ или с "​кузни":​ __upx.sourceforge.net__.
 +
 +{{linux-unpack-review_Image_2.png}}
 +
 +Рисунок 3 отсюда можно скачать UPX
 +
 +**описание**:​ UPX упаковывает все секции файла (включая и таблицы,​ содержащие имена функций динамически загружаемых библиотек),​ вполне корректно обрабатывая elf-формат и успешно работая на всем "​зоопарке"​ UNIX-подобных систем. Не содержит никакого кода, препятствующего его отладке или дизассемблированию.
 +
 +**распаковка:​**UPX содержит встроенный распаковщик,​ возвращающий исполняемые файлы в исходный вид (для этого достаточно указать ключ -d в командной строке),​ однако,​ этому легко воспрепятствовать. Доступность исходных текстов позволяет модифицировать код упаковщика или изменить "​раскладку"​ служебной информации в генерируемом файле. Еще проще затереть сигнатуру "​UPX!",​ находящуюся в конце упакованного файла. Во всех этих случаях встроенный распаковщик склеивает ласты и распаковкой приходится заниматься самостоятельно.
 +
 +Нам потребуется утилита для снятия дампа с активных процессов PD, исходный код которой был опубликован в #63 номере электронного журнала PHRAK: __www____.____phrack____.____org____/​____phrack____/​63/​____p____63-0____x____0____c_________Process_________Dump_________and_________Binary_________Reconstruction____.____txt__.
 +
 +Запускаем упакованную программу (пусть,​ для определенности ее будет elinks), открываем новую консоль и, определив идентификатор процесса с помощью штатной утилиты ps, передаем его программе PD.
 +
 +Сеанс ручной распаковки выглядит следующим образом:​
 +
 +{{linux-unpack-review_Image_3.png}}
 +
 +Рисунок 4 сеанс ручной распаковки с помощью утилиты PD
 +
 +К сожалению,​ утилита PD еще довольно сыровата и сдампленные программы очень часто оказываются неработоспособными. В некоторых случаях помогает ключ -l, запрещающий трогать секцию .got, но чаще всего над полученным дампом приходится основательно поработать руками. Будем надеяться,​ что в следующих версиях PD этот недостаток будет преодолен.
 +
 +===== Burneye =====
 +
 +**происхождение**:​ экспериментальный протектор,​ созданный хакером по кличке **Scut** (scut@segfault.net),​ он же "​TheTower",​ живущим в западной германии и входящим в группу TESO, известную своим отладчиком linice – аналогом soft-ice под UNIX. Сначала исходные тексты протектора были недоступны и он распростился в виде уже откомпилированного файла на бесплатной основе:​ __packetstorm____.____linuxsecurity____.____com____/​____groups____/​____teso____/​____burneye____-1.0-____linux____-____static____.____tar____.____gz__,​ но через некоторое время Scut отдал на растерзание ~30% от общего объема кода проекта:​ __packetstorm.linuxsecurity.com/​groups/​teso/​burneye-stripped.tar.gz__,​ а затем и вовсе открыл все тексты целиком:​ __packetstorm____.____linuxsecurity____.____com____/​____groups____/​____teso____/​____burneye____-1.0.1-____src____.____tar____.____bz____2__.
 +
 +**описание**:​ никакой это не упаковщик,​ а самый настоящий протектор,​ изначально нацеленный на борьбу с хакерами. Умеет шифровать файлы по алгоритмам SHA1 и RC4, требуя от пользователя пароля при запуске и при необходимости привязываясь к оборудованию,​ чтобы пират, купивший одну-единственную лицензионную копию, не выложил свой ключ на всеобщее обозрение. Содержит некоторые приемы против отладчиков и дизассемблеров (прыжки в середину команды и установка собственного обработчика для SIGTRAP), но они реализованы _настолько_ неумело,​ что протектор без труда отлаживается даже gdb, не говоря уже про ядерные отладчики private-ice и linice. Некоторые защищенные программы падают под BSD, поэтому использовать этот протектор следует с большой долей скептицизма и осторожности.
 +
 +{{linux-unpack-review_Image_4.png}}
 +
 +Рисунок 5 страничка пацака ByteRage, поломавшего Burneye
 +
 +**снятие пароля**:​ против криптографии,​ увы, не попрешь и все, что может предложить нам хакерская общественность — это тупой brute-force. Подходящий переборщик можно найти на __byterage.hackaholic.org/​source/​UNFburninhell1.0c.tar.gz__,​ однако,​ следует быть заранее готовим к тому, что вскрыть длинные пароли все равно не удастся.
 +
 +Типичный сеанс работы с переборщиком выглядит так:
 +
 +[root@pentagon UNFburninhell]#​ ./burncrack -f /​usr/​stuff/​burneye-1.0/​burneye
 +
 +UNFburninhell by [ByteRage] / UNF
 +
 +---[ removing layer 1 (obfuscation layer)
 +
 +burneye signature found @ 0000100C
 +
 +obfuscation layer (layer 1) decryption key : B0CE3B8C
 +
 +length : 00015B7C
 +
 + start : 05371090
 +
 +---[ loading file data
 +
 +burneye signature found @ 0000100C
 +
 +burneye stub hash : 66 CC 2F 96 65 3D 4E 36 4D 37 19 20 85 8C AC 91 39 DA FD 88
 +
 +encrypted length ​ : 69352
 +
 +encrypted start  : 0x00005D1B
 +
 +encrypted dword  : 0x3EBD3C81
 +
 +checksum ​ : 0xFDB18CF3
 +
 +magic XOR block  : B4 AC 25 4A C1 CB 97 39 71 AF E3 54 F0 AD F5 9C FE 42 EC F2
 +
 +---[ bailing out
 +
 +[root@pentagon UNFburninhell]#​ /​usr/​stuff/​john-1.6/​run/​john -stdout:63 -i | ./burncrack -i
 +
 +UNFburninhell by [ByteRage] / UNF
 +
 +---[ loading file data
 +
 +burneye signature found @ 0000100C
 +
 +burneye stub hash : 66 CC 2F 96 65 3D 4E 36 4D 37 19 20 85 8C AC 91 39 DA FD 88
 +
 +encrypted length ​ : 69352
 +
 +encrypted start  : 0x00005D1B
 +
 +encrypted dword  : 0x3EBD3C81
 +
 +checksum ​ : 0xFDB18CF3
 +
 +magic XOR block  : B4 AC 25 4A C1 CB 97 39 71 AF E3 54 F0 AD F5 9C FE 42 EC F2
 +
 +---[ stdin bruteforce cracker
 +
 +password "​accept"​ okay! cracked in 134 seconds.
 +
 +performing sanity check...
 +
 +found checksum ​ : 0xFDB18CF3
 +
 +---[ bailing out
 +
 +Broken pipe
 +
 +[root@pentagon UNFburninhell]#​ ./burncrack -p accept -d unwrapped
 +
 +[root@pentagon UNFburninhell]#​ chmod a+x unwrapped
 +
 +[root@pentagon UNFburninhell]#​ ./unwrapped
 +
 +Листинг 2 подбор пароля методом bruteforce
 +
 +**распаковка**:​ когда борьба с Byrneye всех хакеров окончательно достала,​ пацак по кличке ByteRage (byterage@yahoo.com) написал утилиту **burneye unwrapper** для автоматического снятия протектора и представляющую из себя LKM-модуль (загружаемый модуль ядра), бесплатно распространяемый в исходных текстах (впрочем,​ называть "​исходными текстами"​ крошечную Си-программу можно только с большой натяжкой):​ __byterage____.____hackaholic____.____org____/​____source____/​____burndump____.____c__.
 +
 +Предполагается,​ что либо программа не защищена паролем,​ либо он нам известен (или подобран вышеописанной утилитой). Привязка к оборудованию убирается в любом случае.
 +
 +Компилируем:​ "​gcc ‑c burndump.c"​ (на некоторых системах необходимо явно указать включаемые файлы "​gcc ‑c ‑I/​usr/​src/​linux/​includeburndump.c"​),​ заходим в систему под root'​ом и начинаем взлом, потягивая свежее пиво:
 +
 +$ insmod burndump#​ загружаем LKM-модульвпамять
 +
 +# теперь дампер будет висеть резидентно в памяти,​
 +
 +# отлеживая запуск всех программ,​ и ловить те из них,
 +
 +# которые обработаны Burneye
 +
 +$./​file_name#​ запускаем программу защищенную Burneye
 +
 +# дампер дожидается,​ когда Burneye завершит
 +
 +# расшифровку и сохраняет распакованную программу
 +
 +# вфайл ./burnout
 +
 +$./burnout# запускаем распакованную программу,​
 +
 +# чтобы убедиться в ее работоспособности
 +
 +$rmmodburndump#​ выгружаем LKM-модуль из памяти
 +
 +Листинг 3 освобождение файла от протектора Burneye
 +
 +===== Shiva =====
 +
 +**происхождение**:​ весьма амбициозный протектор,​ созданный двумя гуру NeelMehta и ShaunClowes (Email: shiva@securereality.com.au) и неоднократно демонстрируемый ими на конференциях BlackHat. Исходные тексты не разглашаются (как будто там есть, что скрывать!),​ а сам бинарник можно скачать как с сайта разработчиков __www.securereality.com.au/​archives/​shiva-0.95.tar.gz__,​ так и с сервера BlackHat: __blackhat.com/​presentations/​bh-usa-03/​bh-us-03-mehta/​bh-us-03-shiva-0.96.tar__,​ причем,​ версия с BlackHat'​а посвежее будет, что наводит на определенные размышления.
 +
 +{{linux-unpack-review_Image_5.png}}
 +
 +Рисунок 6 сайт разработчиков протектора Shiva
 +
 +**описание**:​ протектор поддерживает парольную защиту (правда,​ без привязки к оборудованию),​ реализует мощную антиоталадку,​ многоуровневую динамическую шифровку с порождением дочернего отладочного процесса,​ эмуляцию некоторых процессорных инструкций… в общем получился почти что Armadillo, только под LINUX. Но, если Armadillo хоть как-то работает,​ то Shiva на всех доступных мыщъху системах выпадет в Segmentationfault. Конкретно тестировались:​ KNOPPIX с ядрами 2.6.7/4.2.7 и S.u.S.Ec ядром 2.6.8, пускаемых как под VM Ware, так и на "​живой"​ машине с процессором AMD Athol-1700,​ что делает снятие протектора сверх актуальной задачей.
 +
 +{{linux-unpack-review_Image_6.png}}
 +
 +Рисунок 7 Shiva настолько крутой протектор,​ что ни под одной системой даже не запускается
 +
 +**распаковка**:​ морской волк Chris Eagle (cseagle@nps.navy.mil) создал автоматический распаковщик,​ позволяющий любому желающему поиметь Шиву во все дыры и, как и большинство остальных хакерских инструментов,​ бесплатно распространяемый в исходных текстах:​ __www____.____blackhat____.____com____/​____presentations____/​____bh____-____federal____-03/​____bh____-____federal____-03-____eagle____/​____bh____-____federal____-03-____eagle____.____zip__. Распаковав архив, мы найдем мультимедийную презентацию bh-federal-03-eagle.ppt с объяснением принципов работы протектора,​ пару idc-скриптов для упрощения дизассемблирования защищенных файлов в IDA Pro и еще один архив stripshiva.tar.gz,​ содержащий исходный код автоматического распаковщика.
 +
 +Компиляция осуществляется простым запуском утилиты "​make",​ после чего у нас на диске образуется stripshiva — распаковщик не защищенных паролем файлов и shivalkm.o — загружаемый модуль ядра для взлома паролей.
 +
 +Незапароленнные программы распаковываются так:
 +
 +# stripshivax.shiva
 +
 +Листинг 4 распаковка незапароленных файлов,​ обработанных протектором Shiva
 +
 +А вот для взлома запароленных файлов приходится совершать гораздо больше телодвижений (при этом предполагается,​ что запароленный файл уже запущен,​ то есть пароль должен быть известен,​ по другому,​ увы, ломать не получается):​
 +
 +$insmodshivalkm.o#​ загружаем LKM-модуль в память
 +
 +$rmmodshivalkm#​ выгружаем модуль (все что было нужно он уже сделал)
 +
 +$tail /​var/​log/​messages#​ проверяем на наличие любых сообщений
 +
 +$ls# проверяем на наличие сдампленного файла
 +
 +$stripshiva -pshivaout# превращаем дамп в готовый elf
 +
 +Листинг 5 распаковка файлов,​ обработанных протектором Shiva и защищенных паролем
 +
 +===== заключение =====
 +
 +Shiva — это лучший протектор из всех, существующих под UNIX, но, увы, на проверку это оказывается всего лишь кривая калька с Armadillo и к тому же неработающая. В то время как под Windows, протектор Armadillo уже давно не является чудом инженерной мысли, ситуация в мире UNIX напоминает СССР в эпоху "​персональных компьютеров коллективного использования"​. И это хорошо! Потому что UNIX свободная система и она еще будет оставаться такой какое-то время!
 +
 +