Мечтать в обратном инжиниринге

Каждую неделю в Holberton School нам выдают 2–3 набора задач, в которые всегда входят дополнительные задачи повышенной сложности. На четвертой неделе нам дали исполняемую программу, написанную на C, которая принимает определенный пароль. Перед нами стояла задача создать генератор случайных паролей, возвращающий учетные данные для исполняемого файла. Цель этого упражнения - познакомить нас с сборкой и обратным проектированием, процессом, при котором для данного программного обеспечения делается попытка воссоздать его исходный код. Для этого проекта я использовал GNU Project Debugger (GDB), который может дизассемблировать программу в удобочитаемый ассемблерный код.

Моими целями были дизассемблировать исполняемый файл Linux, определить параметры, по которым проверяется пароль, и, наконец, создать программу на языке C, которая случайным образом генерирует действительные пароли. Обучение чтению ассемблерного кода показалось мне полезным в этом упражнении, поэтому я решил сделать это в первую очередь.

Используя GDB и другие инструменты, я смог просмотреть скомпилированный ассемблерный код и шаг за шагом увидеть, что происходит в исполняемом файле. Я устанавливал точки останова по всей программе и проверял, как обрабатываются данные, хранящиеся в адресных регистрах памяти. Потратив целый день на попытки разобрать биты ассемблерного кода путем чтения его шестнадцатеричных выходных данных, я нашел общий формат исходного исходного кода.

Используя GDB, я сначала разобрал основную программу, чтобы просмотреть вызываемые функции. Я заметил две стандартные библиотечные функции printf и put, а также функцию контрольной суммы.

(Http://imgur.com/a/cq0xU)

Используя другой инструмент, ltrace, я смог увидеть, что было два вызова функции put и что они вернули Доступ разрешен и Доступ запрещен соответственно.

Следующим шагом было изучение функции контрольной суммы. Разобрав его, я увидел, что существует цикл, который выполняет итерацию по строке пароля, суммирует значение ascii каждого символа и сохраняет результат в стеке. Это говорит о том, что параметры пароля зависят от суммы вводимых символов (точнее, от кодов ASCII этих символов).

(Http://imgur.com/a/CyzXR)

Однако нигде в функции контрольной суммы не сравнивается сумма моей строки с чем-либо. Вместо этого проверка происходит в основной функции.

По адресу 0x4005e9 после вызова функции контрольной суммы я вижу cmpq, инструкцию сравнения: она сравнивает контрольную сумму (хранящуюся в стеке) с непосредственным значением $ 0xad4. Это непосредственное значение представлено в шестнадцатеричном формате. (Вы знаете это, потому что по соглашению число, начинающееся с 0x, является шестнадцатеричным числом.) При преобразовании в основание 10 это 2772, поэтому, чтобы получить доступ к исполняемому файлу, просто введите строку, значение ascii символов которой составляет 2772.

массив символов [63] = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;

символьный пароль [100];

srand (время (NULL));

сумма = 0;

i = 0;

в то время как (сумма ‹(2772–122))

{

r = rand ()% 62;

пароль [i] = массив [r];

сумма = сумма + пароль [i];

i++;

}

r = 2772 - сумма;

пароль [i] = r;

Четырнадцать часов в этом упражнении я наконец получил свой генератор случайных паролей. Моя программа непрерывно добавляет случайный буквенно-цифровой символ к массиву, пока сумма символов не станет одной буквенной из 2772, а затем добавляет последний символ, который завершает суммирование до 2772.

Моя логика была правильной, и все индикаторы указывали на правильность моих выводов. Я дважды, трижды и четыре раза проверил строку и ее сумму, чтобы быть уверенным, но мне все равно было отказано в доступе. Это был долгий день (до ночи), и мой код остался нетронутым.

Лежа в постели, я чувствовал себя побежденным. Я потратил так много времени на изучение кода сборки, что было, безусловно, самой сложной частью задания, но я не мог заставить работать мою простую программу генератора случайных паролей. Я заснул, снова и снова повторяя логику своего кода.

Мне снился день, который я провел в Холбертоне, обед, который я ел, люди, с которыми я разговаривал, и дневные уроки по указателям и массивам. Все это время код моего генератора паролей отображался на заднем плане, как какой-то телесуфлер. А потом я увидел это: нулевой символ - «\ 0» - управляющий символ в C, обозначающий конец строки. Ни один из моих случайно сгенерированных паролей не содержал нулевого символа! Таким образом, хотя сумма символов составила 2772, когда моя программа попыталась напечатать строку, она не знала, где остановиться. Он будет пытаться прочитать другие блоки памяти, используемые в настоящее время или заполненные мусором, пока в конечном итоге не найдет нулевой символ.

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

В настоящее время я учусь в Holberton School, названной в честь Бетти Холбертон, одной из первых женщин-пионеров в области компьютеров. Говорят, что Бетти часто мечтала о программировании, и она решала многие проблемы во сне. Как и Бетти, мой разум не останавливается, когда рабочий день заканчивается в 5:00 или даже во время сна. Я надеюсь пойти по пути Бетти Холбертон и оказать влияние на сферу программирования.

Дженни Чу в прошлом была геологом и школьным консультантом, а теперь работает инженером-программистом полного стека, посещая школу Холбертона в Сан-Франциско. Она увлечена EdTech и мечтает сделать программирование доступным для всех.

Исходный пост

Об авторе
Дженни всегда любила решать головоломки и решать их. Надеясь стать следующим Индианой Джонсом, она изучала геологию и археологию. Она была первой в семье, кто окончил колледж и верит в равные возможности для получения образования. В конце концов, она стала консультантом колледжа для студентов с низким доходом и первого поколения студентов, чтобы отдать их своему сообществу, прежде чем учиться веб-дизайну. Дженни сейчас является амбициозным инженером-программистом полного стека, посещая школу Холбертона в Сан-Франциско. Дженни увлечена EdTech и мечтает сделать программирование доступным для всех.

Первоначально опубликовано на www.womenwhocode.com.