Как XOR предотвращает пустые байты в шеллкоде - PullRequest
0 голосов
/ 29 декабря 2018

Я пытался следовать этому уроку (https://paraschetal.in/writing-your-own-shellcode) о том, как написать свой собственный шелл-код. 99% этого имеет смысл для меня, но у меня есть только две долгие сомнения - это относится к написанию шелл-кодав общем

Во-первых, я думаю, что понимаю , почему мы хотим избежать нулевого байта, но как использует следующие избегающие нулевые байты?

xor eax, eax

Разве eax теперь не содержит в точности нулевых байтов? Или он содержит 0? Когда мы что-то XOR с собой, он возвращает False, правильно?

Во-вторых, учебник говорит:

Наконец, мы загрузим номер системного вызова (11 или 0xb) в регистр eax. Однако если мы используем eax в нашей инструкции, результирующий шелл-код будет содержать несколько байтов NULL (\ x00), и мы не будемхочу, чтобы. Наш eax-регистр уже имеет значение NULL. Поэтому мы просто загрузим номер системного вызова в al-регистр вместо всего eax-регистра.

mov byte  al, 0x0b

Теперь я понимаю, что происходитздесь число 11 (для execve) загружается в первые 8 бит регистра eax (то есть al).Но остальная часть eax все еще содержит нулевые байты, так что именно здесь достигается?

Пожалуйста, обратите внимание, что я приехал сюда в качестве крайней меры, потратив большую часть дня, пытаясь понять это, поэтому, пожалуйста, примитемне легко:)

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Инструкция mov eax, 0 собирается в

b8 00 00 00 00

, который содержит NUL байтов.Однако инструкция xor eax, eax собирается в

31 c0

, который не содержит байтов NUL, что делает ее пригодной для шелл-кода.

То же самое относится к mov al, 0x0b.Если вы сделаете mov eax, 0x0b, кодировка будет

b8 0b 00 00 00

, которая содержит NUL байтов.Однако mov al, 0x0b кодирует в

b0 0b

, избегая байтов NUL.

0 голосов
/ 29 декабря 2018

Эксплойты обычно атакуют код C, и поэтому код оболочки часто необходимо доставлять в NUL-оканчивающейся строке .Если код оболочки содержит NUL-байты, то используемый код C может игнорировать и удалить остаток кода, начиная с первого нулевого байта .

Это касается только машинный код .Если вам нужно вызвать системный вызов с номером 0xb, то, естественно, вам нужно иметь возможность генерировать число 0xb в регистре EAX, но вы можете использовать только те формы машинного кода, которые не содержат нулевых байтов в самом машинном коде..


xor eax, eax

будет инвертировать все 1 бит в eax, то есть ноль it.Он является функциональным эквивалентом

mov eax, 0

, за исключением того, что последние будут иметь нулевой код в нулевом байте в машинном коде *1028*.


Машинный код для

xor eax, eax
mov byte al, 0x0b

равен

31 c0 b0 0b

Как видите, в нем нет встроенных нулевых байтов.Машинный код для

mov eax, 0xb

:

b8 0b 00 00 00

Обе эти программы функционально эквивалентны в том смысле, что они устанавливают значение регистра EAX равным 0xb.

Если последнийкод оболочки обрабатывается C-программой как строка с нулевым символом в конце, а остальная часть после b8 0b 00 может быть отброшена программой и заменена другими байтами в памяти, что по существу делает шеллкод неработающим.

...