Отже, ви створили свій сайт, відвідувачі задоволені, але одного разу вам
прийшло в голову переробити сайт з використанням модного в
нині мови веб-програмування: Perl, і написати
кілька власних CGI-крипта. Припустимо, що ви
переїхали на хостинг, підтримує використання Perl/CGI
скриптів, куплений за десяток буказоїдів в місяць, і перевели
свій сайт на cgi скрипти. Але не минуло й кількох днів, як ваш
сайт був зламаний злісним кібер-недолітком з залишеної
написом, типу «Не можеш писати скрипти, не берись»! Так от,
щоб такого з вами більше не сталося, читайте цю статтю до
кінця і мотайте на вус.
#
#
#
#################################################
# #
# Вступ #
# #
#################################################
#
#
#
Професійно працюючи з мережею, можна не замислюватися над
питаннями інформаційної безпеки. Добре написані .cgi
і .pl скрипти повинні не тільки видавати гарні результати, але
і стабільно працювати. Також вони не повинні створювати дірок в системі
безпеки.

CGI-скрипти виконуються від імені непривилигированного
користувача nobody, однак є ймовірність порушення вимог
безпеки.

Цим, до речі, і обґрунтовується небажання деяких
адміністраторів давати всім користувачам можливість виконання
CGI. З іншого боку це всього лише показує некомпетенцию
цих адміністраторів в питаннях забезпечення захисту інформації.

Можливість виконання команд на сервері надається CGI-
інтерфейсом сервера. Завдання CGI-програміста полягає в тому,
щоб виконувані команди не стали дірою.
#
#
#
#################################################
# #
# Основа #
# #
#################################################
#
#
#
CGI-скриптів можна передавати параметри. І безпечний скрипт
відрізняється саме тим, що він виконується стабільно при БУДЬ-яких
можливих значеннях параметрів, переданих йому.
#
#
#
#################################################
# #
# 0х00 байт // %00 // ” #
# #
#################################################
#
#
#
Перший клас уразливостей, який я хочу висвітлити, це
використання нульового байта в Перл. Всі системні виклики
программированы на Сі, де нуль являє закінчення рядка.

Розберемо уразливість на конкретному прикладі:
==========================================

# Get Script DATA
$base=”$input.db”;
open(FILE,”$file”);}

Така реалізація експлоїта дозволить відкрити файл /etc/passwd на
читання

Як пропатчити баг:
===================

1. Для цього потрібно просто відфільтрувати всі нульові символи:
$data=~s///g;
2. Бажано також відфільтрувати відразу і символи,
перенаправляють потоки даних:
&;`”|*?~^()[]{}$
3. Далі необхідно відфільтрувати бэкслеш () і подвійні бэкслеши
$data=~s/..//g;
Така реальзация патча не дозволить здійснити перегляд
директорії по шляху виду /../../../
Після фільтрації рядок /usr/tmp/../../etc/passwd перетвориться
в /usr/tmp///etc/passwd (“..” просто будуть вирізані).

Однак тут є обхідний маневр:
достатньо передати параметр /usr/tmp/../../etc/passwd для
того, щоб обійти фільтр і передати рядок скрипту далі.

Ще приклад:
===========

$pageurl=$realpath.$DATA{‘adPath’}.”.html”;

Якщо скрипт не перевіряє передані йому дані на ‘..’ і
нульові байти, то використовуючи
‘adPath=/../../../../../etc/passwd%00’ ми можемо вказати
$pageurl на файл з паролями.
#
#
#
#################################################
# #
# Пайпи (|) #
# #
#################################################
#
#
#
Додавання пайпа до імені відкриття файлу запустить його, а не
відкриє. Так:
open(FILE,”/bin/ls”) — видасть виконуваний код
open(FILE,”/bin/ls|”) — виконає команду ls і виведе лістинг
директорії

Як пропатчити баг:
===================

Необхідно відфільтрувати s/(|)/$1/g
Буде виведено повідомлення «Unexpected end of file», так як sh
очікує, що слудующая рядок буде починатися з .

Приклад:
=======

$file=”/secret_data/$FORM”;
open(FILE,$file);

Експлоїт в даному випадку буде виглядати наступним чином:
необхідно передати $FORM -> “../../../../bin/ls|” — видасть нам
лістинг директорії
#
#
#
#################################################
# #
# Опція -e #
# #
#################################################
#
#
#
Використання опції -e є перешкодою для багатьох тих, хто
шукає уразливості в скрипті, бо як -e припинить роботу
функції, як тільки переконається, що файл, який треба
відкрити, закінчується пайпом (|).

Завдання: зробити пайп невидимим для -e, в теж час, Перл дожен
знати про його існування.

Розглянемо на конкретному прикладі:
=================================

$file=””/secret_data/$FORM;
if(!(-e $file)) die(«Fucking Hacker!»);
open(FILE,$file);
Ось вона, злісна опція -e.

Неправильний експлоїт:
======================

$file=”/bin/ls /etc|”;
if(!(-e $file)) exit;
open(FILE, $file);
close(FILE);
Даний експлоіт не дозволить нам переглянути вміст папки
/etc, так як -e бачить, що /bin/ls /etc не існує.

Правильний експлоїт:
====================

$file=”/bin/ls /etc|”;
if(!(-e $file)) exit;
open(FILE, $file);
close(FILE);
Даний експлоіт видасть лістинг поточної папки, так як /etc не
сприймається як аргумент.

Для реальзации експлоїта ми використовували нульовий байт.
ls%00|
Опція -e закінчить обробку даних на
нульовий байт і команда виконається.
#
#
#
#################################################
# #
# Перенаправлення даних () #
# #
#################################################
#
#
#
Приклад:
=======

$bug=«ls|»;
open(FILE,”$bug”);

close(FILE);

Видасть лістинг поточної директорії.

open(FILE,”$bug”);
open(FILE,”>>$bug”);
Тут команда вже не пройде і все буде в порядку.

Разом:
======

Якщо вам треба просто читати з файла, то відкривайте його як
>$output”);

Тут, використовуючи стандартний вихід за межі папки, куди нас
посадили (/../../), нам навіть не доведеться використовувати
нефильтрацию 0х00. Однак, що б ми не відкрили, файл
відкривається для дописування, тому ми повинні мати права
на запис в той файл, який намагаємося відкрити. З цієї ж
причини не спрацює і pipe (|) bug.
#
#
#
#################################################
# #
# Декілька прикладів використання багів #
# #
#################################################
#
#
#
Баг в гостьовій книзі:
=====================

Заздалегідь хочу попередити, що я не буду вказувати назву
гостьової книги, щоб ставити її автора в незручне становище.
Для вас на даний момент выжен сам процес аналізу скрипта
на вразливість.

#!/usr/bin/perl
$datafile=«guestbook.txt»;
$sendmail=”/usr/sbin/sendmail -i -t”;
########
sub urlencode{
local($val)[email protected]_;
$val=~s/+/ /g;
$val=~s/%([0-9A=Ha-h]{2})/pack(‘C’,hex($1))/ge;
}
########
if($ENV{‘REQUEST_METHOD’} eq ‘POST’){
sysread(STDIN,$query,$ENV{‘CONTENT_LENGTH’});
}
else{
$query=$ENV{‘QUERY_STRING’};
}
print «Content-Type: text/html;
if($query eq “){
print “”;
print “”;
print «Тут було ім’я гостьової книги»;
print “”;
print “”;
print “”;
print «Welcome»;
print “”;
print “”;
print «Name:»;
print «E-mail:»;
print “”;
print “”;
print “”;
}
else{
foreach (split(/&/,$query)){
if(/^Name=(.*)/){$Name=&urlencode($1);}
if(/^Email=(.*)/){$Email=&urlencode($1);}
}
open(DATAFILE,”>>$datafile”);
print DATAFILE “-=-=-=-=-=-=-=-=-“;
print DATAFILE «Date:».scalar(localtime()).””;
print DATAFILE «Name: $Name»;
print DATAFILE «E-mail: $Email»;
print DATAFILE “-=-=-=-=-=-=-=-=-“;
close (DATAFILE);
open(SENDMAIL,”|$sendmail $Email”);
print SENDMAIL «From: [email protected];
print SENDMAIL «To: $Email»;
print SENDMAIL «Subject: New Entry»;
print SENDMAIL “”;
print SENDMAIL «Dear $Name, thank you for your entries to
our guestbook!»;
print SENDMAIL «Thank you!»;
close(SENDMAIL);
print “”;
print “”;
print «Тут було ім’я гостьової книги»;
print “”;
print “”;
print “”;
print «Your Entry has been added to our guestbook»;
print “”;
print “”;
}

Перед тобою скрипт наипростейшей гостьової книги. Автору
доданого повідомлення надсилається лист подяки
на E-mail, введений ним у формі. Відправка відбувається
автоматично.

Якщо подивитися на цей скрипт з точки зору його безпеки,
цей скрипт дозволить КОЖНОМУ виконати БУДЬ-яку команду
на сервері.

Зверніть увагу на рядок
open(SENDMAIL,”|$sendmail $Email”);
Команди потраплять в командний рядок відкриття каналу (Pipe)
Відсутня яка-небудь фільтрація взагалі.
Таким чином, не важко змусити сервер виконати
open(SENDMAIL,”|/usr/sbin/sendmail -i -t [email protected]|
cat /etc/passwd”);
Це величезний удар по безпеці сервера, так як, маніпулюючи
різними командами, можна вивчати сервер зсередини, що в
здебільшого одно подальшого злому.

Порада:
======

Якщо необхідно виконання команд на каналі, не можна допускати
ситуації, коли дані від користувача потрапляють в командну
рядок відкриття каналу без попередньої перевірки або
відповідної обробки і фільтрування.

Пропатчити наведений скрипт можна так:
========================================

if($Email=~/[|;]/ || $Email~!/@/){
print “”;
print «You must enter valid e-mail address!»
exit(0);
}
Тобто ви просто перевіряєте введену адресу, і в разі, якщо він
містить заборонені символи, видаєте помилку. Даний підхід підвищить
безпека скрипта.
#
#
#
#################################################
# #
# Передача і зберігання паролів #
# #
#################################################
#
#
#
Як відомо, пароль значно підвищує рівень безпеки.
Проте паролі необхідно передавати і зберігати. Пароль — річ
секретна. Однак розташування пароля в скрипті відкритим текстом
вже саме по собі ненадійно.

Які є варіанти?
====================
1. Добре, коли скрипт взаємодіє з базою даних
витягувати пароль для перевірки звідти. В такому випадку просто
так пароль переглянути не вдасться. Якщо зловмисник і
проникне на ваш диск, то максимум, що він зможе зробити –
це дістати пароль бази даних і, приконнектившишь до неї
(що далеко не завжди виходить — багато сервери ставлять на
коннект великі обмеження) злити пароль.
2. Якщо ж ви все таки вирішили покласти пароль сам скрипт, то
слід пам’ятати, що скрипт — читабельний файл з усіма
витікаючими звідси наслідками. Щоб зробити зберігання
пароль у файлі відносно безпечним, необхідно
зашифрувати його функції crypt(); а потім застосувати наступним
чином.

#!/usr/bin/perl
####
$CryptedPasswd=«kbFIGN5En0NMv»;
####

$salt=substr($CryptedPasswd,0,2);
if(crypt($TestedPasswd,$salt) eq $CryptedPasswd){
# Продовжуємо дії

}
else{
# Невірний пароль!

}

Коментар:
============

В даному скрипті ми встановлюємо пароль-еталон в зашифрованому
вигляді. Далі на сторінці адміністратора, припустимо, вводимо
пароль, який потім шифрується в crypt(); і порівнюється з
еталоном. Якщо пароль вірний, то ти отримуєш доступ до секретних
матеріалами, якщо ні, то насладишься повідомленням про помилку. Така
система, при правильному використанні підвищить безпеку майже
до рівня UNIX passwd без shadow, а це вже досить прийнятним
функція безпеки.
#
#
#
#################################################
# #
# Пересилання паролів (GET POST vs) #
# #
#################################################
#
#
#
Вибір методу пересилання дуже важливий з точки зору безпеки.
Справа в тому, що багато програмісти передають у своїх програмах
пароль методом GET, хоча паролі потрібно передавати методом POST.
Раздница між цими методами полягає в тому, що при запиті
методом GET передані параметри є частиною URL, а при
POST вони передаються всередині тіла запиту.

Потрібно пам’ятати, що протоколи сервера можуть багато розповісти.
Ось приміром, дамп http-протоколу сервера:


…195.170.203.152 — – [20/Jun/2003:23:30:32 +0400]
«GET /index.php HTTP/1.0» 200 …
…195.170.203.152 — – [20/Jun/2003:23:35:16 +0400]
«GET /cgi-bin/auth/auth.cgi HTTP/1.0» 200 …

Справа в тому, що самі протоколи загальнодоступними і не є
секретом. Таким чином, секретоная інформація, передаваемае
за ним, теж не буде секретною. Таким чином хакер, проник
через якусь діру на ваш сервер, може отримати ще одну
зачіпку при зломі. Справа в тому, що, якщо ви використовуєте для
передачі пароля метод GET, то пароль потрапить в протоколи, а
звідти його зможе дістати будь хакер командою grep. При
передачу пароля методом POST параметри не свляются частиною
URL і в протоколи не потрапляють.
#
#
#
#################################################
# #
# Вільно поширювані скрипти: #
# #
#################################################
#
#
#
Існує багато сайтів, які пропонують своїм відвідувачам
вільно розповсюджувані фриварные скрипти. Всі представлені
там скрипти, за невеликим винятком, написані початківцями
веб-програмістами, які як правило пишуть свої програми на
основі чужих скриптів, навіть не замислюючись про питання їх
безпеки.

Моя вам порада — не беріть звідти нічого, так як 90% скриптів
потенційно уразливі і можуть бути використані для здійснення
атаки на ваш ресурс.

Якщо ви починаючий програміст і складання складного коду для
вас ще недосигаемая мрія, візьміть чужий код, викиньте з нього
всі складні елементи, паралельно перевіряючи працездатність
скрипта, щоб не викинути потрібну частину, яка не дозволить
програмі працювати коректно. Суть в тому, щоб розвантажити скрипт
до того моменту, коли все написане в ньому не стане вам
зрозумілим. Потім перечитайте мою статтю ще раз і вставити
фільтрацію введення на всі потенційно небезпечні місця.
#
#
#
#################################################
# #
# Підіб’ємо підсумок #
# #
#################################################
#
#
#
Основне завдання CGI-скриптів — дозволити відвідувачу отримувати
доступ тільки до певної частини інформації на вашому сервері,
тобто розмежування прав доступу. Вже з визначення випливає
думка про дії, спрямовані на отримання прихованої інформації
з-за некоректного втручання в роботу вашої системи. Якщо не
приймати всі наслідки серйозно, то можна надати
відвідувачам доступ до тих ділянок сервера, які
краще було б приховати від сторонніх очей. Піддаючи
всі передані скрипту дані ретельної фільтрації на
метасимволи, на нульовий байт, на прямий, зворотний і подвійні
бэкслеши, а також символи переходу за рівнями “..”, можна
забезпечити достатньо високий рівень безпеки сервера.

В різних форумах і пошукових системах часто зустрічається
скрипт, який показує якийсь файл, наприклад:
www.victim.com/cgi-bin/show.cgi?base.html покаже base.html
Однак якщо передати скрипту запит виду:
www.victim.com/cgi-bin/show.cgi?../../../../etc/passwd
Ця команда виведе нас в якості результату файл з
паролями UNIX системи. ../../… дана команда переходу
директоріях дозволить дійти до кореня диска, далі
здійснюється перехід до каталогу /etc і показується
файл паролів, розташований тамже.

Ось кілька прикладів скриптів, в яких зустрічається ця
уразливість:
www.victim.com/cgi-bin/htmlscript?../../../../etc/passwd
www.victim.com/cgi-bin/
shopper.cgi?newpage=../../../etc/passwd
www.victim.com/cgi-bin/Web_Store/
web_store.cgi?page=../../../etc/passwd%00ext
В останньому прикладі використовується описаний вище 0x00 баг.
Наприклад, show.cgi?index.htm покаже вам документ, а
show.cgi?index.htm%00 покаже вам вихідний код документа.

Великий список скриптів з уразливими даного роду можна
подивитися тут: kodsweb.ru/exploits.php
#
#
#
#################################################
# #
# Ув’язнення #
# #
#################################################
#
#
#
Природно, присвятити вас в усі тонкощі цієї теми не
представляється можливим, тому що ця тема дуже обширна,
має багато різних варіацій і підводних каменів. Опис
тільки того, що відразу приходить на розум потягне на невелику книгу.
Однак, прочитавши цю статтю і застосувавши отримані знання на своєму
сайті, ви зможете спокійно заснути, знаючи, що ваш сайт зробить
все за вас, і нещасний техномладенец черговий раз не перекине
ваш сервер.

Наостанок дам вам кілька посилань, які допоможуть вам у
освоєнні матеріалу:
kodsweb.ru/texts.php — тут ви знайдете багато статей по
захист інформації
kodsweb.ru/files.php — тут ви знайдете всі необхідні
програми для пошуку вразливостей в cgi-скрипти і аналізу
серверів на дірки в безпеці.
kodsweb.ru/exploits.php — велика колекція багів
різних сервісів в тому числі і CGI-багів.
І запам’ятайте ще одне — діри в системі потрібно нутром відчувати.
Щоб стати хорошим експертом з серевой безпеки, вам
знадобиться досвід, досвід і ще раз досвід. Навчитися цьому можна
тільки самому. Найголовніша порада, яку тут можна дати,
почаше дивіться на вашу систему очима хакера.

########
#
#
#
#################################################
# #
# Привіти #
# #
#################################################
#
#
#
FOA GreetZZ to iNo, Drakula, Aspirin, SkyLinx,
Sandy 4ll aka KODSWEB
spc 2 VooDoo2029 0ur Army f0rce MembeR
Alzo 2 all ths grps en pplz: Limpid Byte, NerF, Void,
Федір mnz Insecure, BugTraq, phrack, UKR,

spc 2 gd frndz SecurityLab, ЗАРАЗА, RootTeam, DHG.

Special 4 former GiN members: mam0nt & z00m[Killer]
alzo 2 Ripper aka former Nitr0gear
Billi_k1d, btr aka NerF
Krok and [Duke] aka Void

0ff-grp pplz .ru, Infernal, exc[ee]d [email protected], Neir0Magik

########
#
#
#
#################################################
# #
# Copyrights © #
# #
#################################################
#
#
#
Copyright © 2003 {dr}{nerve}
// KODSWEB SECURITY GROUP // All Rights Reserved.
#
#
#
$mail = [email protected]
$www = kodsweb.ru
#
#
#
$irc = Efnet, #kodsweb