Скачать 210.13 Kb.
|
При исследовании по методу «черного ящика» на вход выполняемой программы подаются различные данные. При таком тестировании требуется только запуск программы и не проводится никакого анализа исходного кода. С точки зрения безопасности на вход программы могут подаваться вредоносные данные с целью вызывать сбой в работе программы. Если программа дает сбой при выполнении какого-то теста, то считается, что выявлена проблема безопасности. Анализ по методу «черного ящика» возможен даже без доступа к двоичному коду. Таким образом, программа может быть проанализирована по сети. Все, что требуется, - это наличие запущенной программы, которая способна принимать входные данные, т.е. если исследователь способен отправить входные данные, которые принимает программа, и способен получить результат обработки этих данных, значит, возможно тестирование по методу «черного ящика». Анализ программы по методу «черного ящика» не так эффективен, как при использовании метода непосредственного анализа кода, но этот метод намного проще для реализации и не требует высокого уровня квалификации. В ходе тестирования по методу черного ящика, специалист, воздействуя на программу, по выдаваемым результатам пытается максимально точно определить пути исполнения кода в программе. При этом невозможно проверить действительное место ввода пользовательских данных в коде программы.
Этот метод является действенным, только если нет доступа к самому коду программы. Можно лишь проследить зависимость выходной информации от входных данных и на основе этого сделать некие предположения об исследуемом алгоритме. При этом нельзя быть уверенным наверняка в своих предположениях. 4. Методы прямого анализа кода исполняемых модулей Проанализировать доступный код программы можно двумя способами:
Дизассемблирование – это статический анализ программы, представляющий код в виде текста на некотором мнемоническом языке (чаще – на языке Ассемблера). Отладчик позволяет выполнять пошаговую трассировку, отслеживать, устанавливать или изменять значения переменных в процессе выполнения кода, устанавливать и удалять контрольные точки или условия останова и т.д. В дизассемблере (IDA) код программы представлен в виде графа, можно проанализировать каждую ветку алгоритма, что дает лучшее, по сравнению с отладчиком, представление об алгоритме программы. Однако, здесь требуется больше умственной работы, нежели при использовании отладчика. 5. Формат исполняемого PE-файла. Portable Executable — (PE, переносимый исполняемый) — формат исполняемых файлов, объектного кода и динамических библиотек, используемый в 32- и 64-битных версиях операционной системы Microsoft Windows. Формат PE представляет собой структуру данных, содержащую всю информацию, необходимую PE загрузчику для проецирования файла в память. Файл в таком формате начинается со стандартного DOS-кого заголовка: 0х0 WORD Magic “MZ” 0x3C – смещение, по которому начинается заголовок PE-файла. Заголовок PE-файла определяется следующей структурой: struct_IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; }; 1я часть – сигнатура PE\0\0 2я часть – обязательный заголовок 3я часть – дополнительный заголовок. Обязательный заголовок: struct _IMAGE_FILE_HEADER { WORD Machine; //Определяет, для какого процесса была скомпилирована //данная программа (0х14С - 386) WORD NumberOfSections; //Файл, кроме заголовка, имеет различные секции DWORD TimeDateStamp; //Время, когда программа была скомпилирована DWORD PointerToSymbolTable; //Указатель на таблицу символов DWORD NumberOfSymbols; //и число значений в ней WORD SizeOfOptionalHeader; //Размер дополнительного заголовка WORD Characteristics; //Битовое поле, содержащее информацию о том, что это //за файл, например: //0x0002 IMAGE_FILE_EXECUTABLE //0x1000 IMAGE_FILE_SYSTEM //0x2000 IMAGE_FILE_DLL }; Структура дополнительного заголовка: struct _IMAGE_OPTIONAL_HEADER { WORD Magic; //10 либо 20 в зависимости от того, 32-разрядный //или 64-разрядный заголовок BYTE MajorLinkerVersion; //Старшая и младшая часть версии линковщика BYTE MinorLinkerVersion; //соответственно DWORD SizeOfCode; //Суммарный размер кода и данных: DWORD SizeOfInitializedData; //инициализированный и DWORD SizeOfUninitializedData; //неинициализированных DWORD AddressOfEntryPoint; //Адрес точки входа в программу DWORD BaseOfCode; //База области кода DWORD BaseOfData; //База области данных DWORD ImageBase; //Адрес, по которому желательно загрузить //программу в память (по умолчанию 0х0400000) DWORD SectionAlignment; //Определяет границу выравнивания секций DWORD FileAlignment; //Выравнивание при хранении файла WORD MajorOperatingSystemVersion; //Старшая и младшая части версии ОС WORD MinorOperatingSystemVersion; //соответственно WORD MajorImageVersion; //Старшая и младшая части версии программы WORD MinorImageVersion; //в файле WORD MajorSubsystemVersion; //Старшая и младшая части версии WORD MinorSubsystemVersion; //подсистемы DWORD Win32VersionValue; //Это поле зарезервировано нулем DWORD SizeOfImage; //Задает размер всего файла, включая заголовок, //уже после того, как он будет загружен в память DWORD SizeOfHeaders; //Суммарный размер всех заголовков DWORD CheckSum; //Контрольная сумма WORD Subsystem; //Непосредственно задает подсистему, для которой //создан заданный файл. Возможные варианты: //0 – неизвестная подсистема, //1 – NATIVE (драйвера), //2 – GUI (программы с графическим интерфейсом), //3 – CUI (консольное приложение) и т.д. WORD DllCharacteristics; //Описывает характеристики Dll, если этот файл //является динамической библиотекой DWORD SizeOfStackReserve; //Эти поля определяют память, DWORD SizeOfStackCommit; //которую необходимо зарезервировать DWORD SizeOfHeapReserve; //под стек DWORD SizeOfHeapCommit; //и под кучу DWORD LoaderFlags; //Зарезервировано нулем DWORD NumberOfRVAandSizes; //Определяет количество элементов в массиве, //который содержит структуры, указывающие //на местоположение и размер возможных таблиц //PE-файла. Массив структур: //IMAGE_DATA_DIRECTORY DataDirectory []. //Основные таблицы – импорта и экспорта. }; По окончании заголовка в файле располагается таблица секций: struct _IMAGE_SECTION_HEADER { BYTE Name [ 8 ]; //Имя секции DWORD VirtualSize; //Описывают размер секции и ее местоположение, DWORD VirtualAddress; //когда она загружена в память DWORD SizeOfRawData; //Описывают размер и местоположение секции в DWORD PointerToRawData; //файле, когда он находится на диске DWORD PointerToRelocations; //Описывают местоположение DWORD PointerToLineNumbers; //и размер структур, WORD NumberOfRelocations; //описывающих Relocations WORD NumberOfLinenumbers; //и номера строк DWORD Characteristics; //флаговое поле из 3х флагов: //0х80000000 Write //0х40000000 Read //0х20000000 Execute }; Список секций:
Таблица экспорта: struct _IMAGE_EXPORT_DIRECTORY { DWORD TimeDateStamp; //Дата и время, когда структура экспорта была // создана WORD MajorVersion; //Старшая и младшая части версии WORD MinorVersion; //таблицы экспорта соответственно DWORD Name; //Указатель на строку, содержащую имя секции DWORD Base; //Базовые значения для ординалов DWORD NumberOfFunction; //Количество элементов в таблице адресов //экспортируемых функций DWORD NumberOfNames; //Число имен (обычно равно числу функций) DWORD AddresOfFunctions; //Адреса таблиц функций, DWORD AddressOfNames; //имен DWORD AddressOfNameOrdinals; //и имен ординалов }; Таблица импорта: struct _IMAGE_IMPORT_DIRECTORY { DWORD OrdinalFirstThunk; //Относительный адрес таблицы, описывающей //непосредственное поле имен ординалов DWORD TimeDateStamp; //Дата и время создания (равна нулю до того, как //загрузка состоится) DWORD ForwarderChain; //Это поле связано с возможностью передачи //экспорта в другие библиотеки DWORD Name; DWORD FirstThunk; //Содержит адрес таблицы, которая аналогична //таблице в 1-ом параметре до загрузки в память, //после загрузки содержит адреса тех функций //библиотек, которые импортируются }; 6. Процесс запуска исполняемого файла в ОС семейства Windows NT. Windows проверяет наличие DOS-сигнатуры “MZ”, потом по смещению 0x3C берется заголовок PE, проверяется наличие PE-сигнатуры и начинается загрузка файлов в память. По таблице секций по очереди выбираются секции в память. После того, как все секции загружены в память, начинается разбор таблиц импорта. Это самый простой способ обратиться к функциям из библиотек. Происходит поиск библиотеки и загрузка ее в память как обычного PE-файла; вызывается функция с нулевым значением, производящая инициализацию библиотеки; в ней будут найдены необходимые функции. 7. Основные программные конструкции, используемые в коде программных модулей. 1) if (выражение) then { . . } else { . . } Пример реализации на ассемблере следующей проверки: if ( ( (x > y ) && ( z < t ) ) || ( A != B ) ) then ... else… mov ax, A cmp ax, B jne _then mov ax, x cmp ax, y jng _endif mov ax, z cmp ax, t jnl _endif _then: … _endif: … 2) switch [ ] case : … ... case : … default : Можно switch преобразовать в последовательность if ’ов. Если проверяемое значение в switch небольшое, то может использоваться таблица переходов, где будут записаны адреса блоков. Проверяемое значение будет умножено на размер ячейки (как правило, 4 байта), получится адрес перехода, и дальше будет выполнен jmp: shl eax, 2 jmp [eax] 8. Использование функций. Структура функций. Правила передачи параметров и возврата результата. Если в программе возникает необходимость частого обращения к некоторой группе операторов, то рационально сгруппировать такую группу операторов в самостоятельный блок, к которому можно обращаться, указывая его имя. Такие разработанные программистом самостоятельные программные блоки называются подпрограммами пользователя. При вызове подпрограммы (процедуры или функции), определенной программистом, работа главной программы на некоторое время приостанавливается и начинает выполняться вызванная подпрограмма. Она обрабатывает данные, переданные ей из главной программы. По завершении выполнения подпрограмма-функция возвращает главной программе результат (подпрограмма-процедура не возвращает явно результирующего значения). Передача данных из главной программы в подпрограмму и возврат результата выполнения функции осуществляются с помощью параметров. Функция, определенная пользователем, состоит из заголовка и тела функции. Обращение к функции осуществляется по имени с необязательным указанием списка аргументов. Каждый аргумент должен соответствовать формальным параметрам, указанным в заголовке, и иметь тот же тип. Возвращаемое значение функции хранится в регистре eax. Если его размер слишком велик для размещения в регистре, то оно размещается на верхушке стека, а значение в регистре eax будет указывать на него. Правила передачи параметров в функцию:
9. Способы обращения программы к функциям динамических библиотек в ОС Windows. Существуют два способа обращения к DLL:
С помощью LoadLibrary подгружаем необходимую библиотеку (аргументом LoadLibrary является имя необходимой DLL). Затем, чтобы вызвать какую-либо функцию из данной библиотеки, необходимо сначала определить адрес этой функции с помощью GetProcAddress, a после вызывать функцию через полученный адрес. Есть программы с пустой таблицей импорта. Соответственно, им не известны адреса библиотек. Тем не менее, они также могут использовать DLL. Для этого можно воспользоваться тремя способами:
Итак, начиная с FS:[0], располагается структура TEB. В поле PPEB Peb этой структуры (по адресу fs:[30]) лежит адрес структуры PEB в памяти. В PEB обращаемся к полю со смещением 0Ch – LoaderData. Это адрес структуры PEB_LDR_DATA. В ней есть три кольцевых двусвязных списка структур LDR_MODULE:
Теперь нас интересует поле BaseAddress последнего списка. В списке первой будет стоять ntdll.dll, а за ней будет kernel32.dll. Поэтому мы получаем голову списка через PEB_LDR_DATA.InInitializationOrderModuleList.Flink и делаем еще раз переход по Flink к следующему элементу списка. Преобразовав указатель к типу LDR_MODULE*, мы получим указатель на структуру описания kernel32.dll, где и будет ее база. А дальше, получив Loadlibrary и GetProcAddress, можно грузить любые остальные функции. 10. Методы динамического анализа алгоритмов функционирования программных модулей. К методам динамического анализа программ относится отладка. Выделяют:
Используются: трассировка (F8), трассировка с заходом в функции (F7) и исполнение до точки останова (F9). Точки останова бывают:
Однако программные точки останова имеют одно ограничение: когда вы меняете байт исполняемого в памяти, вы изменяете контрольную сумму циклического избыточного кода (Cyclic redundancy code, CRC) выполняемого приложения. CRC - это тип функции, которая используется для определения изменения данных каким либо способом, и она может быть применена к файлам, памяти, тексту, сетевым пакетам, или чего-нибудь еще, за изменением данных которого вам надо наблюдать. CRC возьмет диапазон данных, в данном случае память выполняемого процесса, и получит хэш содержимого. Затем она сравнивает хеш с контрольной суммой для определения были ли изменены данные. Если контрольная сумма отличается от контрольной суммы, которая хранится для подтверждения, проверка CRC собьется. Важно заметить, как часто вредоносное ПО будет проверять свой исполняемый код в памяти для любых изменений CRC и убьёт себя, если обнаружится сбой. Это очень эффективная техника для замедления реверс-инженерии, таким образом, предотвращается использование программных точек останова, ограничивая динамический анализ его поведения. Для того чтобы обойти эти особенности используются аппаратные точки останова.
В отличие от программных точек останова, которые используют событие INT 3, аппаратные используют прерывание INT 1. 11. Способы, используемые программными модулями для противодействия отладке. Способов противодействия отладке существует не меньше, чем отладчиков. Это именно способы противодействия, поскольку основная их задача сделать работу отладчика либо совсем невозможной, либо максимально трудоемкой. Опишем основные способы противодействия: Замусоривание кода программы (обфускация). Способ, при котором в программу вносятся специальные функции и вызовы, которые выполняют сложные действия, обращаются к накопителям, но по факту ничего не делают. Типичный способ обмана. Хакера нужно отвлечь, создав ответвление, которое и будет привлекать внимание сложными вызовами, и содержать в себе сложные и большие вычисления. Хакер рано или поздно поймет, что его обманывают, но время будет потеряно. Использование многопоточности. Тоже эффективный способ защиты, использующий возможности Windows по параллельному исполнению функций. Любое приложение может идти как линейно, то есть инструкция за инструкцией, и легко читаться отладчиком, а может разбиваться на несколько потоков, исполняемых одновременно, естественно, в этом случае, нет никакого разговора о линейности кода, а раз нет линейности, то анализ здесь трудноосуществим. Как правило, создание 5-6 и более потоков существенно усложняет жизнь хакеру. А если потоки еще и шифруются, то хакер надолго завязнет, пытаясь вскрыть приложение. Подавление изменения операционной среды. Программа сама несколько раз перенастраивает среду окружения, либо вообще отказывается работать в измененной среде. Не все отладчики способны на 100% имитировать среду системы, и если "подопытное" приложение будет менять настройки среды, то рано или поздно "неправильный" отладчик может дать сбой. Противодействие постановке контрольных точек. Специальный механизм, поддерживаемый микропроцессором, при помощи которого можно исследовать не всю программу сначала, а, например, только начиная с середины. Для этого в середине программы ставят специальный вызов (контрольную точку - Breakpoint), который передает управление отладчику. Недостаток способа кроется в том, что для осуществления прерывания в код исследуемого приложения надо внести изменение. А если приложение время от времени проверяет себя на наличие контрольных точек, то сделать подобное будет весьма и весьма непросто. Изменение определенных регистров процессора, на которые отладчики неадекватно реагируют. Также как и со средой. Отладчик тоже программа и тоже пользуется и операционной системой и процессором, который один на всех. Так, если менять определенные регистры микропроцессора, которые отладчик не может эмулировать, то можно существенно "подорвать" его здоровье. Также используют: блокировку прерываний и устройств, работу с контроллерами через порты, подсчеты контрольных сумм для выявления контрольных точек, контроль стека, временные метки и т.д. 12. Способы обнаружения отладчиков. Основной принцип действия: программа пытается выявить разницу при обычном исполнении и исполнении под отладчиком. Для этого используются следующие средства:
Возвращаемое значение:
Избежать такого простого обхода проверки можно, если разобраться в том, откуда IsDebuggerPresent берет информацию о наличии отладчика. Лезем дизассемблером в библиотеку и видим ее код: 77E72740 MOV EAX,DWORD PTR FS:[18] ; TEB 77E72746 MOV EAX,DWORD PTR [EAX+30] ; EAX <- адрес PEB из TEB 77E72749 MOVZX EAX,BYTE PTR [EAX+2] ; EAX <- BeingDebugged 77E7274D RETN PEB содержит информацию о некоторых параметрах процесса. Если посмотреть описание этой структуры, можно заметить, что третий байт в ней - это BeingDebugged, то есть флаг присутствия отладчика. Это значит, что для обнаружения отладчика можно не вызывать API, а просто где угодно в коде проверять значение BeginDebugged. Обход этой штуки напрашивается сам собой: сразу после загрузки в отладчик обнулить флаг BeingDebugged.
13. Методы статического анализа алгоритмов функционирования программных модулей. Статический анализ кода – анализ ПО, проводимый без реального выполнения исследуемых процедур. Так дизассемблирование – это статический анализ программы, представляющий код в виде текста на некотором мнемоническом языке (чаще – на языке Ассемблера). Наиболее известный дизассемблер – IDA Pro. Позволяет отслеживать переменные, давать им осмысленные имена, отслеживать ссылки на функции, точки входа. У IDA есть возможность написания скриптов, что упрощает выполнение однотипных участков кода. 14. Способы, используемые программными модулями для противодействия дизассемблированию. Существует несколько методов противодействия дизассемблированию:
Другой подход к защите от дизассемблирования связан с совмещением процесса расшифрования с процессом выполнения программ. Если расшифрование всей программы осуществляется блоком, получающим управление первым, то такую программу расшифровать довольно просто. Гораздо сложнее расшифровать и дизассемблировать программу, которая поэтапно расшифровывает информацию, а этапы разнесены по ходу выполнения программы. Задача становится еще более сложной, если процесс расшифрования разнесен по тексту программы.
Для дезориентации дизассемблера часто используются скрытые переходы, вызовы и возвраты за счет применения нестандартных возможностей команд. Маскировка скрытых действий часто осуществляется с применением стеков. 15. Программы-упаковщики. Принципы работы. Методы снятия упаковки с программных модулей. Упаковщик - программа для сжатия исполняемого файла, которая отличается от архиватора лишь тем, что добавляет код распаковщика в тело программы. При запуске управление передается этому коду вплоть до полной распаковки программы в память. Изначальное предназначение – уменьшение размера программ. Средства распаковки:
Нахождение OEP: при стандартном начале Windows-программ указатель на верхнюю часть стека один и тот же и равен значению регистра esp. Когда упаковщик передает управление первоначальной программе, указатель восстанавливается, но перед этим, как правило, упаковщик считывает из стека значение esp-4. Соответственно, за этой командой, вероятно, будет следовать OEP. Для снятие дампа существует различный софт. Например, PETools и LordPE. Нам предстоит еще восстановить таблицу импорта. Импорт можно восстановить с помощью еще Import Recontructor. Запустим упакованную программу, затем найдем ее в листе процессов ImpRec'а. Теперь нам необходимо указать RVA OEP (в ImpRec он просто OEP). "RVA OEP = VA OEP - ImageBase". Image Base мы сможем найти, нажав на кнопку PE Editor в LordPE. Вводим значение RVA в поле OEP и жмем автопоиск, то есть IAT AutoSearch. После этого нажимаем Get Imports. Мы должны увидеть строки с функциями и надписью YES напротив. Останется только указать наш дамп и после нажатия на ОК получить распакованную программу. Можно восстанавливать таблицу импорта вручную. Как известно, функции в исполняемом файле находятся в виде адресов. Упаковщик сохраняет всю таблицу. Следовательно, по адресам в простом HEX-редакторе мы сможем обнаружить таблицу импорта в упакованном файле. |
Игорь Губерман Чудеса и трагедии чёрного ящика «И. Губерман. «Чудеса... Елей, медленно, но верно приближая разгадку тайн этого чуда природы. Научно-популярное произведение Игоря Губермана, не утратило... |
Исследование параметров метеорологических условий в производственных помещениях Аимодействия организма человека с внешней средой и санитарными нормами на метеорологические условия в производственных помещениях;... |
||
Лабораторная работа №1 Изучение методов контроля параметров врл "Корень-ас" Изучение методов контроля параметров врл "Корень-ас" встроенными средствами контроля |
Техническое задание на заключение договора финансовой аренды (лизинга)... Выкупной платеж устанавливается в размере 59,00 (пятьдесят девять рублей 00 копеек) рублей с ндс за один контейнеров |
||
Учебно-методический комплекс учебной дисциплины «Информационные системы нефтегазовой геологии» Гис-систем регионов и России в целом; компьютерных систем бассейнового моделирования; информационных систем моделирования залежей... |
Положение о размещении объектов капитального строительства, технико-экономические... Целью данного проекта является выделение элементов планировочной структуры, установление параметров планируемого развития элементов... |
||
Руководство по эксплуатации и обслуживанию Регулируемая Среда Она регулирует внутреннюю среду контейнеров. Эта среда наполняется газом необходимой структуры, который обеспечивается настройками... |
Техническое задание на выполнение работ по восстановлению элементов... Выполнение работ по восстановлению элементов благоустройства (восстановление асфальта, восстановление щебеночного основания, восстановление... |
||
Обоснование структуры, параметров и алгоритмов управления электротехническим... |
Выдержки из Закона об Образовании РФ Краткая характеристика информационных систем и информационных технологий, применяемых в Омгу для организации учебного процесса с... |
||
Промышленная мебель Для этого необходимо выдвинуть ящик до упора, на направляющих ящика нажать на пластмассовый фиксатор (с одной стороны ящика вниз,... |
Заполнения формы расчета по начисленным и уплаченным Расчет), заполняется с использованием средств вычислительной техники или от руки печатными буквами шариковой (перьевой) ручкой черного... |
||
I. Общие требования к заполнению Расчета Фсс рф) (далее Расчет), заполняется с использованием средств вычислительной техники или от руки шариковой (перьевой) ручкой черного... |
I. Общие требования к заполнению Расчета Фсс) (далее Расчет), заполняется с использованием средств вычислительной техники или от руки шариковой (перьевой) ручкой черного... |
||
Спутниковый мониторинг климатических параметров океана. Часть 1 А.... Описываются приборы и спутники, которые используются для исследования этих климатических переменных. Приводятся некоторые результаты... |
6. 8 Вопросы повышения эксплуатационной надежности электрических... Обоснование структуры, параметров и алгоритмов управления электротехническим комплексом систем поддержания пластового давления |
Поиск |