Порушення економічної безпеки користувачів мереж tcp/ip за допомогою технології "зриву стеку"
В зв’язку з переміщенням центру ваги злочинів в галузь високих технологій, проблеми економічної безпеки користувачів комп’ютерних мереж набувають надзвичайно високої актуальності[1]. Проблема "зриву стеку" турбує спеціалістів в галузі інформаційної безпеки комп’ютерних мереж вже два десятка років [2]. Ця проблема присутня у більшості сучасних операційних системах: Windows, Linux, Unix... Така технологія дає можливість реалізувати що найменше DoS (Deniel of Service - відмова в обслуговуванні) атаку, підняття прав користувача та у найгіршому випадку дозволяє отримати права суперкористувача. З допомогою "зриву стеку" чи деякої модифікації цієї технології злочинці отримують несанкціонований доступ до серверів правоохоронних структур, банків, комп’ютерів які представляють економічну та стратегічну цінність для держави. Прикладами можуть бути відомий на весь світ вірус Моріса або недавно знайдений "баг" (так хакери називають недолік у програмному забезпеченні) у сервісі RPC DCOM після якого вийшов та набув широкого поширення мережевий хробак (вірус) під назвою Sobig.F (F - модифікація). В цій роботі піде мова про правові та організаційні аспекти технологій які призводять до дуже важких, з економічної точки зору, наслідків – руйнування як програмного забезпечення, знищення комп’ютерної інформації так і фізичне руйнування окремих комп’ютерів і серверних станцій. Для того щоб показати як працює механізм зриву стеку, інакше кажучи переповнення буферу, уявімо програму що дозволяє користувачу ввести певну кількість байт. А що буде якщо замість розрахованої кількості даних програма отримає набагато більше? Наприклад максимальна довжина яка передбачена авторами 100 байт. Ми передаємо програмі 120 байт. Доки програма отримує перші 100 все в порядку, коли надходять зайві 20 байт вони затирають частину коду в пам’яті що призводить до не передбачуваних наслідків та не передбачуваних дій програми. Розглянемо програму на мові Сі:
int main(int argc,char **argv) { char inp[100]; strcpy(inp,argv[1]); printf("все в порядку \n"); }
Нам пропонують ввести 100 байт які передадуться змінній inp. Все добре до того часу доки у змінну inp не потрапить більше ніж 100 байт. У результаті такого переповнення дані які йдуть за 100 байтами які виділені під змінну inp перезапишуться. Тобто перезапишуться байти eip, ebp. Ebp – вказівник стеку, eip – адреса місця, в якому знаходилась програма до переходу в функцію. Для більш детального ознайомлення із структурою стеку радимо звернутись до статті Modern kinds of system attacks [3]. У найкращому випадку програма завершить свою роботу за сигналом 11 (помилка адресації). Але може вийти так що адреса повернення зі стеку перезапишеться не випадковими байтами а байтами які будуть вказувати на інше місце в пам’яті наприклад де розміщена програма яка буде виконувати певні дії (зміна паролю суперкористувача чи інші дії які ведуть до підвищення прав). Прикладом такої програми може бути програма для виклику Linux шелу: char shellcode[]= "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" "\xb0\x2e\xcd\x80\xeb\x15\x5b\x31" "\xc0\x88\x43\x07\x89\x5b\x08\x89" "\x43\x0c\x8d\x4b\x08\x31\xd2\xb0" "\x0b\xcd\x80\xe8\xe6\xff\xff\xff" "/bin/sh";
Для полегшення написання програм переповнення буферу (програма exploit) хакери використовують такі речі як Lib_Exploit які значно полегшують написання коду експлоіта. Типовий приклад реалізації переповнення буферу на операційній системі FreeBSD з використанням Lib_Exploit може бути програма:
#include <LibExploit.h> // Allways be included!!
int main(int argc, char *argv[]) { char *egg; long retaddr; int eggsize, offset, i;
if(argc < 3) { printf("exploit -> %s (eggsize) (offset)\n",argv[0]); exit(0); }
eggsize = atoi(argv[1]); offset = atoi(argv[2]);
if((egg = (char *) malloc(eggsize)) == NULL) { perror("malloc"); exit(0); }
// Get the esp using LibExploit_Getesp function. retaddr = LibExploit_Getesp() - offset;
for(i = 0; i < (eggsize / 4); i++) { *((long *)egg + i) = retaddr; }
// NOP is already defined in LibExploit... for(i = 0; i < eggsize / 2; i++) { *(egg + i) = NOP; }
// FreeBSD_x86_Binsh is already defined in LibExploit. // A simple FreeBSD /bin/sh shellcode. for(i = 0; i < strlen(FreeBSD_x86_Binsh); i++) { *(egg + i + (eggsize/2) - (strlen(FreeBSD_x86_Binsh) / 2)) = FreeBSD_x86_Binsh[i]; }
egg[eggsize - 1] = '\0';
memcpy(egg, "EGG=", 4); putenv(egg);
printf("eggsize/offset : %i / %i\n", eggsize, offset); printf("retaddr : 0x%x\n", retaddr);
// BINSH already defined in LibExploit, as /bin/bash. system(BINSH);
return(0); }
Приклад деяких функцій у яких може виникнути переповнення: strcpy(char *dest, const char *src) можна переповнити буфер dest strcat(char *dest, const char *src) можна переповнити буфер dest getwd(char *buf) можна переповнити буфер buf gets(char *s) можна переповнити буфер s [vf]scanf(const char *format, ...) можна переповнити аргументи функції realpath(char *path, char resolved_path[]) можна переповнити буфер path [v]sprintf(char *str, const char *format, ...) можна переповнити буфер str
Як можна побачити з вище наведених прикладів що така реалізація функцій є небезпечною. Потрібно строго контролювати дані які передаються в функції. Частково проблеми зі „зривом стеку” вирішені у таких програмних продуктах як libparanoia. При найменшій небезпеці чи помилці роботи зі стеком операційна система видає повідомлення про порушення безпеки. Тобто система інформує:
Всі ці дані записуються у log файли які в подальшому можна проаналізувати. Автори програми переписали стандартні функції такі як strcpy/strcat/sprintf якими замінені функції операційної системи. Після заміни функцій потрібно перезібрати всі критичні програми що дозволить як заявляють автори на 99% уникнути неприємностей з переповненням буферу. Найпростіша методика захисту від переповнень буферу за якою працюють програми захисту це запис контрольного байту в кінець стеку. Якщо цей бай був змінений (тобто дані „вилізли” за межі стеку) і змінили цей контрольний байт – зразу виникає тривога. Незважаючи на це, все ж існують методики переповнення: overflow in heap. Тобто переповнення виникає не в самому стеку а при вивільненні пам’яті. Прикладами таких функцій можуть бути: malloc() calloc() realloc(). На даному етапі розвитку інформаційних технологій ефективних методик захисту від таких атак є дуже мало, а тому такі недоліки у програмному коді є одними з найнебезпечніших. Наслідком таких атак може бути повне знищення інформаційних ресурсів комп’ютерних систем обробки інформації, руйнування програмного забезпечення комп’ютерів а також фізичне руйнування комп’ютера, яке призводить до тривалої зупинки роботи обчислювальних систем. Найбільш ефективним способом захисту, на нашу думку, є використання тільки ліцензійного програмного забезпечення та якомога швидше поновлення програмного забезпечення на вебсайтах розробників програмного забезпечення, які знайомі з цією проблемою[3] та несуть відповідальність за якість та надійність свого програмного продукту.
Список використаних джерел
Викладач кафедри інформатики та СТ, майор міліції С.М.Соколов 06.11.2003 Застосування інформаційних технологій у діяльності правоохоронних органів та навчальному процксі. Матеріали міжвузівської науково-практичної конференції 28 листопада 2003 р. Львів: Львівський юридичний інститут МВС України. 2004 р., ст. 162- 166 |
|||


