Направление вывода шеллкода в файл — C

Я использую этот код отсюда: Чтение и выполнение шелл-кода из файла . текстовый файл

#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <stdlib.h>

int main(void)
{
    FILE *file = fopen("text.txt", "r");
    unsigned char *buf;
    int length = 0;
    struct stat st;
    int v;

    // get file size and allocate. We're going to convert to bytes 
    // from text, so this allocation will be safely large enough
    fstat(fileno(file), &st);
    buf = valloc(st.st_size);
    while (fscanf(file, "\\x%02x", &v) == 1)
    {
        buf[length++] = v;
    }

    fclose(file);

    mprotect(buf, length, PROT_EXEC);

    int (*ret)() = (int (*)())buf;
    ret();

    return 0;
}

И я компилирую с помощью: gcc -fno-stack-protector -z execstack testshell.c -o testshell

Он работает нормально, но исполняемый им шелл-код пишет в терминал, но я хотел бы каким-то образом перенаправить его в файл.

Я попытался:

./testshell > output.txt

но, похоже, не смог получить и это, чтобы зафиксировать результаты шелл-кода.

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

Обновление: Шеллкод, который я использую, выводит вывод системного вызова sys_write в файловый дескриптор (вычисляет и выводит на экран) -

\xeb\x4d\x5e\x66\x83\xec\x0c\x48\x89\xe0\x48\x31\xc9\x68\x33\x09\x00\x7c\x48\x89\xcf\x80\xc1\x0c\x40\x8a\x3e\x40\xf6\xd7\x40\x88\x38\x48\xff\xc6\x68\x16\x96\xd0\xd9\x48\xff\xc0\xe2\xea\x2c\x0c\x48\x89\xc6\x68\xf2\xf5\x44\x48\x48\x31\xc0\x48\x89\xc7\x04\x01\x48\x89\xc2\x80\xc2\x0b\x0f\x05\x48\x31\xc0\x04\x3c\x0f\x05\xe8\xae\xff\xff\xff\x85\xa7\xaa\xc7\x9e\x87\xa5\xa5\x8e\xb7\x87\xba\x31\x80\xe0\x55\xef\xa1\x93\x0c\x4e\x1c\xdc\x34\x53\xb3\x8b\x43\x48\x68\x30\x1d\x4b\x65\x5b\x52\x41\x4e\x44\x53\x54\x52\x32\x5d

person user2059300    schedule 12.04.2015    source источник
comment
Это должно работать, если шелл-код пишет в stdout, а не в stderr. Попробуйте: ./testshell › output.txt 1›&2   -  person Deanie    schedule 12.04.2015
comment
fscanf формат "\\x%02x" является избыточным и вводит в заблуждение. Должно быть "\\x%2x"   -  person chqrlie    schedule 12.04.2015
comment
@Deanie Нет кубиков на 1>&2, вывод по-прежнему происходит в терминале, а не в output.txt   -  person user2059300    schedule 12.04.2015
comment
Я думаю, что он имел в виду ./testshell > output.txt 2>&1 для перенаправления как stdout, так и stderr на output.txt.   -  person David C. Rankin    schedule 12.04.2015
comment
@Deanie - я добавил шелл-код, который пытаюсь заставить работать, если это поможет.   -  person user2059300    schedule 12.04.2015
comment
@DavidC.Rankin Все еще не согласен, но спасибо, что взглянули на это еще раз. Я предоставил тестируемый шеллкод.   -  person user2059300    schedule 12.04.2015
comment
Как шелл-код пишет? Что он делает? Мы не собираемся разбирать его для вас — шелл-код, как правило, сильно зависит от платформы, и вы не определили, какую систему используете. (Конечно, довольно легко догадаться, что вы используете Linux на машине Intel, но это может быть 32-битная или 64-битная Linux, и что делает код оболочки, все еще нужно понимать, чтобы знать, как перенаправить его вывод , Если он открывает терминал и записывает в него, вам будет трудно избежать появления вывода, например, на терминале.   -  person Jonathan Leffler    schedule 12.04.2015
comment
@JonathanLeffler Это вывод системного вызова sys_write в дескриптор файла. Спасибо за вашу помощь.   -  person user2059300    schedule 12.04.2015
comment
Какой файловый дескриптор? 0, 1, 2 и т. д.?   -  person Jonathan Leffler    schedule 12.04.2015
comment
Это все еще в воздухе. Сброс в сборку показывает вызов fprintf, но перенаправление как stderr, так и stdout ничего не делает. Это похоже на использование ядра printf.   -  person David C. Rankin    schedule 12.04.2015
comment
@DavidC.Rankin: вот почему я указал 0 в качестве дескриптора файла-кандидата. Обычно это дубликат файловых дескрипторов 1 и 2, поэтому вы можете как записывать в 0 (стандартный ввод), так и читать из 1 и 2 (стандартный вывод и стандартная ошибка). Конечно, это совершенно не поддерживается и не переносимо (и вы не можете сделать это через файловые потоки stdin, stdout, stderr), но в таком случае шелл-код в целом тоже.   -  person Jonathan Leffler    schedule 12.04.2015
comment
Ха! Ты сделал это. ./testshell > output.txt 0>&1 работал нормально. Обучение произошло... Спасибо. Это первый и, надеюсь, последний раз, когда я сталкиваюсь с этим. Я слишком стар, чтобы учиться этим трюкам.   -  person David C. Rankin    schedule 12.04.2015
comment
Большое спасибо, ребята. Обучение действительно произошло :D ./testshell > output.txt 0>&1 Добавьте это как решение, и я отмечу его правильным и решенным!   -  person user2059300    schedule 12.04.2015
comment
@JonathanLeffler Рад, что это решило проблему. Пусть Джонатан опубликует ответ, он оставил след из хлебных крошек, чтобы остальные пошли за ним ....   -  person David C. Rankin    schedule 12.04.2015


Ответы (1)


Перенос комментариев в ответ с указанием заслуг там, где это необходимо.

Дини сказал:

Это должно работать, если шелл-код пишет в stdout, а не в stderr. Пытаться:

./testshell > output.txt 1>&2

На что user2059300, OP, ответил:

На 1>&2 кубиков нет, вывод все равно происходит в терминал а не в output.txt

И Дэвид С. Рэнкин сказал:

Я думаю, что он имел в виду ./testshell > output.txt 2>&1 для перенаправления stdout и stderr на output.txt.

Но user2059300 заявил:

По-прежнему не согласен с этим… Я предоставил шелл-код, который тестирую.

Тогда я спросил:

  • Как шелл-код пишет? Что он делает? Я не собираюсь анализировать это для вас; Шелл-код, как правило, сильно зависит от платформы, и вы не определили, какую систему используете. Конечно, довольно легко догадаться, что вы используете Linux на машине Intel, но это может быть 32-битная или 64-битная Linux, и что делает код оболочки, все еще нужно понимать, чтобы знать, как перенаправить его вывод. . Если он открывает терминал и записывает в него, вам будет трудно, например, избежать появления вывода на терминале.

И user2059300 заявил:

Это вывод системного вызова sys_write в файловый дескриптор.

побуждая меня спросить:

  • Какой файловый дескриптор? 0, 1, 2 или другое?

Дэвид С. Рэнкин отметил:

Это все еще в воздухе. Сброс в сборку показывает вызов fprintf, но перенаправление и stderr, и stdout ничего не делает. Это похоже на использование ядра printf.

И я возразил:

  • Вот почему я указал 0 в качестве дескриптора файла-кандидата. Файловый дескриптор 0 обычно является дубликатом файловых дескрипторов 1 и 2, поэтому вы можете как записывать в 0 (стандартный ввод), так и читать из 1 и 2 (стандартный вывод и стандартная ошибка). Конечно, делать поэтому полностью не поддерживается и не переносится (и вы не можете сделать это через файловые потоки stdin, stdout, stderr), но тогда шелл-код вообще непереносим.

И это, кажется, было ключевым. Дэвид С. Рэнкин подтвердил:

Ха! Ты сделал это. ./testshell > output.txt 0>&1 работал нормально. Обучение произошло… Спасибо. Это первый и, надеюсь, последний раз, когда я сталкиваюсь с этим. Я слишком стар, чтобы учиться этим трюкам.

то же самое сделал user2059300:

Большое спасибо, ребята. Обучение действительно произошло. ./testshell > output.txt 0>&1

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

person Jonathan Leffler    schedule 12.04.2015