Надежное тестирование шеллкода

Предполагается, что код, подобный приведенному ниже, может «тестировать» шелл-код, а именно выполнять его.

char shellcode[] = "...";

int main(int argc, char **argv)
{
    int (*func)();
    func = (int (*)()) shellcode;
    (int)(*func)();
}

Однако, когда я пытаюсь использовать такие примеры, я получаю то, что код, кажется, выполняется в памяти, которая не является исполняемой, потому что он получает segfault при самой первой инструкции шелл-кода.

Если вместо этого я изменю объявление шелл-кода на #define, я смогу заставить шелл-код выполняться. Однако шелл-код останавливается, когда пытается записать в свою собственную память (этот шелл-код предполагает, что он выполняется в стеке).

Итак, мой вопрос заключается в том, какой самый простой и надежный способ протестировать шелл-код, предполагающий исполняемую (очевидно) и доступную для записи память? Если я выделю код в стеке или куче и попытаюсь перейти к нему, я просто столкнусь с NX-битной защитой и снова потерплю неудачу. Теперь, очевидно, я мог бы отключить бит NX, но нет ли лучшего способа провести это тестирование?


person ioctlvoid    schedule 14.01.2013    source источник
comment
возможный дубликат мер безопасности Linux против выполнения шеллкода   -  person Flexo    schedule 14.01.2013


Ответы (2)


Выделите доступную для записи и исполняемую область памяти (например, с mmap и mprotect) и поместите туда свой код, а затем вызовите его, как это делает ваш main. В случае защиты исполняемого пространства, такой как W^X, PaX и т. д., вы можете сначала сделать свою область памяти доступной для записи для копирования шелл-кода, а затем исполняемой только для его выполнения, но ваш пробег может варьироваться в зависимости от защиты (й) на месте. .

person Michael Foukarakis    schedule 12.03.2013

Если все, что вам нужно, это проверить функциональность, вы можете просто написать соответствующую сборку в функции. Тем не менее, это просто проверит сборку, а не шелл-код как байтовую строку, и если ваш шелл-код строго не сгенерирован сборкой (например, если вы перейдете к середине «несуществующей» инструкции), это не сработает. В этом случае вы должны поместить свой код в исполняемую память. Вы можете выделить его самостоятельно или перезаписать существующий раздел .text (хотя вам нужно будет отключить только чтение).

person Yuri Ro    schedule 19.01.2015