Простое переполнение буфера, перезапись EIP не работает

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

Я пытался использовать этот код переполнения буфера в течение нескольких недель, я просто не знаю, в чем хитрость!

Я контролирую EIP при перезаписи с помощью \x41 или любого другого символа, но когда я пытаюсь перезаписать адрес возврата действительным адресом, SIGSEGV указывает на другой адрес, адрес, который перехватывает SIGSEGV, действительно содержит весь мой шелл-код и мой 41-й и т.д.

У меня есть защита стека отключения, и стек RWE, я также проверил наличие плохих символов и нашел код оболочки, который не содержит никаких плохих символов. Если бы кто-нибудь мог помочь, это было бы признательно, так как я хочу прогрессировать, а онлайн-ресурсы, похоже, не охватывают мою проблему. Я прочитал Smashing the stack для развлечения и получения прибыли и понимаю основы, очень минимальные основы сборки, я прочитал большинство руководств в Интернете, они по большей части избыточны, я читал все статьи о стеке, которые я считаю относящимися к моему сценарию, пожалуйста кто-нибудь из вас, профессионалы, попытается понять, в чем моя проблема.

uname -вывод:

Linux windows 4.14.15-1-ARCH #1 SMP PREEMPT Tue Jan 23 21:49:25 UTC 2018 x86_64 GNU/Linux

Вот код:

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

void validate(char *pass) {
    if (strcmp(pass, "[REDACTED]") == 0) {
        printf("ACCESS GRANTED!");
        printf("Oh that's just idio... Oh my god!\n");
    } else {
        printf("Damn it, I had something for this...\n");
    }
}

int main(int argc, char** argv) {
    char password[200];
    printf("C:/ENTER PASSWORD: ");
    scanf("%s", password);
    validate(password);
    return 0;
}

Вот Payload, содержащий шеллкод, 28 байт:

payload = "\x90"*132+ret+shell+"A"*44

вот шеллкод:

\x50\x48\x31\xd2\x48\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x54\x5f\xb0\x3b\x0f\x05

Бадчары это:

totalbad = "\x09\x0a\x0b\x0c\x0d\x20"

person zeroskilz    schedule 11.02.2018    source источник
comment
Я думаю, чтобы выполнить ваш шелл-код, вам нужно пойти и изменить GOT из exit, чтобы он перешел на начальный адрес password (где будет полезная нагрузка) при выходе из вашей программы. Поскольку, когда программа завершается и вызывает exit, она разрешает адрес exit с помощью динамического загрузчика. Итак, в кратком объяснении, exit на самом деле вызовет exit.PLT, который будет использовать exit.GOT для получения адреса фактического exit, который, вероятно, находится в libc.so, если вы динамически скомпоновали исполняемый файл. Для статически связанных это совсем другая история. Надеюсь, это поможет~   -  person Seoul    schedule 11.02.2018
comment
Спасибо за ваш ответ! Итак, чтобы изменить это, я должен ввести больше кода или просто изменить исходный код, а затем скомпилировать? Также каково объяснение того, почему, когда я перезаписываю EIP с помощью A или B, он перезаписывается идеально, но когда я пытаюсь перезаписать обратным адресом, он переключает по крайней мере последний байт адреса? Спасибо еще раз!   -  person zeroskilz    schedule 11.02.2018
comment
Просто чтобы уточнить, что GOT — это аббревиатура от Global Offset Table?   -  person zeroskilz    schedule 11.02.2018


Ответы (1)


Итак, исходя из вашей истории, проблема заключается в обратном адресе. Ваш неверный адрес возврата — 0x41414141, который равен 'AAAA' и не содержит NULL-байт. Затем вы пытаетесь использовать свой «действительный» адрес возврата, который содержит байт NULL, так что scanf("%s", password); перестанет читаться со стандартного ввода. Помните, что здесь scanf читает строку, которая заканчивается NULL, и если ваш адрес возврата содержит NULL байт, он остановится, и это объяснит, почему ваша полезная нагрузка неполная, шеллкод и 'A' * 44 не копируются. Помните, что я только догадался, что адрес содержит NULL байт, потому что, судя по вашей истории, проблемы начались, когда вы изменили обратный адрес на действительный адрес.

person whoami    schedule 30.03.2021