Может ли кто-нибудь помочь мне понять этот код asm (это короткий) - PullRequest
1 голос
/ 15 февраля 2011

я пытаюсь узнать шеллкод для проекта в компьютерной науке

но у меня возникли проблемы с написанием Я читаю книгу под названием «Руководство по Shellcoder» и это дает мне код, который не будет работать должным образом Это код:

    section     .text
    global _start
_start:
    jmp short      GotoCall
shellcode:
     pop            rsi
     xor            rax, rax
     mov  byte      [rsi + 7], al
     lea            rbx, [rsi]
     mov            [rsi + 8], rbx
     mov            [rsi + 14], rax
     mov  byte      al, 0x0b
     mov            rbx, rsi
     lea            rcx, [rsi + 8]
     lea            rdx, [rsi + 14]
     int            0x80
GotoCall:
     Call            shellcode
     db             '/bin/shJAAAAAAKKKKKK'

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

mov  byte      [rsi + 7], al

это вывод gdb: GDB ./sclivro

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400085 in _start ()
(gdb) disas _start
Dump of assembler code for function _start:
0x0000000000400080 <_start+0>:  jmp    0x4000a2 <_start+34>
0x0000000000400082 <_start+2>:  pop    %rsi
0x0000000000400083 <_start+3>:  xor    %rax,%rax
0x0000000000400085 <_start+5>:  mov    %al,0x7(%rsi)
0x0000000000400088 <_start+8>:  lea    (%rsi),%rbx
0x000000000040008b <_start+11>: mov    %rbx,0x8(%rsi)
0x000000000040008f <_start+15>: mov    %rax,0xe(%rsi)
0x0000000000400093 <_start+19>: mov    $0xb,%al
0x0000000000400095 <_start+21>: mov    %rsi,%rbx
0x0000000000400098 <_start+24>: lea    0x8(%rsi),%rcx
0x000000000040009c <_start+28>: lea    0xe(%rsi),%rdx
0x00000000004000a0 <_start+32>: int    $0x80
0x00000000004000a2 <_start+34>: callq  0x400082 <_start+2>
0x00000000004000a7 <_start+39>: (bad)  
0x00000000004000a8 <_start+40>: (bad)  
0x00000000004000a9 <_start+41>: imul   $0x414a6873,0x2f(%rsi),%ebp
0x00000000004000b0 <_start+48>: rex.B
0x00000000004000b1 <_start+49>: rex.B
0x00000000004000b2 <_start+50>: rex.B
0x00000000004000b3 <_start+51>: rex.B
0x00000000004000b4 <_start+52>: rex.B
0x00000000004000b5 <_start+53>: rex.WXB
0x00000000004000b6 <_start+54>: rex.WXB
0x00000000004000b7 <_start+55>: rex.WXB
0x00000000004000b8 <_start+56>: rex.WXB
0x00000000004000b9 <_start+57>: rex.WXB
0x00000000004000ba <_start+58>: rex.WXB add    %bpl,(%r14)
End of assembler dump.

Я компилирую код, используя yasm и ld

yasm -f elf64 sclivro.asm

ld -o sclivro sclivro.o

Моя ОС - Debian 6.0 x64

У меня процессор Intel Celeron

Я хотел знать, почему я получаю ошибку ошибки сегмента и объясни мне.

Спасибо за ваше время.

Также в книге сказано, что я должен выполнить следующие шаги:

  1. Заполните EAX нулями, хранив EAX с собой.

  2. Завершите нашу строку / bin / sh, скопировав AL поверх последнего байта строка. Помните, что AL является нулевым, потому что мы обнулили EAX в предыдущих ous инструкция Вы также должны рассчитать смещение от начала строка для заполнителя J.

  3. Получить адрес начала строки, который хранится в ESI, и скопируйте это значение в EBX.

  4. Скопируйте значение, сохраненное в EBX, теперь адрес начала строка, над заполнителями AAAA. Это указатель на аргумент исполняемый двоичный файл, который требуется execve. Опять надо рассчитать смещение.

  5. Скопируйте нули, все еще сохраненные в EAX, через заполнители KKKK, используя правильное смещение.

  6. EAX больше не нужно заполнять нулями, поэтому скопируйте значение нашего выполнить системный вызов (0x0b) в AL.

  7. Загрузите EBX с адресом нашей строки.

  8. Загрузить адрес значения, хранящегося в заполнителе AAAA, который является указатель на нашу строку в ECX.

  9. Загрузите EDX с адресом значения в KKKK, указатель на ноль.

  10. Выполнить int 0x80.

Ответы [ 2 ]

3 голосов
/ 15 февраля 2011

Размещенный вами шелл-код предназначен для Linux, работающего на 32-битном процессоре x86 - как видно из использования "int 0x80" в качестве инструкции системного вызова.

Вы скомпилировали его в 64-битном режимеВпрочем, и попытался это запустить.Что не удается при первом доступе к памяти, потому что вы не используете адрес real строки "/ bin / sh" (который находится в RSI), а только явно урезанный младший 32-битный (так как в вашем коде явно указано ESI).Последнее недопустимо в 64-битном режиме, где ваш стек находится где-то на верхнем конце 0xffff....(64bit addr) адресного пространства.

1 голос
/ 15 февраля 2011

Инструкция pop rsi получает адрес строки.

Вы перезаписываете защищенную от записи область, когда пытаетесь поставить нулевой байт после / bin / sh. Я не уверен, почему этот код должен быть особенным: он выглядит как запутанный вызов execve ().

...