Захищаємо Perl, Perl
Вразливі CGI-скрипти – чудова лазівка у комп'ютерні системи. Чи можемо ми перекрити її зі 100% надійністю, раз і назавжди? У статті проаналізовано переваги та недоліки існуючих підходів до захисту Perl та запропоновано метод захисту, що ґрунтується на «хакерській» (клин клином вибивають!) підміні системних функцій процесу.
Якщо ви програмуєте (або збираєтеся програмувати) Internet-додатки мовою Perl, то напевно стикалися з інформацією, що описує вразливість цієї мови для атак хакерів. Найпростіший скрипт, наведений у будь-якому підручнику з мови Perl, насправді виявляється «широко відкритими воротами» для хакерів, як досвідчених, так і початківців. Наприклад, фрагмент коду, який просто виводить вміст вказаного файлу
насправді може виконувати інші дії. Подайте на його вхід рядок calc.exe, і ви запустите на виконання стандартний калькулятор. У запуску на віддаленому сервері стандартних програм (таких як calc.exe або notepad.exe) мало сенсу, якщо не знати про ідеальну відмичку хакера – утиліту mshta.exe. Вона входить у стандартне постачання Windows і дозволяє легко і невимушено закачувати в систему, що атакується, і виконувати в ній довільний код.
Наприклад, виконання у системі команди:
призведе до завантаження на комп'ютер файлу foobar.hta та виконання його як скрипта VBS. Цей приклад створює і запускає нешкідливий (за запевненнями організаторів сайту malware.com) додаток для MS-DOS, що показує стандартний алгоритм генерації полум'я. Звичайно, таким же способом можна закачати і виконати в системі довільний файл, що виконується, навіть якщо його там ще немає.
Кому це потрібно?
Таким чином, вразливі сервери, незалежно від їх важливості, становлять небезпеку.не меншу, ніж ті люди, які вміють використовувати ці сервери за їх прямим призначенням. 🙂
Чому Perl вразливий?
Раціональне пояснення, навіщо функція open у Perl відпрацьовує символ конвеєра як команду запустити програму на виконання, дати складно: Perl взагалі досить ірраціональна (зате гнучка і компактна) мова. 🙂 Автор мови Perl Ларрі Уолл жартома розшифровує його назву як Patalogically Eclectic Rubbish Lister (Паталогічно Еклектичний Сміттєвий Лістер) — ми можемо лише побажати, щоб наступні його версії розвивалися в напрямку більшої безпеки, однозначності та безпомилковості коду — настільки необхідних якостей для загальнодоступних . Безумовно, «патологічність», «еклектичність» та «сміттєвість» — це негативні риси, з якими Ларрі Уолл має боротися. 🙂
Фільтрування введення користувача
Оцініть, яке достаток спеціальних значків - «крокозябліків» треба відфільтрувати для простої функції відкриття файлу. Очевидно, що треба бути глибоким експертом з мови Perl та дуже уважною людиною, щоб правильно розставити всі фільтри. Оскільки від людини, на відміну від залізного брухту, важко вимагати стовідсоткової надійності, розставлені у різних місцях програми «пастки на крокозябликів» на практиці можуть не спрацювати.
Обмеження прав Web-сервера
Internet-сервер і всі запущені ним програми, так чи інакше, що контактують з усім зовнішнім світом, не повинні мати права адміністратора чи привілейованого користувача. Призначити службі Web-сервера обмежені права - дуже надійний (і, мабуть, єдино правильний) спосіб захистити свій сервер від атак ззовні.
При проектуванні Інтернет-сайту необхідно від початку розбити йогоінформаційний вміст на окремі папки, де знаходяться:
- а) виконувані скрипти та програми
- б) дані, призначені лише для читання (HTML-сторінки)
- в) дані, призначені зміни відвідувачами.
Користувач, під ім'ям якого буде запущено Internet-сервер, повинен мати доступ тільки до цих папок, причому на скрипти і дані треба накласти заборону запису (інакше хакер може трохи змінити зовнішній вигляд і функціонування вашого сайту), а на дані, призначені для зміни зовнішніми користувачами - заборона виконання (інакше він зможе створити і відразу виконати в цій папці все, що завгодно). Цей варіант захисту теоретично «нерозкриваємо» — але на практиці у адміністратора-початківця виникне низка складнощів.
Так, у системі Windows web-сервер не запуститься, якщо не відкрити йому доступні системні dll в папці c:winntsystem32. А якщо їх відкрити, усьому світу виявляться доступними чудові програми на зразок regedt32.exe, mshta.exe і т.д. Можна, звичайно, переписати на листочок список необхідних програмних системних dll і відкрити на доступ Internet-серверу тільки їх. Але чи багато адміністратори це роблять (і чи їм це потрібно?).
У Unix-подібних системах існують свої труднощі (одна з можливих проблем — закритий порт 80 для процесів, що не мають адміністративних привілеїв в системі).
У будь-якому випадку, цей метод захисту вимагає хорошої підготовки та високої мотивації адміністратора системи, що вказує на фундаментальний недолік такого захисту: його не можна встановити примусово, разом із установкою програми, що захищається, і надійність комп'ютерної системи повністю залежить від надійності найслабшої її ланки — людського мозку. .
"Лоботомія" Perl
Лоботомія - цеоперація зі зміни особи шляхом пошкодження лобових часток мозку, які відповідають за агресію. У свій час цю операцію застосовували по відношенню до злочинців, щоб зменшити їх небезпеку для суспільства. Хірург за допомогою спеціального інструменту через очниці досягав цієї області мозку і легким постукуванням дерев'яним молоточком по рукоятці інструменту наносив необхідні пошкодження (надлишкова кров та клітинна маса видалялися за допомогою гнучкого зонда).
Застосовувати подібну операцію ми не будемо не до хакерів (свого часу її визнали нелюдською та антигуманною), а до бінарного дистрибутива Perl, щоб «відрубати» у нього «агресивну» реакцію на символ («конвеєр»).
Програма sex.exe має виводити на стандартний висновок (stdout) якесь добре і зворушливе вітання для хакера. Я сподіваюся, що з її створенням ви легко впораєтеся самостійно. :-).
Перехоплення системних викликів
Ми попередили не всі небезпеки, що чатують на Perl-програміста.
Припустімо, що ми хочемо заборонити інтерпретатору Perl:
- запуск будь-яких зовнішніх програм (мудре рішення; ту ж відправку пошти, безумовно, краще виконувати стандартними функціями Perl — інакше «лоботомію» тією чи іншою мірою довелося б виконувати до всіх програм, які ми запускаємо)
- читання файлів, якщо розширення не ".html"
- запис файлів, якщо розширення не ".user".
Отримавши такий дистрибутив Perl, навіть … скажемо так, не зовсім грамотний Web-програміст (вимагати іншого від живих людей ми не тільки не вправі, а й не в змозі) почуватиметься комфортно і, найголовніше, сухо.
Роль "захисної прокладки" в даному випадку виконає спеціальна dll, яка перехопить вказані нами системні виклики і, при необхідності, їхзаблокує.
у разі Perl нам необхідно перехоплювати системну функцію CreateProcessA (запуск програми) з бібліотеки KERNEL32.dll, а також функцію fopen (відкриття файлу на читання або запис) з бібліотеки MSVCRT.dll.
Маючи ці ключові слова, ви можете знайти в Internet готове рішення, або написати додаток-«перехоплювач» самостійно.
Використання захисної DLL
Спробую запускати Perl.exe. Звичайно ж, Perl пише, що не знайдено необхідної бібліотеки romix1.dll. Що ж, створимо її. Для цього скомпілюємо програму із трьох рядків на Delphi, назвавши її romix1.dpr:
Цього недостатньо: тепер Perl під час запуску видає помилку:
Perl імпортує єдину функцію RunPerl з цієї бібліотеки, і ми її зараз створимо (наша підробка буде просто передавати управління на оригінал):
Асемблерна вставка робить перехід, куди треба. Тепер лайливі повідомлення припинилися, і змін у роботі Perl не видно. Проте ми досягли важливого результату: наша dll стала повноправним членом (якщо не мозком) виконуваного процесу Perl.exe. Подальше стає справою техніки (точніше, системних викликів Windows API та кількох «точкових» замін у таблиці імпорту Perl56.dll).
Ви можете запитати: як я дізнався, які DLL та функції імпортує програма? Відповідь проста: dumpbin.exe зі студії розробки Microsoft.
Приклад виклику цієї утиліти з командного рядка:
Висновок
Ми спробували захистити Perl один з найбільш популярних (хоча і кілька еклектичних) 🙂 мов для роботи з CGI - від атак з Internet. Ми робили це на різних рівнях:
- Фільтрацією введення користувача
- Обмеження прав доступу
- Заміною підрядок у тілі програми
- Перехопленнясистемних викликів
Можливі ще два рівні захисту:
- Перекомпіляція Perl
- Перекомпіляція ядра ОС.
Ефективність захисту у всіх розглянутих випадках йде «за наростаючим».
Зрозуміло, що нам важлива не просто перекомпіляція, а перекомпіляція з впровадженням захисних перевірок. Наша мета — впровадити ці перевірки у той чи інший спосіб, хай навіть антигуманним та «хакерським». За допомогою дерев'яного молоточка.