The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Пример эксплуатации целочисленных переполнений. (integer security attack overflow)


<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>
Ключевые слова: integer, security, attack, overflow,  (найти похожие документы)
From: __blf, RusH Security Team <http://rst.void.ru>; Date: Wed, 23 Feb 2008 18:21:07 +0000 (UTC) Subject: Пример эксплуатации целочисленных переполнений. Оригинал: http://rst.void.ru/papers/int_of.txt OpenBSD integer overflows На сегодняшний день все большую популярность приобретают целочисленные переполнения или integer overflows. Целочисленное переполнение происходит когда мы пытаемся записать в переменную значение, большее максимального значения типа этой переменной. В этой статье я расскажу вкратце про этот тип уязвимостей и приведу несколько примеров. Работать будем под OpenBSD 3.6. Рассмотрим для начала небольшой пример: #include <stdio.h> int main(int argc, char ** argv) { u_int32_t i; u_int16_t s; s = 0x100000000; // 65536 in hex i = (s % 0x100000000); printf("%d\n", i); return 0; } Программа выдаст нам 0, т.к. 0x100000000 % 0x100000000 = 0. Что будет если мы в переменную s вместо 65536 подставим 65537? Программа выдаст 1. Это основа, которая необходима для понимания целочисленного переполнения. Согласно стандарту C99, при целочисленном переполнении компилятор может вести себя как угодно. Согласно стандарту, если переменная unsigned типа не может вместить в себя какое то значение, то происходит следущее преобразование: usigned_toobig_number = usigned_toobig_number % (unsigned_max_value+1) Мы будем работать с типом unsigned short, его максимальное значение 65535, соответсвенно если мы попробуем присвоить переменной типа usigned short значение больше чем 65535, то значение переменной будет равно: u_short_number % 65536 Пример: #include <stdio.h> int main(int argc, char ** argv) { usigned short s; s = 65535; //ok printf("s is %d\n", s); s = 65536; // too big printf("s is %d\n", s); return 0; } Вот что мы получим: localhost:prog {173} ./int s is 65535 s is 0 localhost:prog {174} Все работает в соответствии со стандартом. Уязвимость целочисленного переполнения не очень опасна, т.к. она не может самостоятельно повредить какие либо участки памяти, но она может вызвать переполнение буфера, правда в большинстве случаев довольно сложно эксплуатируемое, что мы сейчас и рассмотрим на примере: #include <stdio.h> #define BUF 25 int secure_cpy(u_char *, int); int main(int argc, char ** argv) { if(argc < 3) { fprintf(stderr, "Usage: %s <value> <len>\n", argv[0]); return -1; } secure_cpy(argv[1], atoi(argv[2])); return 0; } int secure_cpy(u_char * buf, int len) { char secure_buf[BUF]; unsigned short secure_len = len; if(secure_len > BUF) { printf(stderr, "Abuse!\n"); return -1; } memcpy(secure_buf, buf, len); secure_buf[len] = '\0'; printf("%s\n", secure_buf); return 0; } Казалось бы ничего опасного в програме нет и переполнение буфера невозможно, однако тут нам и приходит на помощь целочисленное переполнение: localhost:prog {206} ./int admin 65534 Abuse! localhost:prog {207} ./int admin 65535 Abuse! localhost:prog {208} ./int admin 65536 Segmentation fault (core dumped) localhost:prog {209} Что же происходит? Почему происходит переполнение буфера? А происходит вот что: unsigned short secure_len = len; Переменной типа unsigned short присваеватся значение переменной int. Все хорошо до тех пор пока len <= 65535. Если же len будет равно 65536 то secure_len будет равно 0, и проверка: if(secure_len > BUF) { fprintf(stderr, "Abuse!\n"); return -1; } Будет пропущена, а после этого memcpy лихо скопирует 65536 байтов в 25 байтовый буфер secure_buf: memcpy(secure_buf, buf, len); В результате чего и произойдет переполнение буфера. На сегодняшний день целочисленные переполнения буфера приобретают все более масштабный характер и более разрушительные последствия. Эффективной защиты от целочисленного переполнения при использовании стандартных типов данных на сегодняшний день не существует. __blf, RusH Security Team, http://rst.void.ru

<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>

Обсуждение [ RSS ]
  • 1, exn (??), 17:43, 27/02/2008 [ответить]  
  • +/
    warning: integer constant is too large for 'long' type

    gcc version 4.1.2

    к сожалению :)

     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру