-
Notifications
You must be signed in to change notification settings - Fork 1
passengers 2
- Категория: PWN
- Стоимость: 400
- Автор: Михаил Евдокимов aka merrychap
- Репозиторий
После публикации новости об открытии набора экипажа на космический корабль корпорации Spacebury Craft сразу несколько исследователей в области информационной безопасности предостерегли желающих поучаствовать в программе. Они напомнили, что, несмотря на революционность изобретений компании, разработчики программного обеспечения Spacebury регулярно допускали ошибки, которые впоследствии приводили ко взломам.
Эксперты недвусмысленно намекают на то, что новая система с открытым кодом, используемая компанией для регистрации заявок, тоже может содержать уязвимости, ставящие под угрозу безопасность всего предприятия. «Это давно стало традицией Spacebury: если есть одна уязвимость, то обязательно найдётся и вторая», — заявил Эгнинг Маркуссон, известный хакер и программист.
Представители компании, однако, считают, что у желающих принять участие в экспедиции нет поводов для беспокойства. «Это всё пустые слова. Пусть покажут мне хотя бы одну уязвимость», — парирует основатель корпорации Иван Ланн, — «тогда я поверю, что, может быть, есть и вторая».
Примечание: для доступа к системе следует использовать программу nc: nc passengers.contest.qctf.ru 50001
. При заполнении заявки нужно воспользоваться токеном Your_Token_Right_Here
Краткий обзор исходного кода системы приведён в предыдущем райтапе. Теперь мы хотим найти второй флаг. Довольно быстро можно заметить следующую функцию:
void print_flag2() {
print_file_content("./flag2");
}
Но нигде в коде она не используется. Нам нужно каким-то образом заставить поток исполнения зайти в эту функцию.
Посмотрим на функцию update_info
, которая используется для изменения данных в анкете:
........
........
........
switch (choice) {
case 1:
printf("\nNew first name: ");
input_string(buf, 111);
strcpy(applier->first_name, buf);
break;
case 2:
printf("\nNew last name: ");
input_string(buf, 111);
strcpy(applier->last_name, buf);
break;
case 3:
printf("\nNew country: ");
input_string(buf, 111);
strcpy(applier->country, buf);
break;
........
........
........
Мы вводим 111 байтов в поле last_name
, хотя в определении структуры это поле занимает только 100 байт. То есть 11 байт запишутся после структуры last_name
, а именно в поле указателя на функцию on_unfreeze_ptr
. Как вы уже знаете, указатели хранят адрес, на который ссылаются. В данном случае, при создании пассажира, можно увидеть, что on_unfreeze_ptr
ссылается на функцию on_unfreeze
. Если мы перезапишем этот указатель на какой-либо свой адрес, например, 0x00414141
, то при вызове passngr->on_unfreeze_ptr()
вызовется код по адресу 0x00414141
. Таким образом мы можем контролировать поток исполнения программы
Мы можем перезаписать адрес указателя on_unfreeze_ptr
на функцию print_flag2
, тем самым стриггерив вывод флага при вызове passngr->on_unfreeze_ptr()
. Эта функция используется, когда происходит разморозка члена экипажа. Значит, мы можем перезаписать адрес, заморозить какого-либо члена экипажа, а затем его разморозить. После этого выведется флаг.
Код эксплойта, который выводит флаги сразу для первой и второй уязвимостей доступен здесь.