Завоевание интернета Крис Касперски ака мыщъх Спецвыпуск: Хакер, номер #059, стр. 059-066-8 Еще хуже, что IOS контролирует целостность кучи и автоматически перезагружает маршрутизатор, если цепочка ссылок (chunk linkage) оказывается разрушенной. За это отвечает специальный фоновой процесс, в зависимости от загрузки маршрутизатора пробуждающийся каждые 30 или 60 секунд. Именно он проверяет магический номер и красную зону. Так что shell-коду отпущено совсем немного времени. Конечно, 30 секунд – это целая вечность для процессора, за это время можно не только внедриться в целевое железо, но и заразить множество соседних маршрутизаторов. FX с KIMO предложили несколько решений этой проблемы, но все они оказались нежизнеспособными. Майкл был первым, кому удалось нащупать правильный путь, простой, как и все гениальное. Оказалось, что процедура abort(), выполняющая перезагрузку, использует специальный флаг-семафор, предотвращающий повторное вхождение (по такому же принципу устроена защита от многократного нажатия <Alt>-<Ctrl>-<Del> в NT). Если мы установим его в единицу, функция abort() тут же выполнит return без всякий перезагрузки. Ниже приведен ее ключевой фрагмент. (Впрочем, маршрутизатор все равно будет перезагружен через некоторое время, так как куча разрушена, так что shell-коду надо спешить.) stwu sp, var_18(sp) mflr r0 stmw r29, 0x18+var_C(sp) stw r0, 0x18+arg_4(sp) lis r9, (crashing_already_ >> 16) lwz r0, (crashing_already_ & 0xFFFF)(r9) cmpwi r0, 0 bne loc_80493D18 # return Программа для расчета контрольных сумм Ни одна из версий IOS, работающих на платформе M68K, не использует аппаратные механизмы контроля памяти, предоставляемые MMU (Memory Management Unit – блок управления памятью), поэтому запись в кодовый сегмент проходит вполне беспрепятственно. Для защиты от непреднамеренного разрушения используются контрольные суммы. Каждые 30 или 60 секунд специальный процесс сканирует кодовый сегмент на предмет проверки его валидности и перезагружает маршрутизатор, если контрольные суммы не совпадают с расчетными. Однако против преднамеренной модификации эта "защита" уже не срабатывает, поскольку контрольные суммы легко пересчитать и подправить. Это можно сделать, например, так: // (c) freedemon #include <stdio.h> unsigned char const hexchars[] = "0123456789abcdef"; char tohexchar (unsigned char c) { c &= 0x0f; return(hexchars[c]); } int main(int argc, char **argv) { unsigned char checksum; int count; char *command; char ch; if (argc <= 1) exit(1); printf("gdb protocol command: "); command = argv[1]; putchar ('$'); checksum = count = 0; while ((ch = command[count])) { putchar(ch); checksum += ch; count++; } putchar('#'); putchar(tohexchar(checksum >> 4)); putchar(tohexchar(checksum)); putchar('\n'); } На платформе MIPS операционная система IOS ведет себя иначе. На стадии инициализации она перепрограммирует MMU, запрещая модификацию кодового сегмента. Любая попытка записи в эту область вызывает крах системы и последующую перезагрузку маршрутизатора. Против непреднамеренной модификации этот механизм действует очень хорошо, но здравомыслящий хакер после пятого пива сможет легко обойти его. Идея заключается в отображении одной из физических кодовых страниц на область данных в записываемый регион. Аналогичный трюк, кстати говоря, используется и для модификации ядра NT. В частности, он применяется во многих брандмауэрах и утилитах Марка Руссиновича. |