В исходном тексте программы можно найти функцию
Подробнее с проблемой переполнения буфера можно познакомиться в главе 8.
Ошибки проверки входных данныхПричина других типичных ошибок программирования кроется в недостаточной проверке входных данных программы. В результате уязвимость программы может проявиться при передаче ей различных типов данных, как, например, это происходит с программами Web CGI.
Ошибки проверки входных данных программы могут привести к
/* fmtstr.c */
/* Hal Flynn <mrhal@mrhal.com> */
/* December 31, 2001 */
/* fmtstr.c demonstrates a format */
/* string vulnerability. By supplying */
/* format specifiers as arguments, */
/* attackers may read or write to */
/* memory. */
#include <stdio.h>
int main(int argc, char *argv[])
{
printf(*++argv);
return (0);
}В результате запуска программы и передачи ей на вход форматирующей строки со спецификацией преобразования
Проверка программами Web-интерфейса, например CGI-программами, входных данных программы часто приводит к неожиданным результатам. Нередко недостаточно квалифицированно написанные CGI-программы (особенно это касается программ, написанных на языке Perl) позволяют выполнять команды, заключенные в специальные символы, что дает возможность выполнять произвольные команды системы с привилегиями Web-пользователя. В некоторых случаях это может привести к серьезным последствиям. Например, к удалению файла index.html, если HTTP-процесс является владельцем этого файла и имеет право писать в него данные. Или к предоставлению пользователю локального доступа к системе с разрешениями HTTP-процесса, если пользователь свяжет оболочку shell c произвольным портом системы.
К сходным проблемам может привести предоставленная пользователю возможность выполнять произвольные SQL-команды. Обычно CGI-программы используются для облегчения взаимодействия между внешним Web-интерфейсом и серверной частью системы управления базами данных, поддерживающих SQL, например Oracle, MySQL или Microsoft SQL Server. Пользователь, который может выполнять произвольные SQL-команды, сможет просматривать произвольные таблицы, обрабатывать данные таблиц и даже удалять их.
Посмотрите на вариант вызова функции#!/usr/bin/perl open(“ls $ARGV[0] |”);
Эта функция не проверяет входные данные, переданные программе в $argv [0]. Добавив к входным данным символы точек (..), становится возможным сменить директорию и просмотреть родительский каталог, в котором может храниться важная информация. Более подробное обсуждение ошибок проверки входных данных приведено в главе 7. Соперничество программ за ресурсы
При соперничестве программ за ресурсы часто встречается программная ошибка, получившая название «состояние гонок» (Race Conditions). Проявляется состояние гонок различным образом, например в виде блокирования одним процессом разделяемой области памяти, не позволяя тем самым другому процессу изменить в ней данные, или в виде ошибок одновременной работы нескольких процессов с одним и тем же файлом.
Изучим пример использования функции/* mtmprace.c */
/* Hal Flynn <mrhal@mrhal.com> */
/* mtmprace.c creates a file in the */
/* temporary directory that can be */
/* easily guessed, and exploited */
/* through a symbolic link attack. */
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *example;
char *outfile;
char ex[] = “/tmp/exampleXXXXXX”;
example = ex;
mktemp(example);
outfile = fopen(example, “w”);
return (0);
}В некоторых операционных системах эта программа создает файл во временной директории с предопределенным именем, состоящим из строки символов, в которую входят слово example, пять символов идентификатора процесса и одна буква латинского алфавита. Первый недостаток рассматриваемой программы заключается в том, что между проверкой существования файла и его созданием может возникнуть ошибка «состояние гонок» (Race Conditions), обусловленная соперничеством программ за ресурсы. Второй – в том, что имя файла можно сравнительно легко предсказать, поскольку идентификатор процесса можно определить, а последний символ – это одна из 26 букв английского алфавита. В результате возможна успешная для злоумышленника атака символических связей. Для того чтобы определить, позволяет ли операционная система воспользоваться указанными уязвимостями, достаточно исследовать файлы, созданные программой в директории /tmp. При помощи такой утилиты, как
Технологии реинжиниринга
Технологии реинжиниринга в большинстве случаев позволяют с большой точностью определить уязвимости в программе с недоступными исходными текстами. Для реинжиниринга программ существует различный инструментарий, выбор которого определяется используемой операционной системой и предпочтениями исследователя. Но независимо от этого чаще всего применяются одни и те же способы реинжиниринга.
Обычно наиболее целесообразна методика работы «сверху вниз», предполагающая сначала рассмотрение общих случаев, а затем, по мере необходимости, их детализацию. В большинстве случаев это означает первоначальное применение средств мониторинга операционной системы для определения файлов и ресурсов, к которым обращается исследуемая программа. (Исключение из этого правила составляют сетевые программы. При исследовании сетевых программ чаще всего требуется перейти к анализу передаваемых по сети пакетов.)
В составе операционных систем Windows подобный инструментарий не поставляется, поэтому используют программные средства других производителей. До настоящего времени главным их источником для Windows был сайт SysInternals по адресу www.sysinternals.com в Интернете. Особенно интересны программы FileMon, RegMon, а в случае NT – HandleEx. Подробнее о них будет рассказано в главе 5. Все, что вам необходимо знать об этих средствах сейчас, – это то, что они позволяют контролировать выполняющуюся программу (или программы), узнать, к каким файлам обращается контролируемая исследователем программа, читает ли она их или пишет в них информацию и куда именно, какие другие файлы она ищет. Перечисленные функции реализованы в программе FileMon. Программа RegMon позволяет исследовать то же самое применительно к реестру Windows NT: к каким ключам реестра программа обращается, какие ключи читает, обновляет, ищет и т. д. HandleEx реализует те же самые функции, но несколько другим способом. Результаты ее работы упорядочены по процессам, дескрипторам файлов и тем объектам, на которые указывают дескрипторы файлов.
В качестве дополнительной услуги доступны свободно распространяемые версии почти всех инструментальных средств SysInternals, причем большинство из них с исходными текстами программ. (Помимо сайта SysInternals, на родственном сайте Winternals.com продаются аналогичные коммерческие инструментальные средства с несколько большими возможностями.) Для пользователя UNIX в этом нет ничего необычного, но для пользователя Windows это приятная неожиданность.
В состав большинства дистрибутивов UNIX включены программные средства, которые могут облегчить анализ VB-программ. В списке Rosetta Stone перечислено много программ трассировки. Список можно найти по адресу http://bhami.com/rosetta.html в Интернете. Любая программа трассировки реализует низкоуровневые функции, поэтому она может работать только под управлением ограниченного количества операционных систем. Примерами программ трассировки могут служить программы
Приоткрывая завесу
Декомпиляторы VB
Изрядное количество программ во всем мире написано на Visual Basic (VB). Сюда относятся как зловредные программы, так и программы законопослушных программистов. VB бросает вызов всякому, кто отважится декомпилировать программу, написанную на этом языке. Последний свободно доступный декомпилятор мог работать только с программами VB3. Начиная с VB5, результат компиляции программы может быть представлен как во внутреннем коде исполняемого модуля («native code»), реализующем стандартное обращение к Windows, так и в p-code. P-код – это псевдокод, который похож на байт-код (или машинно-независимый код), генерируемый Java-компилятором. P-код распознает интерпретатор реального времени Visual Basic VBRUN300.DLL, VBRUN500.DLL или VBRUN600.DLL. Сложность заключается в том, что очень мало доступной документации, в которой описано соответствие конструкций исходного текста программы функциям VB в откомпилированной программе. Конечно, всегда можно декомпилировать интерпретатор VB DLL и восстановить соответствие, но это очень трудоемкое занятие.
Вместо этого опытные хакеры воспользовались бы средствами отладки. Конечно, они мысленно преследуют совсем другие цели. В основном их интересует, как взломать защиту от копирования. Поэтому напрямую их навыки не всегда могут пригодиться для декомпиляции программ, написанных на VB. В большинстве известных работ в этой области используется пошаговое выполнение программы для обнаружения места, где проверяется, например, серийный номер. Затем ищутся пути отключения проверки. Тем самым хакеры стремятся заблокировать выполнение нужного им участка программы. Несмотря на это, изучение способов работы хакеров позволяет начать квалифицированную работу по анализу программ, написанных на VB.
Для удобства восприятия протокол трассировки дополнен комментариями:
[elliptic@ellipse]$ echo hello > test
[elliptic@ellipse]$ strace cat test
execve(“/bin/cat”, [“cat”, “test”], [/* 21 vars */]) = 0Утилита
brk(0) = 0x804b160
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, – 1, 0) = 0x40014000
open(“/etc/ld.so.preload”, O_RDONLY) = -1 ENOENT (No
such file or directory)После вызова
open(“/etc/ld.so.cache”, O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=12431, ...}) = 0
old_mmap(NULL, 12431, PROT_READ, MAP_PRIVATE, 4, 0) =
0x40015000
close(4) = 0
open(“/lib/libc.so.6”, O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0755, st_size=4101324, ...}) = 0
read(4,
“\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\210\212”...,
4096) = 4096Прочитаны первые 4 Кб библиотеки
old_mmap(NULL, 1001564, PROT_READ|PROT_EXEC, MAP_PRIVATE, 4,
0) = 0x40019000
mprotect(0x40106000, 30812, PROT_NONE) = 0
old_mmap(0x40106000, 16384, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED, 4, 0xec000) = 0x40106000
old_mmap(0x4010a000, 14428, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED| MAP_ANONYMOUS, -1, 0)
= 0x4010a000
close(4) = 0
mprotect(0x40019000, 970752, PROT_READ|PROT_WRITE) = 0
mprotect(0x40019000, 970752, PROT_READ|PROT_EXEC) = 0
munmap(0x40015000, 12431) = 0
personality(PER_LINUX) = 0
getpid() = 9271
brk(0) = 0x804b160
brk(0x804b198) = 0x804b198
brk(0x804c000) = 0x804c000
open(“/usr/share/locale/locale.alias”, O_RDONLY) = 4
fstat64(0x4, 0xbfffb79c) = -1 ENOSYS (Function not
implemented)
fstat(4, {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, – 1, 0) = 0x40015000
read(4, “# Locale name alias data base.\n#”..., 4096) = 2265
read(4, “”, 4096) = 0
close(4) = 0
munmap(0x40015000, 4096) = 0Если в программе встречается вызов функции
open(“/usr/share/i18n/locale.alias”, O_RDONLY) = -1 ENOENT
(No such file or directory)
open(“/usr/share/locale/en_US/LC_MESSAGES”, O_RDONLY) = 4
fstat(4, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
close(4) = 0
open(“/usr/share/locale/en_US/LC_MESSAGES/SYS_LC_MESSAGES”,
O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=44, ...}) = 0
old_mmap(NULL, 44, PROT_READ, MAP_PRIVATE, 4, 0)
= 0x40015000
close(4) = 0
open(“/usr/share/locale/en_US/LC_MONETARY”, O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=93, ...}) = 0
old_mmap(NULL, 93, PROT_READ, MAP_PRIVATE, 4, 0)
= 0x40016000
close(4) = 0
open(“/usr/share/locale/en_US/LC_COLLATE”, O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=29970, ...}) = 0
old_mmap(NULL, 29970, PROT_READ, MAP_PRIVATE, 4, 0)
= 0x4010e000
close(4) = 0
brk(0x804d000) = 0x804d000
open(“/usr/share/locale/en_US/LC_TIME”, O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=508, ...}) = 0
old_mmap(NULL, 508, PROT_READ, MAP_PRIVATE, 4, 0)
= 0x40017000
close(4) = 0
open(“/usr/share/locale/en_US/LC_NUMERIC”, O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=27, ...}) = 0
old_mmap(NULL, 27, PROT_READ, MAP_PRIVATE, 4, 0)
= 0x40018000
close(4) = 0
open(“/usr/share/locale/en_US/LC_CTYPE”, O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=87756, ...}) = 0
old_mmap(NULL, 87756, PROT_READ, MAP_PRIVATE, 4, 0)
= 0x40116000
close(4) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4),
...}) = 0
open(“test”, O_RDONLY|O_LARGEFILE) = 4
fstat(4, {st_mode=S_IFREG|0664, st_size=6, ...}) = 0Наконец, команда cat открывает наш файл «test». Конечно, имя файла – это входные данные команды, но они безопасны для работоспособности команды из-за ее логики работы. В других случаях может потребоваться учет содержимого входного файла.
read(4, “hello\n”, 512) = 6
write(1, “hello\n”, 6) = 6
read(4, “”, 512) = 0
close(4) = 0
close(1) = 0
_exit(0) = ?В заключение
int count, handle
string contents
handle = open (argv[1])
while (count = read (handle, contents, 512))
write (STDOUT, contents, count)
exit (0)Для сравнения приведем результат выполнения утилиты
execve(“/usr/bin/cat”, 0x08047E50, 0x08047E5C) argc = 2
open(“/dev/zero”, O_RDONLY) = 3
mmap(0x00000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE, 3, 0) = 0xDFBE1000
xstat(2, “/usr/bin/cat”, 0x08047BCC) = 0
sysconfig(_CONFIG_PAGESIZE) = 4096
open(“/usr/lib/libc.so.1”, O_RDONLY) = 4
fxstat(2, 4, 0x08047A0C) = 0
mmap(0x00000000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE, 4,
0) = 0xDFBDF000
mmap(0x00000000, 598016, PROT_READ|PROT_EXEC, MAP_PRIVATE,
4, 0) = 0xDFB4C000
mmap(0xDFBD6000, 24392, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED, 4, 561152) = 0xDFBD6000
mmap(0xDFBDC000, 6356, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xDFBDC000
close(4) = 0
open(“/usr/lib/libdl.so.1”, O_RDONLY) = 4
fxstat(2, 4, 0x08047A0C) = 0
mmap(0xDFBDF000, 4096, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xDFBDF000
close(4) = 0
close(3) = 0
sysi86(SI86FPHW, 0xDFBDD8C0, 0x08047E0C, 0xDFBFCEA0)
= 0x00000000
fstat64(1, 0x08047D80) = 0
open64(“test”, O_RDONLY) = 3
fstat64(3, 0x08047CF0) = 0
llseek(3, 0, SEEK_CUR) = 0
mmap64(0x00000000, 6, PROT_READ, MAP_SHARED, 3, 0)
= 0xDFB4A000
read(3, “ h”, 1) = 1
memcntl(0xDFB4A000, 6, MC_ADVISE, 0x0002, 0, 0) = 0
write(1, “ h e l l o\n”, 6) = 6
llseek(3, 6, SEEK_SET) = 6
munmap(0xDFB4A000, 6) = 0
llseek(3, 0, SEEK_CUR) = 6
close(3) = 0
close(1) = 0
llseek(0, 0, SEEK_CUR) = 296569
_exit(0)Проанализировав конец протокола, можно заметить, что в Solaris команда
Приведенная трассировка не раскрывает правил использования инструментария трассировки (хотя с этим и стоило бы познакомиться, но для этого потребовалось написать бы несколько глав). Скорее всего, приведенный пример демонстрирует некоторые факты, с помощью которых можно выяснить логику работы операционных систем в этой ситуации.
Для углубления своих представлений об используемом инструментарии следует рассмотреть случаи применения файлов с предсказуемыми именами в директории временной памяти
Дизассемблеры, декомпиляторы и отладчики
Подготовка к анализу загрузочного файла – тема отдельного разговора. Отладчики – это программные средства, предназначенные для контроля выполнения программ. Отладчики позволяют приостановить выполнение программы в некоторой точке, изменить значение переменных и даже, в некоторых случаях, внести изменения в машинный код программы на лету в процессе ее выполнения. К сожалению, возможность выполнения отладчиком подобных действий зависит от включения в выполнимый код отладочной информации, прежде всего таблицы соответствия символов (для большинства загрузочных программ это не выполняется). Если отладочной информации в выполнимом коде нет, то отладчик может выполнить некоторые функции, хотя большую часть работы по отладке программ приходится выполнять вручную, например при указании точек прерывания вместо имен приходится задавать адреса памяти.
Проблема несколько упрощается, если исследователь в состоянии разобраться с ассемблерным кодом, генерируемым декомпилятором. В этом случае декомпилятор особенно полезен. Рассмотрим пример результатов работы декомпилятора.
Среди коммерческих декомпиляторов для Windows хорошая репутация у IDA Pro компании DataRescue (пример работы декомпилятора показан на рис. 4.1). IDA Pro может декомпилировать программный код многих процессоров, включая виртуальную машину Java.
На рисунке показан пример применения декомпилятора IDA Pro для дизассемблирования программы pbrush.exe (Paintbrush). IDA Pro нашел секцию внешних функций, используемых программой pbrush.exe. Если программа выполняется под управлением операционной системы, которая поддерживает разделяемые библиотеки (например, под управлением операционных систем Windows или UNIX), то она содержит список необходимых ей библиотек. Обычно этот список представлен в удобочитаемом виде, который легко обнаружить при экспертизе выполняемого кода. Для выполнения программ операционной системе также требуется этот список, поэтому она загружает его в память. В большинстве случаев это позволяет декомпилятору вставить список в двоичный код программы, сделав его более понятным.
Чаще всего таблица соответствия имен pbrush.exe недоступна, поэтому в большей части сгенерированного декомпилятором ассемблерного кода отсутствуют имена.
Оценочную версию IDA Pro, пригодную для первоначального знакомства с программой, можно загрузить с www.datarescue.com/idabase/ida.htm. SoftICE компании Numega – другой популярный отладчик. Дополнительные сведения о нем можно найти по адресу www.compuware.com/products/numega/drivercentral/.
Для сравнения была написана небольшая программа на языке C (классическая небольшая программа, выводящая строку «Hello World»). Для отладки использовался отладчик GNU (GDB). Код программы представлен ниже:#include <stdio.h>
int main ()
{
printf (“Hello World\n”);
return (0);
}Программа была скомпилирована с включением отладочной информации (был включен переключатель
[elliptic@]$ gcc -g hello.c -o hello
[elliptic@ellipse]$ ./hello
Hello WorldПример протокола отладки под управлением GDB показан ниже:
[elliptic@ellipse]$ gdb hello
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public
License, and you are welcome to change it and/or
distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show
warranty” for details.
This GDB was configured as “i386-redhat-linux”...
(gdb) break mainБыла установлена точка прерывания при входе в функцию
Breakpoint 1 at 0x80483d3: file hello.c, line 5. (gdb) run
Команда run начинает выполнение программы под управлением отладчика.
Starting program: /home/ryan/hello
Breakpoint 1, main () at hello.c:5
5 printf (“Hello World\n”);
(gdb) disassembleПосле того достижения программой точки прерывания и начала сессии отладки была выдана команда disassemble, позволяющая вывести дополнительную отладочную информацию о программе.
Dump of assembler code for function main:
0x80483d0 <main>: push %ebp
0x80483d1 <main+1>: mov %esp,%ebp
0x80483d3 <main+3>: push $0x8048440
0x80483d8 <main+8>: call 0x8048308 <printf>
0x80483dd <main+13>: add $0x4,%esp
0x80483e0 <main+16>: xor %eax,%eax
0x80483e2 <main+18>: jmp 0x80483e4 <main+20>
0x80483e4 <main+20>: leave
0x80483e5 <main+21>: ret
End of assembler dump.Протокол отображает ассемблерный код программы «hello world», соответствующий ассемблеру x86 Linux. Исследование собственных программ в отладчике – хороший способ изучения листингов ассемблерного кода.
(gdb) s
printf (format=0x8048440 “Hello World\n”) at printf.c:30
printf.c: No such file or directory.После задания командой s («step») режима пошагового выполнения программы в отладчике выполняется переход к вызову функции
(gdb) s
31 in printf.c
(gdb) s
Hello World
35 in printf.c
(gdb) c
Continuing.Далее выполняется несколько шагов реализации программы внутри функции
Program exited normally. (gdb)
В число аналогичных программ входят программы
Инструментарий и ловушки
Инструментарий никогда не заменит знаний
Некоторые из средств дизассемблирования и отладки предлагают фантастические возможности. Но они, как и любой другой инструментарий, несовершенны. Особенно это проявляется при анализе злонамеренного кода (вирусов, червей, Троянских коней) или специально разработанных программ. Обычно авторы подобных поделок делают все возможное для затруднения их анализа и снижения эффекта от применения отладчиков, дизассемблеров и других подобных инструментальных средств. Например, вирус RST для Linux в случае обнаружения, что он работает под управлением отладчика, завершает свою работу. Этот же вирус при инфицировании исполняемых и компонуемых файлов ELF (Executable and Linkable Format – формат исполняемых и компонуемых модулей) модифицирует их заголовки таким образом, что некоторые дизассемблеры не могут дизассемблировать двоичный код вируса (обычно это достигается путем размещения кода вируса в необъявленном программном сегменте). Часто злоумышленный код шифруется или сжимается, что защищает его от экспертизы. Черви Code Red распространялись половинками своих программ, маскируясь под строки переполнения, и, таким образом, формат их двоичных данных не подходил ни под один из стандартных заголовков файла.
Поэтому при анализе двоичных данных нужно знать не только о том, какие инструментальные средства и как применять, но и как обойтись без них. Анализируя заголовок файла, возможно, потребуется определить, какие данные в файле модифицированы, как и с какой целью. Вероятно, потребуется проанализировать зашифрованные данные и процедуру их расшифровки, восстановить алгоритм работы программы и выяснить результаты ее работы.
Необходимо знать ассемблер не только в объеме, достаточном для чтения ассемблерных программ, но и для написания программ расшифровки или восстановления данных. Писать на ассемблере намного сложнее, чем читать программы, написанные на этом языке.
Из этого не следует, что инструментальные средства бесполезны. Далеко не так. Нужно только выявить часть программы, оказавшуюся не по зубам инструментальным средствам, и проанализировать ее самостоятельно, а остальную часть программы – при помощи инструментальных средств. Кроме того, иногда для лучшего понимания логики работы программы следует воспользоваться инструментарием.
Тестирование методом «черного ящика»
Термин
Тестирование методом
Как и следовало ожидать, для большинства хакеров сама идея
Чипы
Предположим, что в руки исследователя попало электронное устройство, про которое хотелось бы знать, как оно работает. В настоящее время большинство электронных устройств построено на микросхемах. Вскрыв устройство, можно обнаружить, что оно состоит из множества немаркированных микросхем. Вытащив таинственную микросхему из слота, как определить, что это за чип?
Неизвестная микросхема – удачный пример встречающегося на практике
Что можно вынести из визуального осмотра? Только то, что у чипа 16 контактов или что-то подобное этому. Исследовав монтажную плату и токопроводящие слои, довольно легко можно определить контакты питания. Их можно проверить вольтметром. Но если предположение о контактах питания окажется ошибочным, микросхема будет сожжена.
Кроме того, следует попытаться сделать выводы, основываясь на других компонентах устройства. Можно составить список компонентов, подсоединенных к чипу, и выяснить, к каким контактам они подсоединены. Например, может оказаться, что два контакта в конечном счете подключены к светодиоду LED (LED – Light-Emitting Diode – светоизлучающий диод).
Если окажется, что чип – простое устройство TTL-логики (transistor-transistor logic – транзисторно-транзисторные логические схемы), то можно определить реализуемые этим чипом простые логические функции, подавая на различные контакты напряжение, эквивалентное сигналам «истина/ложь» и одновременно измеряя выходное напряжение на других контактах. Если удастся определить, что чип относится, например, к классу схем И-НЕ (NAND (not-and) gate), то по каталогу микросхем можно определить исследуемый чип или его аналог.
С другой стороны, чип может оказаться по своей сложности сравнимым с небольшим микропроцессором или встроенной вычислительной системой. В последнем случае для определения соответствия между входными и выходными сигналами методом проб и ошибок потребуется рассмотреть слишком много комбинаций. Вполне возможно, что во встроенной системе окажутся аналоговые компоненты (например, динамик), которые сведут на нет все попытки установления закономерностей двоичной логики.
С образцами подобных устройств можно познакомиться по адресу www.parallaxinc.com/html_files/products/Basic_Stamps/module_bs2p.asp. Parallax производит семейство чипов со встроенным интерпретатором BASIC, отличающихся различными комбинациями входных и выходных интерфейсов. Главная сложность подобного устройства заключается в том, что число его состояний заведомо больше, чем можно перечислить. Даже крошечный компьютер с небольшим количеством памяти может сгенерировать бесконечно большое число неповторяющихся результатов. В качестве простого примера представьте себе компьютер на одном чипе, который складывает большие целые числа. Все, что он может сделать, – это выполнить простую программу добавления 1 к введенному числу и вывести результат. Вероятно, исследователь быстро определит, что на компьютере выполняется простая программа сложения чисел, но определить другие возможности компьютера практически невозможно. Иными словами, ничего нельзя сказать о том, является ли это устройство компьютером общего назначения или оно выполняет единственную функцию.
Сложно найти закономерность при исследовании систем методом
Если из результатов исследования и доступной информации непонятно, что это за чип, то вскройте его! Вскрыть чип? Именно так. Исследователям защитного корпуса таких устройств, как смарт-карты (smart card – кредитная карточка с микропроцессором), известно много способов их изучения, включая выжигание корпуса чипа кислотой и исследование его структуры под микроскопом. Подробнее эти вопросы освещены в главе 14.
Итак, если исследователь с помощью метода «черного ящика» не может разобраться с устройством чипа, то он должен вскрыть его. Опыт посещения автором копий обсидиана (вулканического стекла) в Аризоне наглядно демонстрирует это. Если держать обсидиан на расстоянии вытянутой руки, то он выглядит как черный камень. Но при ярком свете обсидиан становится немного прозрачнее. Таким образом, он не вполне «черный ящик», а скорее в той или иной степени прозрачный
Резюме
Методологии поиска уязвимости часто используют принципы аудита безопасности систем. Изучение исходного текста программ начинается с выявления потенциально небезопасных функций, например
Аудит исходного текста программы предполагает поиск потенциально опасных функций и применение методологии построчного аудита. В этой главе были рассмотрены примеры, демонстрирующие переполнение буфера при использовании функций
Реинжиниринг – один из наиболее часто используемых методов поиска уязвимостей в программе, исходный текст которой недоступен. Этот тип исследования проводится по методике «сверху вниз». Средства аудита в Windows можно найти на сайте sysinternals.com, а список Rosetta Stone поможет выбрать средства трассировки на различных платформах. В этой главе был рассмотрен пример трассировки команды
Дизассемблер и отладчики позволяют исследовать выполнимый код. Дизассемблер (также известный как декомпилятор) – это программа, которая преобразует двоичный код в исходный текст программы на языке высокого уровня, но чаще всего на языке ассемблера. Отладчик – программа, которая может управлять выполнением другой программы. В этой главе был приведен пример дизассемблирования программы на платформе Windows с использованием отладчика IDA Pro, а также пример сессии отладки под управлением отладчика GDB в Linux. Также были обсуждены возможности программ
Конспект
Суть методологии исследования уязвимости
· Анализ и экспертиза исходного текста программы – идеальная методология поиска ее уязвимостей.
· Исследование исходного текста программ предполагает поиск подверженных ошибкам директив, построчную экспертизу исходного текста программы и изучение различий в нем.
· Изучение выполнимого кода программы осуществляется при помощи программ трассировки, отладчиков, модулей проверки текущего состояния программы (анализаторов) и аудита документации проектирования программы.
Значение экспертизы исходного текста программы
· Экспертиза исходного текста программы – необходимая часть обеспечения ее безопасности.
· Поиск подверженных ошибкам конструкций языка программирования в исходном тексте программ позволяет найти ошибки переполнения буфера, проверки входных данных и ошибки, сопутствующие конкуренции программ за ресурсы.
· Утилита
Технологии реинжиниринга
· На сайте www.sysinternals.com можно найти свободно распространяемые инструментальные средства аудита для Windows.
· Список Rosetta Stone (по адресу http://bhami.com/rosetta.html) позволяет найти программы трассировки для заданной платформы.
· Отладчики используются для управления выполнением исследуемой программы и поиска ошибок в ней или исследования логики ее работы.
Тестирование методом «черного ящика»
· Тестирование методом
· Вскрытие корпуса
· Абсолютно
Часто задаваемые вопросы
Приведенные вопросы и ответы авторов позволяют оценить степень уяснения читателем изложенного в главе материала и получить представление о возможности применения полученных знаний на практике. Если читатель захочет задать автору вопрос, то ему следует посетить сайт www.syngress.com/solutions, заполнить и отослать форму «Вопрос автору» («Ask the author»).
Вопрос: Какой наилучший метод исследования уязвимостей? Ответ: На этот вопрос можно дать только субъективный ответ. Наилучший метод исследования уязвимостей – это тот, который исследователю наиболее знаком, наиболее удобен и позволит быстрее провести исследование. Рекомендуется поэкспериментировать с различными методами и схемами их применения.
Вопрос: Законны ли с юридической точки зрения декомпиляция и другие методы реинжиниринга? Ответ: В Соединенных Штатах реинжиниринг скоро может стать противозаконным. В Акте авторского права цифрового тысячелетия (Dig^l Millennium Copyright Act) содержатся меры по предотвращению обхода обманным путем технологических мер управления доступом к работам, защищенным авторским правом. Исходный текст программы может быть защищен авторским правом, поэтому в этом случае реинжиниринг текста, защищенного авторским правом, противозаконен.
Вопрос: Какие инструментальные средства могут быть полезны при экспертизе сложных исходных текстов программ? Ответ: Такие инструментальные средства, как SCCS и CVS, могут облегчить экспертизу исходного текста программы. Кроме того, применение интегрированных сред разработки (IDEs – Integrated Development Environmen) может облегчить экспертизу исходного текста.
Вопрос: Где можно узнать правила разработки защищенного программного обеспечения? Ответ: Для этой цели подойдут ресурс Интернета «Часто задаваемые вопросы по разработке защищенного программного обеспечения в среде UNIX (Secure UNIX Programming FAQ)» по адресу www.whitefang.com/sup/secure-faq.html или список адресатов secprog, поддерживаемый Оливером Фридричсом (OliverFriedrichs).
Вопрос: Где можно достать утилиту
Вопрос: Откуда можно загрузить исходные тексты приведенных в главе примеров? Ответ: Исходные тексты доступны по адресу www.syngress.com/solutions.
Глава 5 Поиск различий