Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР 124, АПРЕЛЬ 2009 г.

Имплантация Cisco. Модифицирование прошивки маршрутизатора

Евгений «ShadOS» Хабаров (shados@mail.ru)




Приветствую, дорогой друг! Сегодня мы будем дарить вторую молодость (а может даже и жизнь) старым маршрутизаторам Cisco, практически не нарушая лицензионного соглашения. Пусть этот хакерский метод достаточно прост, но от этого он не становится менее интересным. Имя ему – «бинарный патчинг».

Сразу к делу. Исходные данные следующие: старенькая кошка Cisco 2611 с двумя Ethernet-портами, 64 Мб RAM и 16 Мб на Flash. Это максимально возможные параметры, поддерживаемые платформой (читай – увеличить объем DRAM памяти и flash не получится из-за отсутствия в природе комплектующих больших объемов). Исходя из данных Cisco IOS Feature Navigator (tools.cisco.com/ITDIT/CFN/jsp/index.jsp), последней версией IOS для этого маршрутизатора является 12.3(26) – вполне естественно для столь старого продукта (End-of-Sale - апрель 2003, End-of-Life – апрель 2008). Хочется получить только все самое последнее и новое, а все самое новое и вкусное доступно только в версии 12.4 (точнее 12.4T).

Посыл номер два, или дополнительные исходные данные таковы: если внимательно следить за модельным рядом маршрутизаторов Cisco или просто ознакомиться с информацией о продуктах на официальном сайте, то можно обнаружить, что серия 2600 включает в себя, например, маршрутизаторы 2611XM. Отличается эта серия от своего предшественника незначительно:

  • Максимальный объем flash-памяти увеличен до 48 MB (в 2611 — 16 MB)
  • Максимальный объем SDRAM-памяти увеличен до 128 MB (в 2611 — 64 MB)
  • Интегрированные 10/100 Fast Ethernet порты (в 2611 — 10 Мбит/c Ethernet)

Для такой кошки Cisco IOS Feature Navigator сообщит, что последний IOS имеет версию 12.4(23). Системные требования для IOS 12.4(21) с набором Enterprise Base или Advanced Security составляют 128 MB DRAM и 32 MB flash. Конечно, у нас нет 128 MB памяти, но попытка не пытка, да и пропускная способность портов у нас невысокая. Это позволяет сделать предположение, что ОС можно запустить на моем устройстве. Осталось превратить теорию в практику.

Extended, или Что хотим получить

Идея проста - загнать бинарный образ операционной системы Cisco IOS 12.4(21) с набором фьючерсов Enterprise Base на старенький маршрутизатор 2611 с исходными данными, представленными выше. В дальнейшем – использовать как тестовый стенд, ибо 10-мегабитные интерфейсы ограничивают его применение в дикой природе, или, как говорится, in production. С тем же успехом устройство может надежно служить файрволом корпоративной сети взамен какого-нибудь PIX (если, конечно, достаточно пропускной способности в 10 Мбит), но тогда встает вопрос — а есть ли такой функционал, который может потребоваться в IOS 12.4, но которого нет в 12.3? За подсказкой вновь отправляю к Cisco IOS Feature Navigator (tools.cisco.com/ITDIT/CFN/Dispatch). Утилита сравнения образов тебе в помощь, но ответ, скорее всего, - «нет». Отсюда вывод — не стоит меня корить в малой практичности, так как изначально статья в большей степени исследовательская (just for fun).
У меня не возникло бы потребности писать статью, если бы не две небольших проблемы. О первой я уже упомянул — это объем DRAM памяти. К сожалению, я не повелитель паяльника и вольтметра, так что здесь поделать ничего не можем. Стоит только надеяться, что ОС не уйдет в core в самый ответственный момент из-за недостатка памяти. Вторая проблема, которая застигла меня врасплох – это размер самого образа IOS 12.4 и тот факт, что он не помещается на флеш объемом 16 МB. И неудивительно: файл образа – c2600-entbasek9-mz.124-9.T1.bin – который я взял для эксперимента, занимает 16,4 MB, то есть 17 257 364 байт. Даже если стереть флеш с опцией no-squeeze-reserve-space (командой erase /no-squeeze-reserve-space flash:), это нам не поможет. Хотя, в свое время, для образа c2600-ik9o3s3-mz.123-13.bin было решением проблемы (этот образ чуть меньше размера самой флеш, и для его загрузки требуется отформатировать ее с опцией, запрещающей резервировать свободное место).

Что делать? Бежать!

Решения здесь может быть два – либо грузиться с tftp, что не всегда удобно, либо же взломать образ так, чтобы размер стал меньше. Грубо говоря, перепаковать его (собственно, это и было отчасти сделано).

Посылом номер три стал эмулятор Dynamips. Причем он тут? Именно он натолкнул меня на мысль о перепаковке образа. Если взглянуть на раздел «How to use?» на официальном сайте проекта (www.ipflow.utc.fr/index.php/Cisco_7200_Simulator), то можно обнаружить, что эмулятор использует распакованные образы для ускорения загрузки:


<skipped>
To boot quickly, the preferred method is to decompress the IOS image with the "unzip" utility. It avoids to run the self-decompressing process in the emulator.
chris@portchris2:~/dynamips-0.2.5$ unzip -p c7200-advipservicesk9-mz.124-9.T.bin > image.bin
warning [c7200-advipservicesk9-mz.124-9.T.bin]: 27904 extra bytes at beginning or within zipfile
(attempting to process anyway)
chris@portchris2:~/dynamips-0.2.5$ file image.bin
image.bin: ELF 32-bit MSB executable, cisco 7200, version 1 (SYSV), statically linked, stripped
You can ignore the warning, unzip has just skipped the self-decompressing code at the beginning of the image.
Now, you can boot the imagе
<skipped>

Если есть запакованный образ, то можно попытаться использовать более оптимальные параметры сжатия, которые позволят поместить образ на флеш. Обращаю внимание на важную деталь — так как мы не собираемся переписывать самораспаковывающийся код, то есть заниматься дизассемблированием (да и ассемблер под 32-битные процессоры PowerPC я не знаю), то сам алгоритм сжатия менять мы не сможем. Самораспаковывающаяся часть просто не сможет распаковать архивы, сжатые другими методами. По поводу используемого в образе алгоритма сжатия – можно взглянуть вот сюда: Cisco IOS Configuration Fundamentals Configuration Guide, Release 12.4 - Loading and Managing System Images, пункт Image Naming Conventions. Поле «тип» в имени образа как раз отвечает за его характеристики:

  • f - The image runs from flash memory
  • m - The image runs from RAM
  • r - The image runs from ROM
  • l - The image is relocatable
  • z - The image is zip compressed
  • x -The image is mzip compressed

В нашем случае образ имеет тип mz – работает в памяти и запакован как раз в zip-архив. Убедиться в этом просто — большинство архиваторов (WinZIP, WinRAR, 7zip) с легкостью открывают его и распаковывают.

Упаковка

Не мудрствуя лукаво, пытаемся перепаковать архив заново с максимально возможной степенью сжатия. Сразу же отмечаем, что используемый метод — deflate и изменить его не получится. Я использовал четыре архиватора, чтобы сравнить их и получил такой результат:

7-zip 4.65 со следующими параметрами:

  • Формат архива — zip
  • Уровень сжатия — Ультра
  • Метод сжатия — Deflate
  • Размер словаря — 32КB
  • Размер слова — 258

В результате был получен архив: 15,7 MB (16 489 764 bytes). WinZIP 11.2 при использовании улучшенного метода Deflate выдал файл размером 16,0 MB (16 803 634 bytes). WinRAR 3.80 формат архива — zip с наилучшими параметрами сжатия: 16,3 MB (17131 353 bytes). PKZIP 9.00 от создателей формата совсем подвел, и по методу Deflate с максимальным сжатием произвел файл размером 16,3 MB (17 094 474 bytes).

Итогом моего небольшого сравнительного тестирования стал выбор для экспериментов архива, как нетрудно догадаться, созданного 7zip.

Теория (интеграции нового архива)

Далее требуется сей архив поместить вместо оригинального образа. Чтобы проделать это, нам понадобится шестнадцатеричный редактор типа WinHex, HT Editor или hview. Я предпочитаю WinHex, но понадобится еще и HT, чуть позже объясню почему.

Как ты можешь видеть на скриншоте, бинарный образ IOS, скорее всего, есть не что иное, как исполняемый файл в формате ELF (Executable and Linkable Formate). ELF-формат является основным исполняемым файлом в *nix-like системах, поэтому неудивительно встретить его здесь. По ELF-формату существует четкая спецификация, последняя версия которой 1.2, однако для наших целей будет достаточно, например, заголовочного файла из состава libc - elf.h. Обычный бинарный ELF-файл представляет собой структуру вида:

ELF Header
Program Header Table (optional)
Section 1
Section 2

Section n
Section Header Table

Не углубляясь в описание (и дабы не повторяться), отправляю тебя к спецификации.Так как весь процесс исследования я проводил в MS Windows, то пришлось искать замену утилите readelf из состава binutils. Подходящим вариантом оказался шестнадцатеричный редактор HT (hte.sf.net), который умеет читать и модифицировать структуры данных исполняемых файлов ELF. При попытке открыть подопытный образ c2600-entbasek9-mz.124-9.T1.bin, HT сразу меня обругал, что и привлекло мое внимание. Обратимся к elf.h. Структура данных, отвечающая за ELF-заголовок, выглядит так:

typedef struct {
Elf_Chare_ident[EI_NIDENT];
Elf32_Halfe_type;
Elf32_Halfe_machine;
Elf32_Worde_version;
Elf32_Addre_entry;
Elf32_Offe_phoff;
Elf32_Offe_shoff;
Elf32_Worde_flags;
Elf32_Halfe_ehsize;
Elf32_Halfe_phentsize;
Elf32_Halfe_phnum;
Elf32_Halfe_shentsize;
Elf32_Halfe_shnum;
Elf32_Halfe_shstrndx;
} Elf32_Ehdr;

В нашем случае поле e_machine имеет значение 0x002b или 43, что соответствует процессору SPARC v9:

#define EM_SPARCV9 43 /* SPARC v9 64-bit */

Но нам известно, что маршрутизатор 2611 использует процессор Motorolla MPC860, значит, поле должно иметь значение 0x0014, – что соответствует:

#define EM_PPC 20 /* PowerPC */

Скорее всего, это простейшая защита от дизассемблирования образа. Нам это не сильно помешает. С помощью F6 открываем режим просмотра elf/header. Из него становятся известны следующие подробности:

  • elf header size 0x34
  • program header entry size 0x20
  • program header count 1
  • section header entry size 0x28
  • section header count 6

Что, в сумме, дает размер 52+32+6*40=324 или 0x144, то есть, в файле всего 6 секций (соответственно, 6 заголовков секций) и 1 заголовок программы. Вероятнее всего, одна из секций предназначена для хранения архива с исполняемым образом IOS. Эту секцию можно вычислить либо по размеру (логично, что ее размер должен быть максимальным), либо по типу секции. Заголовок таблицы секций можно просмотреть, нажав <F6> и выбрав elf/section headers, но для начала обратимся к описанию секции:

typedef struct {
Elf32_Wordsh_name;
Elf32_Wordsh_type;
Elf32_Wordsh_flags;
Elf32_Addrsh_addr;
Elf32_Offsh_offset;
Elf32_Wordsh_size;
Elf32_Wordsh_link;
Elf32_Wordsh_info;
Elf32_Wordsh_addralign;
Elf32_Wordsh_entsize;
} Elf32_Shdr;

Поле sh_type и будет отвечать за искомый тип. К сожалению, здесь меня ждал облом, – большинство секций имело тип SHT_PROGBITS, предназначенный для секций, значение которых определяется самой программой. Однако четвертая секция имела тип, отличный от предыдущих, и значение 0x00000007 (секция предназначена для каких-то программных заметок). Первая (нулевая) секция также имеет отличный от предыдущих тип (SHT_NULL). Исходя из этого, ясно, что она пустая и ни с чем не ассоциирована. В итоге, приходится искать секцию с максимальным размером (поле sh_size). Это – секция за номером пять, ее размер 0x1070e7c или 17239676 байт. Вернемся к hex-виду (<F6> - hex) и перейдем по смещению (поле sh_offset) с помощью <F5>.

Что же мы здесь видим? Где наш архив, который должен начинаться с сигнатуры PK, а точнее, если следовать спецификации PKZIP-формата (pkware.com/documents/casestudies/APPNOTE.TXT), – с 0x04034b50 в обратном порядке? Как ни странно, эта сигнатура обнаруживается на 22 байта позже. А если хорошо присмотреться, то отказывается, что сразу за значением 0xFEEDFACE идет размер распакованного образа 0x02AED904. Внимательно поискав в Сети, можно наткнуться на информацию из книги Cisco Networks Hacking Exposed издательства McGraw Hill/Osborne.

Наши русские парни Andrew A. Vladimirov, Konstantin V. Gavrilenko, Janis N. Vizulis and Andrei A. Mikhailovsky еще в 2006 году занимались разработкой бинарного патчинга IOS 12.3(6). Им удалось выяснить, что после магического значения 0xFEEDFACE идут последовательно uncompressed image size, compressed image size, compressed image checksum, uncompressed image checksum. Товарищам также стало известно, что алгоритм вычисления контрольной суммы представляет собой модифицированный алгоритм контрольной суммы в интернете. К счастью, нам не придется ничего вычислять —проверено на практике, что маршрутизатор сам скажет, какое значение должно иметь это поле, если, конечно, подсчитанная контрольная сумма и записанная в соответствующем поле не совпадут:

Error : compressed image checksum is incorrect 0xB99D8823
Expected a checksum of 0xF6F69877

*** System received a Software forced crash ***
signal= 0x17, code= 0x5, context= 0x800805f0
PC = 0x0, Vector = 0x0, SP = 0x0

Практика (интеграции нового архива)

Перейдем к активным действиям. Для начала вырезаем из файла старую четвертую секцию, содержащую zip-архив, – за исключением 20 байт, начиная с магического значения 0xFEEDFACE до сигнатуры zip (то есть, со смещения 0x44F8 по смещение 0x1075360 + 0x44F8). Затем по смещению 0x44F8 вставляем новый архив.
Соединим всю известную нам информацию воедино. Размер старой секции (№5), содержащей архив с образом IOS, загружаемым в память, – 0x1070e7c или 17239676 (включая 20 байт с 0xFEEDFACE по 0x504B0304). Размер новой секции, содержащей архив, – 0xFB9D38 или 16489784 (включая те же 20 байт). Разница между старым и новым значением составит 0xB7158 — 749912. То есть, смещение четвертой секции, физически расположенной в файле после пятой секции, требуется изменить с 0x1075360 на 0xFBE208!Старые значения после магической записи 0xFEEDFACE:

unpacked image size: 0x02AED904 45013252
packed image size: 0x01070E66 17239654 (разница с размером 5й секции - на 22 байта меньше)
packed image checksum: 0xB58BE139
unpacked image checksum: 0xA29D4F6E
затем идет сигнатура: 0x504B0304

Новые значения после магической записи 0xFEEDFACE:

unpacked image size: 0x02AED904 (остался тот же)
packed image size: 0x00FB9D22 16489762 (разница с размером 5й секции - на 22 байта меньше)
packed image checksum: нам неизвестна и можно заменить на что-нибудь приметное, типа 0x48000000
unpacked image checksum: 0xA29D4F6E (остался тот же)

Новую контрольную сумму, как я уже говорил, сообщит сам маршрутизатор.После всех манипуляций конечный образ был получен, но его размер меня не впечатлил. По сравнению с изначальным размером 16,4 MB (17257364 bytes) я получил всего лишь 15,7 MB (16507472 bytes). Разница, которую я уже посчитал выше, составила 749912 байт. Конечно, это позволит загрузить образ на flash, но, скорее всего, придется применять опцию /no-squeeze-reserve-space. Когда при копировании маршрутизатор запросит повторное стирание flash, подтверждать действие не нужно.

Естественно, такая ситуация была бы только в том случае, если образ был бы сформирован правильно. Поэтому я не стал спешить и для загрузки образа зашел в режим rommon по Ctrl+Break. И – со своего компьютера загрузил образ по tftp напрямую в RAM:

rommon 1>tftpdnld -r

После загрузки маршрутизатор я сказал:

TFTP flash copy: Error, image size (16507470) mismatches netsize (16507472).

Оказалось, что при редактировании размера 5й секции я ошибся на 2 байта (те самые 20 байт с 0xFEEDFACE + 2).После второй попытки загрузки выяснилось, что контрольная сумма запакованного образа — 0xB0257B0D:

Error : compressed image checksum is incorrect 0xB99D8823
Expected a checksum of 0x48000000

*** System received a Software forced crash ***
signal= 0x17, code= 0x5, context= 0x800805f0
PC = 0x0, Vector = 0x0, SP = 0x0

Корректируем соответствующее поле после 0xFEEDFACE (загружаем файл в HT по <F3>, переходим по смещению с помощью <F5> и редактируем по <F4>, не забывая сохраняться по <F2>). Затем снова грузимся.

rommon 4>reset -s

Дальше все нормально, однако затем IOS вываливается и отказывается работать по причине недостатка памяти:

Никогда не сдавайся

Я не расстроился и решил взяться за другой образ — c2600-advsecurityk9-mz.124-21.bin. После аналогичных манипуляций с байтами, даже при использовании 128-битного слова в 7zip, размер составил 15947076 (против изначальных 16635336), что позволило загрузить его во flash. Помимо прочего, этот образ уже не ругался на недостаток памяти RAM и прекрасно чувствовал себя на этой платформе:

router#show version
Cisco IOS Software, C2600 Software (C2600-ADVSECURITYK9-M), Version 12.4(21), RELEASE SOFTWARE (fc1)

<skiped>

router#show memory summary
Head Total(b) Used(b) Free(b) Lowest(b) Largest(b)
Processor 82A44240 20244772 8718640 11526132 10171028 10098348
I/O 3CA3400 3525632 1650536 1875096 1875096 1875068

<skiped>

router#show flash:

System flash directory:
File Length Name/status
1 15947076 c2600-advsecurityk9-mz.124-21-shad-pk.bin
[15947140 bytes used, 830072 available, 16777212 total]
16384K bytes of processor board System flash (Read/Write)

Остается еще одна небольшая проблема. Если запустить проверку:

router#verify flash:c2600-advsecurityk9-mz.124-21-shad-pk.bin

– маршрутизатор обругает нас, сообщив, что Embedded hash и Calculated hash не совпадают. Исправить это очень просто — 16 байт контрольной суммы находится в самом конце бинарного файла образа.

После исправления маршрутизатор сообщает, что контрольная сумма успешно подсчитана и совпадает:

Embedded Hash MD5 : 3DD2C6591FF4F033425147DE4540F9CD
Computed Hash MD5 : 3DD2C6591FF4F033425147DE4540F9CD
CCO Hash MD5 : 79020945BDFE2A354E012C8303136360

Embedded hash verification successful.
File system hash verification successful.

Логическое заключение

Новый образ готов и правильно сформирован. Усвоив эту статью, ты получишь опыт:

  1. по формату PKZIP;
  2. по формату исполняемых файлов ELF;
  3. по внутреннему устройству образов Cisco IOS;
  4. по работе в режиме rommon маршрутизатора.

Кроме того, готов задел для дальнейших извращений над маршрутизаторами. Для общего развития можно поковырять распакованные образы в IDA, изучить вирусы в *nix-like системах, чтобы проинфицировать образ своим бекдором, ну и собственно, написать бекдор. A мои изыскания здесь успешно заканчиваются. Все вопросы, пожелания и, в особенности, идеи, мой дорогой друг, я готов получить по электронной почте. С радостью отвечу и помогу по мере сил. Удачи в бинарном патчинге... и не только.

Содержание
загрузка...
Журнал Хакер #151Журнал Хакер #150Журнал Хакер #149Журнал Хакер #148Журнал Хакер #147Журнал Хакер #146Журнал Хакер #145Журнал Хакер #144Журнал Хакер #143Журнал Хакер #142Журнал Хакер #141Журнал Хакер #140Журнал Хакер #139Журнал Хакер #138Журнал Хакер #137Журнал Хакер #136Журнал Хакер #135Журнал Хакер #134Журнал Хакер #133Журнал Хакер #132Журнал Хакер #131Журнал Хакер #130Журнал Хакер #129Журнал Хакер #128Журнал Хакер #127Журнал Хакер #126Журнал Хакер #125Журнал Хакер #124Журнал Хакер #123Журнал Хакер #122Журнал Хакер #121Журнал Хакер #120Журнал Хакер #119Журнал Хакер #118Журнал Хакер #117Журнал Хакер #116Журнал Хакер #115Журнал Хакер #114Журнал Хакер #113Журнал Хакер #112Журнал Хакер #111Журнал Хакер #110Журнал Хакер #109Журнал Хакер #108Журнал Хакер #107Журнал Хакер #106Журнал Хакер #105Журнал Хакер #104Журнал Хакер #103Журнал Хакер #102Журнал Хакер #101Журнал Хакер #100Журнал Хакер #099Журнал Хакер #098Журнал Хакер #097Журнал Хакер #096Журнал Хакер #095Журнал Хакер #094Журнал Хакер #093Журнал Хакер #092Журнал Хакер #091Журнал Хакер #090Журнал Хакер #089Журнал Хакер #088Журнал Хакер #087Журнал Хакер #086Журнал Хакер #085Журнал Хакер #084Журнал Хакер #083Журнал Хакер #082Журнал Хакер #081Журнал Хакер #080Журнал Хакер #079Журнал Хакер #078Журнал Хакер #077Журнал Хакер #076Журнал Хакер #075Журнал Хакер #074Журнал Хакер #073Журнал Хакер #072Журнал Хакер #071Журнал Хакер #070Журнал Хакер #069Журнал Хакер #068Журнал Хакер #067Журнал Хакер #066Журнал Хакер #065Журнал Хакер #064Журнал Хакер #063Журнал Хакер #062Журнал Хакер #061Журнал Хакер #060Журнал Хакер #059Журнал Хакер #058Журнал Хакер #057Журнал Хакер #056Журнал Хакер #055Журнал Хакер #054Журнал Хакер #053Журнал Хакер #052Журнал Хакер #051Журнал Хакер #050Журнал Хакер #049Журнал Хакер #048Журнал Хакер #047Журнал Хакер #046Журнал Хакер #045Журнал Хакер #044Журнал Хакер #043Журнал Хакер #042Журнал Хакер #041Журнал Хакер #040Журнал Хакер #039Журнал Хакер #038Журнал Хакер #037Журнал Хакер #036Журнал Хакер #035Журнал Хакер #034Журнал Хакер #033Журнал Хакер #032Журнал Хакер #031Журнал Хакер #030Журнал Хакер #029Журнал Хакер #028Журнал Хакер #027Журнал Хакер #026Журнал Хакер #025Журнал Хакер #024Журнал Хакер #023Журнал Хакер #022Журнал Хакер #021Журнал Хакер #020Журнал Хакер #019Журнал Хакер #018Журнал Хакер #017Журнал Хакер #016Журнал Хакер #015Журнал Хакер #014Журнал Хакер #013Журнал Хакер #012Журнал Хакер #011Журнал Хакер #010Журнал Хакер #009Журнал Хакер #008Журнал Хакер #007Журнал Хакер #006Журнал Хакер #005Журнал Хакер #004Журнал Хакер #003Журнал Хакер #002Журнал Хакер #001