Я делаю простой пример переполнения кучи: при компиляции кода я использую флаги -m32
, -no-pie
, -fno-stack-protector
и -z execstack
. Я могу вызвать сбой программы, если просто отправлю строку прямо с терминала. Например, «АААААА....ААА», но когда я пытаюсь использовать python2, программа не выходит из строя, хотя я использую очень большое количество букв «А».
Пример:
./exe 'python2 -c"print 'A'*100"'
Код С:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define BUFFER_SIZE 32
int main(int argc, char** argv)
{
char *a = malloc(BUFFER_SIZE);
char *b = malloc(BUFFER_SIZE);
strcpy(a, argv[1]);
free(a);
free(b);
return 0;
}
Я пробую следующие команды:
./simple 'python2 -c"print A*100"'
./simple python2 -c"print A*100"
./simple 'python2 -c"print 'A'*100"'
./simple python2 -c"print 'A'*100"
./simple python2 -c"print('A'*100)"
Это на виртуальной машине с Ubuntu 22.04.4 LTS
и python 2.7.18
.
Я могу создать переполнение, вручную набрав много букв A или создав скрипт Python.
Прошу прощения за неточность, это мой первый вопрос.
Я пытаюсь отправить команду python2
в разных формах. Я также пытаюсь напрямую использовать полезную нагрузку, что-то вроде ./simple < payload
. но это всегда приводит к сбою программы независимо от того, сколько букв A содержится в полезной нагрузке.
Не помечайте C++ для вопросов C.
Одинарные кавычки не выполняют команду. Для этого вам нужны обратные кавычки. Как сейчас написано, вы отправляете 23-байтовую строку python2 -c"print A*100"
в свою программу. Об этом вам скажет очень элементарная отладка. Например: printf("(%s)\n", argv[1]);
мой python3.12 также говорит, что его нужно заключить в круглые скобки print('A'*100)
@yano, текст вопроса указывает на то, что ОП использует Python 2.x, где скобки не требуются с print
.
Поэтому я пробую следующие команды: ./simple 'python2 -c"print A*100"'
./simple python2 -c"print A*100"
./simple 'python2 -c"print 'A'*100"'
./simple python2 -c"print 'A'*100"
./simple python2 -c"print('A'*100)"
Ни одна из них не работает, я смог выполнить эксплойт напрямую, отправив сообщение из скрипта Python.
Пожалуйста, внимательно прочитайте комментарий @paddy, он указывает вам правильное направление. Посмотрите документацию, как выполнить внутреннюю команду и использовать ее вывод в виде текста во внешней команде. -- Вместо вашей программы используйте echo
, чтобы увидеть результат.
Как вы ожидаете, что эти другие варианты будут работать, если они содержат ту же ошибку, упомянутую Пэдди, что и ваш первоначальный вариант? Вы добавили отладку, упомянутую Яно? Он должен сразу сказать вам, что не имеет значения, сколько A
вы пытаетесь предоставить, потому что вся ваша настройка неверна.
Мы понимаем, что во многих шрифтах они могут выглядеть одинаково, но '
и `
на самом деле не являются одним и тем же символом, и оболочка обрабатывает их по-разному. Прочтите комментарий Пэдди еще раз.
./simple 'python2 -c"print A*100"'
Запускает вашу программу с установленным argv[1]
в строке python2 -c"print A*100"
.
Вы можете и должны проверять, что на самом деле происходит в вашей программе, каждый раз, когда это вас удивляет, с помощью одного или нескольких из:
Добавление операторов печати, чтобы ваша программа могла подтвердить свое внутреннее состояние, соответствует вашим ожиданиям, например:
printf("argc=%d, argv[1]=%s\n", argc, argv[1]);
Отладка с помощью GDB или любого другого доступного отладчика. Если вы не знаете, как его использовать, самое время научиться. Если вы даже не знали, что он существует, то, где бы вы ни изучали C, это ужасно.
У всех есть ошибки. Каждый учится отлаживать свой код. Это нормально и ожидается, что вы приложите некоторые усилия, чтобы понять, что на самом деле делает ваша программа (и здесь я включаю конвейер оболочки, который является вашей настоящей проблемой: это тоже код).
./simple < payload
это просто совершенно неправильно. Перенаправление ввода меняет то, к чему подключен stdin
, но вообще не влияет на argv
. Прочтите документацию к вашей оболочке, чтобы узнать, какой еще синтаксис может быть полезен.
Пожалуйста, отредактируйте свой вопрос и опубликуйте свой настоящий код C. То, что вы опубликовали, - это не код C, а псевдокод.