четверг, 26 января 2012 г.

Переполнение буфера: теория и практика

Переполнение буфера (Buffer Overflow) — явление, возникающее, когда компьютерная программа записывает данные за пределами выделенного в памяти буфера.

Во многих источниках переполнение буфера называют самой распространенной уязвимостью программного обеспечения. Переполнение буфера присуще не только обычному ПО для PC, но также и программному обеспечению ряда аппаратных средств. Примером может служить уязвимость принтера HP LaserJet 4500, обнаруженная в 1999-ом году. Ниже будет немного теории и пример уязвимости переполнения буфера в программе.

Угрозы

DoS

Переполнение буфера может вызывать аварийное завершение или зависание программы, ведущее к отказу обслуживания (denial of service, DoS).

Повышение привелегий

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

Изменение потока управления

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

Техническое описание

Когда динамический буфер, представляющий собой автоматический массив, выделяется в функции, он создаётся на стеке во время вызова этой функции. В архитектуре x86 стек растёт от бо́льших адресов к меньшим (или справа налево, в приведённых ниже диаграммах), то есть новые данные помещаются перед теми, которые уже находятся в стеке. Здесь, (DATA) (DATA) (…) представляет существующий стек, и (NEWDATA) — это некоторое новое значение, которое ЦП поместил в стек:

(NEWDATA)(DATA)(DATA)(...)

Записывая данные в буфер, можно осуществить запись за его границами и изменить находящиеся там данные. Когда программа вызывает подпрограмму, она помещает адрес возврата в стек, так что подпрограмма знает, куда возвращать управление после того, как она завершится:

(ADDR)(DATA)(DATA)(...)

Когда выделяется динамический буфер, стек растёт влево на размер буфера. Так, если функция начинается с объявления char a[10], результатом будет:

(.a........)(ADDR)(DATA)(DATA)(...)

В конце подпрограммы память, занятая буфером, освобождается, и вызывается операция RET. Она извлекает адрес возврата из стека и выполняет переход по этому адресу, возвращая управление туда, откуда была вызвана подпрограмма.

Предположим, что 10-байтный буфер предназначен для того, чтобы содержать данные, предоставляемые пользователем (например — пароль). Если программа не проверяет количество символов, которые были введены пользователем, и записывает 14 байт в буфер, эти лишние данные будут помещены поверх адреса возврата. Таким образом, это изменит адрес, по которому будет передано управление, когда завершится подпрограмма, и с которого программа продолжит исполнение после этого.

Если пользователь не злонамерен и вводит более, чем 10 символов, добавочные данные будут скорее всего случайными. В таком случае вполне возможно, что адрес возврата будет указывать на область памяти, которая неподконтрольна текущей исполняемой программе. Это вызовет ошибку сегментации в UNIX-системах или аналогичную ошибку в других операционных системах.

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

Пример: обход проверки пароля

// sample1.c
#include <stdio.h>
#include <string.h>

void 
secret() 
{ 
    puts("secret"); 
}

int 
main(int argc, char *argv[])
{
    char buf[4] = {0};
    if (argc == 2)
        strcpy(buf, argv[1]);
    if (strcmp(buf, "123") == 0)
        secret();
    else
        puts("Acess denied");
    return 0;
}

// Makefile
APP = sample1
CFLAGS = -ggdb -O0 -mpreferred-stack-boundary=2 -fno-stack-protector
.PHONY: clean

all: $(APP)
clean:
        rm -f $(APP).o $(APP) *~

Программа запускалася на Ubuntu 11.04. Перед запуском нужно отключить Address Space Layout Randomisation (ASLR). Делается это просто:

kirill@laptop:~/sample1$ echo 0 > /proc/sys/kernel/randomize_va_space

Включить обратно можно аналогично:

kirill@laptop:~/sample1$ echo 2 > /proc/sys/kernel/randomize_va_space

Примеры запуска:

(1) kirill@laptop:~/sample1$ ./sample1
Acess denied

(2) kirill@laptop:~/sample1$ ./sample1 111
Acess denied

(3) kirill@laptop:~/sample1$ ./sample1 123
secret

(4) kirill@laptop:~/sample1$ ./sample1 `python -c "print 'a'*6"`
Acess denied

(5) kirill@laptop:~/sample1$ ./sample1 `python -c "print 'a'*7"`
Acess denied

(6) kirill@laptop:~/sample1$ ./sample1 `python -c "print 'a'*8"`
Acess denied
Segmentation fault

(7) kirill@laptop:~/sample1$ ./sample1 `python -c "print 'a'*12"`
Acess denied
Segmentation fault

(8) kirill@laptop:~/sample1$ ./sample1 `python -c "print 'a'*8+'\x24\x84\x04\x08'"`
Acess denied
secret
Segmentation fault

kirill@laptop:~/sample1$

Методы защиты

Системы обнаружения вторжения

В большинстве случаев данные, предназначенные для переполнения буфера, содержат длинные массивы инструкций No Operation (NOP или NOOP), СОВ просто блокирует все входящие пакеты, содержащие большое количество последовательных NOP-ов. Этот способ, в общем, неэффективен, так как такие массивы могут быть записаны с использованием разнообразных инструкций языка ассемблера. В последнее время крэкеры начали использовать шелл-коды с шифрованием

Защита от повреждения стека

Реализуется компилятором. Проверяется, что стек вызовов не был изменён перед возвратом из функции.

kirill@laptop:~/sample1$ ./sample1 `python -c "print 'a'*8+'\x24\x84\x04\x08'"`
Acess denied
*** stack smashing detected ***: ./sample1 terminated

Защита пространства исполняемого кода

Защита пространства исполняемого кода может смягчить последствия переполнений буфера, делая большинство действий злоумышленников невозможными. Это достигается рандомизацией адресного пространства (ASLR) и/или запрещением одновременного доступа к памяти на запись и исполнение. Неисполняемый стек предотвращает большинство эксплойтов.

Этот способ защиты не предотвращает повреждение стека. Однако он часто предотвращает успешное выполнение «полезной нагрузки» эксплойта.

Address space layout randomization (ASLR) — технология, применяемая в операционных системах, при использовании которой случайным образом изменяется расположение в адресном пространстве процесса важных структур, а именно: образа исполняемого файла, подгружаемых библиотек, кучи и стека. Например, даже если при помощи переполнения буфера или другим методом атакующий получит возможность передать управление по произвольному адресу, ему нужно будет угадать, где же именно расположен стек или куча или другие места в памяти в которые он может поместить шелл-код.

Использование безопасных библиотек

Проблема переполнений буфера характерна для языков программирования Си и C++, потому что они не скрывают детали низкоуровневого представления буферов как контейнеров для типов данных. Таким образом, чтобы избежать переполнения буфера, нужно обеспечивать высокий уровень контроля за созданием и изменениями программного кода, осуществляющего управление буферами. Использование библиотек абстрактных типов данных, которые производят централизованное автоматическое управление буферами и включают в себя проверку на переполнение — один из инженерных подходов к предотвращению переполнения буфера.

Два основных типа данных, которые позволяют осуществить переполнение буфера в этих языках — это строки и массивы. Таким образом, использование библиотек для строк и списковых структур данных, которые были разработаны для предотвращения и/или обнаружения переполнений буфера, позволяет избежать многих уязвимостей.

13 комментариев:

  1. Шаблоны действующих документов по стандартизации https://www.obzor.lt/news/n13503.html
    Образцы уставных документов по декларированию https://www.fishnet.ru/users/80224/
    Образцы уставных документов по стандартизации http://otkaznoe-pismo.mirtesen.ru/
    Примеры уставных документов по стандартизации https://sertifikatsiya.mirtesen.ru/

    ОтветитьУдалить
  2. advanced-systemcare-pro-crack out from the Audience. By way of instance, many modern PCs have SSDs that do not profit from defragging (it may decrease their lifespan), therefore even though Advanced SystemCare carries a defrag tool.
    new crack

    ОтветитьУдалить
  3. paragon ntfs khokharpc Thanks for this post, I really found this very helpful. And blog about best time to post on cuber law is very useful.

    ОтветитьУдалить
  4. piriform recuva pro farooqpc Thanks for sharing such great information, I highly appreciate your hard-working skills which are quite beneficial for me.

    ОтветитьУдалить
  5. ccleaner pro atozcracksoft Thank you, I’ve recently been searching for information about this subject for a long time and yours is the best I have found out so far.

    ОтветитьУдалить
  6. This article is so innovative and well constructed I got lot of information from this post. Keep writing related to the topics on your site. wondershare-allmytube-crack

    ОтветитьУдалить
  7. This article is so innovative and well constructed I got lot of information from this post. Keep writing related to the topics on your site. Macbooster Crack

    ОтветитьУдалить




  8. I like your all post. You have done really good work. Thank you for the information you provide, it helped me a lot. Free4links.com I hope to have many more entries or so from you.
    Very interesting blog.
    Microsoft Office 365 Crack

    ОтветитьУдалить