2014-11-26 4 views
1

Представьте себе следующую уязвимый кодЭксплуатируя переполнение буфера операция чтения

int getNumber(int* array, int index) { 
    return array[index]; 
} 

int main(int argc, char** argv) { 
    int myArray = malloc(10 * sizeof(int)); 
    myArray[0] = 1; 
    myArray[1] = 5; 
    printf("%d\n", getNumber(myArray, atoi(argv[1]))); 
} 

Очевидно, запустив программу с ./hello 11 собирается вызвать программу либо аварии или сбросить что-то в памяти. Однако есть ли способ использовать эту программу для запуска произвольного кода (при привилегиях программы)? Или это единственный способ добиться выполнения кода из этого типа эксплойта, используя это, чтобы получить дамп памяти, который можно разобрать в полную кодовую базу?

+0

Каково ваше намерение? – Jagannath

+1

ЕСЛИ вы хотите массив ints, который вы должны сделать 'malloc (10 * sizeof (int))' –

+0

@Jagannath Я пытаюсь взломать заблокированное встроенное устройство (долгосрочная цель - запустить некоторый вкус Linux в теме). У меня нет доступа к кодовой базе, но сегодня вечером я обнаружил уязвимость, которая, будучи довольно сложной, концептуально содержит код, который у меня есть. (поэтому выполнение кода) – bobbybee

ответ

4

Это undefined behavior.

Вы можете сделать некоторые общие предположения о том, как реализованы кучи и компилятор. В пределах этой границы вы можете ограничить диапазон воздействия несколько «насколько это плохо» вероятно, чтобы иметь возможность получить (авария, как правило, для этого). Но за пределами угадывания ... для эффективного взлома вам понадобится разборка, чтобы узнать, какие инструкции компилятор сгенерировал для этого кода ... и у вас много данных о системе, чтобы связать это.

Вероятный эксплойт заключается в том, что у вас более широкое изображение программы и некоторые переменные, которые программист не ожидал, что вы сможете изменить, что вам удалось изменить - в пределах области песочницы, которой доверяет ОС. Вы показали нам очень короткую программу, которая вряд ли сможет многое использовать. Но если бы это была более крупная программа с большей функциональностью и где-то объявленная int privilegeLevel = 2; ... вы могли бы управлять на границе процесса программы, чтобы перезаписать privilegeLevel до 1 (давайте представим, что дает вам больше возможностей, чем ожидалось, lower = better). Затем вы используете определенный уровень доверия, который был предоставлен программе, основанный на убеждении, что у него не было таких ошибок.

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

Простейший эксплойт, как правило, просто «мы разбили U». Но чем более примитивна система, тем более вероятно, что вы можете найти смещение, когда программа загрузилась сама, обратите внимание на согласованные свойства, где malloc помещает вещи, и, возможно, использует некоторое отрицательное число и начинает писать в ядро ​​или код. В более сложных системах произвольное выполнение требует немного большей уязвимости, чем что-то малое в изоляции.

Я следую политике «информация хороша» в предоставлении такого совета. Будьте этичны.

Смежные вопросы