 
        
        Lab4_otchet
.docxФедеральное агентство связи
Ордена Трудового Красного Знамени
Федеральное государственное бюджетное образовательное
учреждение высшего образования
Московский технический университет связи и информатики»
Кафедра «Информационной безопасности»
Отчёт по лабораторной работе №4 по дисциплине «Защита информации в глобальных сетях»
Выполнил студент группы
Москва, 2020
Порядок выполнения:
- Выполнить настройку окружения: - Установить виртуальную машину 
- Установить операционную систему 
- Установить компилятор языка C 
- Установить отладчик 
- Установить Meatasploit Framework 
 
- Скомпилировать исходный файл с опциями -fno-pie -z execstack -m32 -g 
- Запустите программу, передав в качестве аргумента строку с Вашей фамилией 
- Запустите программу с форматной строкой ‘%d %d’ и убедитесь, что на экран выводятся числа 42 и 100 
- Запустите программу с форматной строкой ‘%x %x’ и убедитесь, что на экран выводятся числа 2a и 64 
- Запустите программу с форматной строкой ‘%08x %08x’ и убедитесь, что на экран выводятся числа 0000002a и 00000064 
- Запустите программу с форматной строкой ‘%2$x %1$x’ и убедитесь, что на экран выводятся числа 64 и 2a 
- Запустите программу под отладчиком, дизассемблируйте функцию main и функцию print. Сделайте предположение, как может выглядеть стэк в момент вызова функции printf. 
- Поставьте точку останова в функции print в момент вызова функции printf и просмотрите содержимое памяти по адресу, хранящемуся в регистре ESP. Сравните предположение с реальными значениями. Определите, на каком расстоянии от начала буфера располагается адрес возврата. 
- Увеличьте длину аргумента командной строки на 16 символов и повторите пункт 9. Как изменился адрес верхушки стэка? 
- Выйдите из отладчика 
- Запустите программу с входным параметром ‘ABCD %08x ’, повторив %08x 24 раза. Найдите адреса возврата, сохранённые в стэке значения регистра EBP адрес буфера (он передаётся в качестве параметра функции print и printf) и начало буфера (число 44434241). 
- Сформируйте shell code с помощью утилиты 
msfvenom --format c --platform linux -p linux/x86/exec -e x86/call4_dword_xor --bad-chars ‘\x00’ -a x86 AppendExit=true CMD=’bash’
- Запустите программу с входным параметром, содержащим буквы 16 байтов заполнителя для адресов перезаписи, 36 байтов заполнителя для форматной строки, осуществляющей запись, и shell code 
- Посмотрите, адрес буфера и определите адрес в памяти, по которому хранится адрес возврата 
- Сформируйте строку, которая записывает в байты адреса адрес начала shell кода (начало буфера, плюс длина форматной строки) 
- При правильном указании адресов, программа должна запустить bin/dash. Если произошла ошибка, перезапустите программу, заменив адреса и форматную строку символами-заполнителями, не меняя длины строки и проверьте адреса 
Ход работы:
 Установим
компилятор языка с gcc,
отладчик gdb
и Metasploit
framework
(рисунок 1)
Установим
компилятор языка с gcc,
отладчик gdb
и Metasploit
framework
(рисунок 1)
Рисунок 1 – Версии gcc и gdb
Исходный код программы на языке C представлен ниже:
#include <stdio.h>
#include <string.h>
void print(char* buffer)
{
printf(buffer, 42, 100);
}
int main(int argc, char** argv)
{
char buffer[1024];
if (argc >= 2)
{
strncpy(buffer, argv[1], 1024);
print(buffer);
}
return 0;
}
 Скомпилируем
исходный файл с опциями -fno-pie
-z
execstack
-m32
-g
и запустим его несколько раз с разными
входными данными (рисунок 2)
Скомпилируем
исходный файл с опциями -fno-pie
-z
execstack
-m32
-g
и запустим его несколько раз с разными
входными данными (рисунок 2)
Рисунок 2 – Компиляция и запуск программы
Запустим программу под отладчиком gdb и дизассемблируем функции print (рисунок 3) и main (рисунок 4).
 
 Рисунок
3
– Дизассемблированная функция print
Рисунок
3
– Дизассемблированная функция print
Рисунок 4 – Дизассемблированная функция main
Можно сделать предположение, что во время вызова функции printf в функции print стэк будет выглядеть следующим образом:
- Адрес верхушки стэка 
- Первый аргумент функции 
- Второй аргумент функции 
- Третий аргумент функции 
- Паддинг 
- EBP 
- Адрес возврата 
 Проверим
данную версию, поставив точку останова
в функции print
во время вызова функции printf
и посмотрим содержимое памяти, которое
хранится в регистре ESP
(рисунок 5).
Проверим
данную версию, поставив точку останова
в функции print
во время вызова функции printf
и посмотрим содержимое памяти, которое
хранится в регистре ESP
(рисунок 5).
Рисунок 5 – Содержимое регистра ESP
Проанализировав память, можно сделать вывод о расположении элементов в стэке. Например, адрес возврата (0х56556292) расположен по адресам 0хаааасс4с, 0хаааасс4d, 0хаааасс4e, 0хаааасс4f. Начало адреса возврата располагается на расстоянии 48 байтов
 Увеличим
длину аргумента командной строки на 16
символов и посмотрим память регистра
ESP
(рисунок 6).
Увеличим
длину аргумента командной строки на 16
символов и посмотрим память регистра
ESP
(рисунок 6). 
Рисунок 6 – Содержимое регистра ESP
Если сравнивать с предыдущими результатами, то видно, что адрес верхушки стэка уменьшился на 16.
 Запустим
программу с входным параметром ‘ABCD
%08x
’, повторив %08x
24 раза (рисунок 7)
Запустим
программу с входным параметром ‘ABCD
%08x
’, повторив %08x
24 раза (рисунок 7)
Рисунок 7 – Результат работы программы
Проанализировав результат, можно сделать вывод, что адрес возврата = 56556292, значение регистра EBP идет до адреса возврата и равно ffffd048, а начало буфера – 19-ый элемент.
Сформируем shell-код с помощью утилиты msfvenom командой: msfvenom --format c --platform linux -p linux/x86/exec -e x86/call4_dword_xor --bad-chars ‘\x00’ -a x86 AppendExit=true CMD=’bash’
 (рисунок
8)
(рисунок
8)
Рисунок 8 – Создание shell кода
 Запустим
программу со стройкой, в которой первые
16 байтов – заполнители для адресов
перезаписи, следующие 36 байтов –
заполнители для форматной строки, а
потом shell
код, и посмотрим память выполнения
функции printf
(рисунок 9)
Запустим
программу со стройкой, в которой первые
16 байтов – заполнители для адресов
перезаписи, следующие 36 байтов –
заполнители для форматной строки, а
потом shell
код, и посмотрим память выполнения
функции printf
(рисунок 9)
Рисунок 9 – Память в момент выполнения printf
Так как адрес начала буфера – 0xffffcbfc, расположен он в ячейках 0xffffcbb0-b3, то адрес возврата расположен в ячейках 0xffffcbac-af.
Сформируем строку, которая записывает в байты адреса адрес начала shell кода. Для этого рассчитаем значения для форматной строки, которая это сделает. Начало shell кода расположен о по адресу 0xffffcc30. Значит:
- 0x30 – 16 = 48 – 16 = 32 
- 0xcc – 0x30 = 0x9c = 156 
- 0xff – 0xcc = 0x33 = 51 
- 0xff – 0xff = 0 
Сформируем строку и подадим ее на вход программы (рисунок 10)
 
Рисунок 10 – Результат работы программы
С помощью данной строки удалось запустить bash из программы.
Вывод: В данной работе была рассмотрена и применена уязвимость форматной строки.
