Python и Bash по-разному обрабатывают hex (шеллкод)?Противоречивые? - PullRequest
0 голосов
/ 02 июня 2018

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

Если кто-нибудь сможет меня просветить, я буду очень признателен.


1.

Изначально я использовал python для сценариев, когда выполнял эти задачи ив частности, этот пример:

python -c 'print "AAAAA\xcc\xd5\xff\x4f"' > a

и последующее просмотр стека в GDB:

    format string> 
    0xffffd550: 0xffffd584  0xf7ffdab8  0x41f95300  0x41414141
    0xffffd560: 0x95c38cc3  0x0a4fbfc3  0xf7e2ec00  0xf7f8f820

Теперь похоже, что он не появляется после «AAAAA» (используется 5, поскольку не выровнен).


2.

Однако, когда я использую другой адрес, с которым я ранее работал:

python -c 'print "AAAAA\x5c\x57\x55\x56"' > a

, я получаю:

    format string> 
    0xffffd550: 0xffffd584  0xf7ffdab8  0x41f95300  0x41414141
    0xffffd560: 0x5655575c  0x0000000a  0xf7e2ec69  0xf7f8f820

И, кажется, прекрасно?


3.

Кроме того, когда я использую что-то вроде:

echo -en "AAAAA\xcc\xd5\xff\x4f" > b

Я могу правильно установить значение в стеке так:

format string> 
0xffffd550: 0xffffd584  0xf7ffdab8  0x41f95300  0x41414141
0xffffd560: 0x4fffd5cc  0x00000000  0xf7e2ec69  0xf7f8f820

Ниже приведены выходные данные файлов a и b соответственно:

AAAAA���O
AAAAAÌÕÿO

1 Ответ

0 голосов
/ 03 июня 2018

Проблема с первым примером состоит в том, что ваша строка содержит значения больше 0x7F.Когда Python выводит строку, он решает (в зависимости от вашей системы и языковых настроек), что он должен записать символы в формате UTF-8.

UTF-8 выражает символы 0x7F и ниже как сами по себе, поэтому A и x4f символы записываются без изменений.Однако UTF-8 выражает символ со значениями выше 0x7F как последовательность из нескольких байтов.В этом случае символы больше 0x7F являются \xcc, \xd5 и \xff.Кодировки UTF-8 для этих символов: 0xC3 0x8C, 0xC3 0x95 и 0xC3 BF соответственно.Это те значения, которые отображаются в вашем дампе памяти.

Вы можете обойти это, заставив Python выдавать строку, используя кодировку, которая обрабатывает значения выше 0x7F, передавая их как сами по себе, без преобразования.«latin1» - это такая кодировка, так что вы можете использовать эту команду:

python 'print u"AAAAA\xcc\xd5\xff\x4f".encode("latin1")'

, но это ужасно.

Кроме того, версии Python всегда выдают символ новой строки (0x0A) в концестроки.Он появляется в дампе памяти в слове после значений, которые вы намеревались передать.Вы можете обойти это, написав:

python -c 'import sys; sys.stdout.write(u"AAAAA\xcc\xd5\xff\x4f".encode("latin1"))'

, но это еще страшнее.

Я бы забыл попробовать использовать для этого однострочник Python и придерживаться подхода echo -ne.

...