Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 [ 43 ] 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

int ret

SaveVictim endp

WriteFName proc

near

push

push

si, 9Eh

NxtChar:

lodsb

al, 0

LastChar

dl, al

ah, 02h

NxtChar

LastChar:

WriteFName endp

GetFSize

mov mov xor xor int mov " mov xor xor int xor ret GetFSize

proc near ax, 4202h bx, FHandle cx, cx dx, dx 21h

FSize, ax ax, 4200h dx, dx cx, cx

ax, ax endp

TruncFile proc near

; Перейти на 92 байта от конца файла

bx, FHandle

al, 2

dx, 92

call

FileSeek

ah, 40h

bx, FHandle

dx, offset Buffer

cx, cx ; Писать 0 байт - отрезать файл

; no текущей позиции

TruncFile

endp

segOOO ends

start

В качестве сигнатуры вируса выбраны 12 байт от начала вируса. Поскольку по( кий пишется в начало файла, то не нужно рассчитьшать смещение сигнатуры для ка го файла в зависимости от его размера.

Подпрограмма ChkSgn проверяет сигнатуру и присваивает переменной SgnS одно из трех значений:

0 - незараженный файл,

1 - зараженный файл,

2 - "голый" вирус.

Реакция на эти значения следующая:

0 - просто сказать - Ок;

1 - вычистить вирус и сообщить о вычищении;

2 - сообщить, что файл пришлось стереть, что и сделать после-его закрытия. Для повышения скорости работы приняты, например, такие меры, как отказ от

верки слишком маленьких файлов (менее 92 байт). Сама проверка сигнатуры реали: на через команду cmpsb (хотя можно и еще ускорить, заменив cmpsb на cmpsw и в уменьшив начальное значение сх).

И последнее. Изготовление антиврфусов из вирусов - отличная тренировка в ассембле программировании, но все же не из любого вируа можно быстро сделать антш (из полиморфных и пермутирующих в особенности). Столкнувшись с вирусом, хотя бы Ким примитивным, вживую, подумайте дважды: а стоит ли делать антивирус из i Написать с нуля может быть и быстрее, и надежнее.



•дава 4. Ассемблер в операционной системе Linux 273

Глава 4

Ассемблер

в операционной системе Linux

ос Linux давно получила широкое распространение не только среди системных администраторов, но и среди обычных пользователей, применяющих эту надежную и безопасную операционную систему с открытым кодом в качестве своей домашней рабочей станции. Под эту операционную систему экспортированы самые популярные пакеты программного обеспечения или написаны подобные.

Помимо популярности данной ОС среди обычных пользователей, считается, что Linux - одна из самых безопасных операционных систем, именно по этой причине Linux устанавливается на сервера Интернета, корпораций и небольших предприятий. В отличие от изделий таких компаний, как Microsoft, HP, Sun Microsystems, Linux - продукт бесплатный и с открытым исходным кодом.

На практике же сервера под управлением открытых систем (Linux, FreeBSD) взламываются чаще других. Дело не в самой операционной системе, а, скорее, в программах, которые на этой ОС используются. Так как сами исходные коды открыты, то многие хакеры исследуют программную реализацию тех или иных компонентов серверов. Цели у всех разные: кто-то ищет ошибки, кто-то учится писать свои программы и рассматривает алгоритмы, но результат один - нахождение ошибок и их исправление.

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

хакерами, пытающимися переписать ядро; Ш хакерами, пытающимися взломать систему.

С точки зрения защиты информации для нас представляет интерес вторая категория хакеров. К этой группе можно также добавить авторов компьютерных вирусов (KB), ДЛ" которых, порой, просто необходимо реализовать код KB на ассемблере. Рассмотрим примеры программ, используемых хакерами для нанесения конкретного вреда системе, и борьбы с ними.

4.1. Синтаксис

Как уже говорилось выше, сама операционная система написана на языке С. Все сис-5мные функции также реализованы на этом языке с небольшими вставками ассемблера (,ри использовании системных вызовов BIOS и прямого обращения к памяти. Существует несколько видов синтаксиса ассемблера под Linux. Привыкшие к синтаксису, предложенному компанией Intel (он используется при написании программ под DOS и Windows), могут вздохнуть облегченно - есть компиляторы (nasm), поддерживающие именно такой, экзотический для Linux, синтаксис, хотя истинные хакеры используют творение AT&T (gas).

Основное отличие их в том, что названия регистров в AT&T синтаксисе не зарезервированы, что приводит к необходимости выполнения лишних действий - подстановкам суффиксов, о которых и пойдет речь.

Названия регистров те же, что и у Intel, но проблема заключается в том, что компилятор не поймет вас, если вы просто укажете их имена. Обязательным является подстановка суффикса % перед названием регистра:

leax

Кстати говоря, Linux является 32-разрядной операционной системной и изначально разрабатывалась для процессоров Intel 386. Так что речь пойдет об ассемблере для процессоров компании Intel.

Вернемся к синтаксису. Использование суффиксов позволяет использовать перемен-Hbie с именами регистров, что, в некоторых случаях, может лишь усложнить написание программы или, в конце концов, просто запутать самого разработчика.

В то же время перед переменными ставится знак $:

$10000 $Ox£ffO

Вы, наверное, обратили внимание на SOxfffO. Ох - это обозначение шестнадцатерич-ного числа. Такое замечание может показаться лишним, если вы писали программы на С "о в данном случае я сравниваются синтаксисы Intel и AT&T.

Далее перейдем непосредственно к самим командам. К командам подставляется пост-фикс, который зависит от того, с каким объемом данных она работает. Если команда пере-"ьиает байт, то подставляется Ь, если работает со словом, то подставляется w, если работа- с двойным словом, то подставляется 1, если используется учетверенное слово - q.

Кстати, что касается работы с операндами: если необходимо что-то поместить в при-Ник, то операцию следует рассматривать слева направо. Иначе говоря, для того чтобь "честить байт $Оха в регистр %al, необходимо выполнить следующую команду:



Ассемблер в задачах защиты инфо

movb $Oxa,%al

Стоит отметить очень примечательный префикс - префикс 1, обозначающий да передачу управления. Он используется с такими командами, как jmp, ret, call:

Icall $proc

В синтаксисе AT&T вместо квадратных скобок используются круглые:

movl (%bpx),%eax

Операторы ассемблера такие же, как и в С, поэтому они приводиться не будут. Еуцц учиться программировать по ходу рассмотрения гфимеров.

4.2. Системные вьвовы

Системные вызовы - неотьемлемая часть программы на ассемблере, если, конечно, мы не пишем программу с использование библиотеки glibc.

Все системные вызовы имеют свой номер, который можно узнать, посмотрев файл /usr/include/sys/syscall.h.

Параметры в эти вызовы передаются следующим образом: если их меньше шести, то они передаются через регистры, как это было в DOS, с условием, что в регистр %еах помещается номер системного вызова, а аргументы помещаются в %еЬх, %есх, %edx, %esi, %edi в указанном порядке. Результат помещается в регистр %еах.

Рассмотрим нашу первую программу.

.data

hello:

main:

.string

"hello world\

length =

. - $hello

main

movl

4,%eax

movl

l,%ebx

movl

$hello,%ecx

movl

$length,%edx

$0x80

movl

l,%eax

xorl

°iebx,%ebx

$0x80

Системный вызов writeQ принимает следующие параметры:

•,ава 4- Ассемблер в операционной системе Linux 275

I дескриптор файла;

I адрес буфера, хранящего строку;

g длину буфера.

Передаем эти параметры через соответствующие регистры в их законном порядке: «/„еЬх - дескриптор стандартного вывода (Linux имеет три стандартных устройства вво-да-вывода: stdin - ввод, stdout - вывод, stderr - стандартная ошибка), равный 1, адрес нашего буфера, содержащего строку, помещаем в %есх, а длину строки (В DOS это мог-10 быть вычислено так length = $ - hello) - в %edx. Далее вызываем прерывание $0x80, которое уже передает все данные ядру. Второй системный вызов, вызов exit(), принимает один параметр - код завершения (О - программа завершилась удачно), который мы поместили в регистр %еЬх.

Если параметров у системного вызова больше, то необходимо их все поместить в память, а указатель - в %еЬх.

43. Как это делают хакеры

Нет особого смысла в описании всех методов взлома систем. Данная часть книги посвящена ассемблеру в Linux, поэтому рассмотрим лишь самые популярные методики. В любом случае все сводится к одному - передать управление на shell-code, чтобы получить управление или выполнить команды.

Shell-code - программа, написанная на ассемблере и хранящая все свои данные в одном сепченте с кодом. В среде хакеров считается хорошим стилем написание очень коротких shell-кодов, так как это говорит о знании ассемблера и качественной алгоритмической базе.

Как уже говорилось, в программных продуктах, функщюнирующих вместе с ОС, допускается большое количество ошибок. Многие из них можно использовать для получения каких-то привилегий в операщюнной системе или для выполнения команд. Для этого хакерами используются такие ошибки, как:

переполнение буфера;

ошибки форматной строки;

ошибки работы с указателями;

• неправильная работа с памятью.

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

Приведем пример программы, подверженной ошибке переполнения буфера.

♦include <string.h>

int 4ain

int argc, char* argv[])



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 [ 43 ] 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88