Опубликован: 20.02.2007 | Доступ: свободный | Студентов: 3480 / 785 | Оценка: 4.42 / 4.03 | Длительность: 40:03:00
Лекция 11:

Простые средства аудита исходных кодов

< Лекция 10 || Лекция 11: 12 || Лекция 12 >

RATS

Программа RATS (Rough Auditing Tool for Security) от Secure Software Solutions может помочь программистам сгладить шероховатости их приложений, написанных на C, C++, Perl, PHP или Python. В отличие от Flawfinder, RATS написана на C и содержит внешнюю коллекцию правил, описанных в XML, которые применяются для каждого языка.

Реализация

Программа легко компилируется большинством Unix-систем, нужно лишь убедиться, что у вас установлен Expat XML Parser (http://sourceforge.net/projects/expat/). Если Expat установлен, компиляция проходит по команде ./configure и make.

Для программы доступно несколько параметров:

RATS v1.3 - Rough Auditing Tool for Security
Copyright 2001 by Secure Software Solutions
http://www.securesw.com
usage: rats [-adhilrwx] name1 name2 ... namen
    -a <fun>        report any occurrence of function "fun" in the source file(s)
    -d <filename>   specify an alternate vulnerability database.
    -h              display usage information (what you"re reading)
    -i              report functions that accept external input
    -l <language>   force the specified language to be used
    -r              include references that are not function calls
    -w <1,2,3>      set warning level (default 2)
    -x              do not load default databases
11.2.

RATS анализирует файлы, написанные на C, но может переключаться на основе анализа расширения файлов:

  • Perl. pl, .pm
  • PHP. php
  • Python. py, .PY

Для явного указания языка C, Perl, Python или PHP используйте параметр -l. Проверка C и C++ основана на тех же самых правилах.

Программы на Perl, Python и PHP проверяются без реальной проверки особенностей конкретного языка. Perl проверяется с точки зрения системных функций (функций, эквивалентных C) вместо проверки синтаксиса и управления переменными. У вас по-прежнему может остаться очень небезопасное Web-приложение, созданное на Perl (Python или PHP); RATS обеспечивает только базовые проверки. В соответствии с ограничениями RATS, типы данных Perl не проходят проверку на строгое соответствие типам и тестирование на выход за границы. Как и C-программы, Perl- скрипты не проверяются на опасность переполнения буфера.

Совет. Perl поддерживает параметр T для "испорченных" переменных. Perl никогда не передаст такие переменные в системные функции (такие, как exeс). Это улучшает большинство входных проверок для управляющих метасимволов, которые требуется проводить в безопасных программах.

Параметры -a и -d всегда в состоянии расширить возможности RATS. Используйте параметр -a для поиска конкретных функций по аналогии с утилитой grep. Параметр -d применяется чаще, но вам потребуется владеть XML-синтаксисом. Ниже приводится пример структуры описания теста для RATS, проверяющего функцию tmpfile.

<Vulnerability>
    <Name>tmpfile</Name>
    <Info>
    <Description>Many calls for generating temporary 
file names are insecure, susceptible to race conditions). 
Use a securely generated file name, for example, by 
pulling 64 bits of randomness from /dev/random, 
base 64 encoding it and using
that as a file suffix.</Description>
    <Severity>Medium</Severity>
    </Info>
</Vulnerability>

Тег name содержит имя функции. Можно задать несколько значений рейтинга (высокий, средний и низкий). Обратите внимание на то, что просто поиск функции может дать много ошибочных положительных ответов; более гибким было бы программировать дополнения к средствам аудита.

Пример из жизни. mtr 0.46

MTR - это средство General Public License (GPL), которое объединяет в себе функциональность трассировки и Ping. Damian Gryski установил условие переполнения буфера способом, которым MTR справляется с переменной окружения MTR_OPTIONS (Bugtraq ID 4217). Переменные окружения имеют давнюю историю в качестве векторов атаки на переполнение буфера. Таким образом, не удивительно, что RATS проверяет функции, которые используют переменные окружения.

$ rats mtr.c
mtr.c:72: High: getopt_long
Truncate all input strings to a reasonable length before passing them to this function
mtr.c:139: High: fixed size local buffer
Extra care should be taken to ensure that character arrays that are allocated on the stack 
are used safely. They are prime targets for buffer overflow attacks.
mtr.c:180: High: getenv
Environment variables are highly untrustable input. They may be of any length, and contain 
any data. Do not make any assumptions regarding content or length.
If at all possible avoid using them, and if it is necessary, sanitize them and truncate 
them to a reasonable length.
mtr.c:185: High: printf
mtr.c:190: High: printf
Check to be sure that the non-constant format string passed as argument 1 to
this function call does not come from an untrusted source that could have added
formatting characters that the code is not prepared to handle.
mtr.c:236: High: gethostbyname
DNS results can easily be forged by an attacker (or arbitrarily set to large
values, etc.), and should not be trusted.
11.3.

Вот строка кода, которая генерировала вывод в RATS (такая же строка могла быть обнаружена с командой grep getenv mtr.c):

parse_mtr_options (getenv ("MTR_OPTIONS"));

RATS идентифицировал потенциальную уязвимость. Дело контролера трассировать уязвимость в функции parse_mtr_options и определять, обоснован ли вывод. Przemyslaw Frasunek сумел найти иллюстрацию того, как функция parse_mtr_options нерационально оперировала с переменной MTR_OPTIONS. Вот часть уязвимого кода:

while (p) {
    argv[argc++] = p;
    p = strtok (NULL, " \t");
}

Переменная p является указателем ячейки памяти, которая может содержать не только значение переменной окружения MTR_OPTIONS, но также данные, которые могут быть помещены в память и использоваться для исполнения произвольных команд. Функция strtok C оперирует со строками, хранимыми в памяти, разыскивая конфигурации, специфицированные в ее втором аргументе ( " \t" или комбинацию пробела и символа табуляции в этом примере). Когда strtok получает значение NULL для первого аргумента, она оперирует на текущем указателе, в данном случае p. Однако взломщик может создать зловредные MTR_OPTIONS, которые запишут shellcode поверх указателя - другими словами, выполнят произвольную команду.

Авторская вставка реализует проверку длины переменной p и сообщает о посторонних данных:

while (p && (argc < (sizeof(argv)/sizeof(argv[0])))) {
    argv[argc++] = p;
    p = strtok (NULL, " \t");
}
if (p) {
    fprintf (stderr, "Warning: extra arguments ignored: %s", p);
}

Контроль от RATS и следование рекомендации "Не делайте никаких предположений относительно содержимого или длины" отразили атаку.

Пример из жизни. Канарейка во мгле

В начале этой лекции мы высказывали пожелание, чтобы появился компилятор, который будет создавать "неразрушаемые" приложения. Stackguard с http://immunix.org - это коллекция вставок в программы для компилятора GCC. Эти вставки превращают GCC в активного защитника любого кода C или C++, которые он компилирует. Базовая концепция заключается в том, что вызовы функций, потенциально уязвимых к переполнению буфера, имеют случайные значения, присоединяемые к области памяти.

Когда взломщик пытается переполнить буфер, атака портит область памяти, которая содержит такие случайные значения. Программа распознает, что случайное значение было модифицировано и внезапно останавливается - без выполнения любого опасного кода, внедренного атакующим.

Мы будем лишь поддакивать великолепной документации Stackguard, чтобы описать защиту от переполнения буфера в соответствующих деталях. Посетите сайт http://immunix.org для получения дополнительной информации.

Помните, что установки Stackguard и "nonexecutable stack" не являются панацеей от переполнения буфера. Есть документированные способы перехитрить методы защиты, подобные Stackguard. Защитите свою сеть, свою главную машину, а затем приложение - лишняя осторожность никогда не помешает.

< Лекция 10 || Лекция 11: 12 || Лекция 12 >