Авторские статьи ошибки CGI защита и нападение

Discussion in 'Статьи' started by ImpLex, 14 Dec 2008.

  1. ImpLex

    ImpLex Member

    Joined:
    12 Dec 2008
    Messages:
    23
    Likes Received:
    20
    Reputations:
    5
    Введение

    Добрый вечер. Многие сталкивались с perl скриптами.

    кому-то это было нужно для системных нужд.
    каким-нить скрипткидисам запустить очередной сплойт, не поняв как он работает.
    Ну а кто-то занимается cgi программированием.
    Конечно это не так популярно, как PHP но все же иногда очень незаменимо, именно для этих людей я пишу данную статью. В ней будет рассказано о двух возможных ошибках, которые вполне могут помочь взломщику повысить свои права в системе, а также о защите. Поехали.
    Некая особенность​

    Если все хорошо настроено, то все приложения CGI выполняются под юзером права которого в системе очень небольшие, но к сожалению(а может и счастью), если удается добиться выполнения системных команд, то во многих случаях, есть возможность эти права повысить. Поэтому к безопасности CGI приложений нужно отнести очень серьезно.

    Ошибка # 1 Опасная работа с файлами.​


    Вообще по сути как в perl так и В php, многие операции с файлами вызывают какую-то долю риска.
    Я накалякал простенький бажный скрипт.
    Code:
    #!/usr/bin/perl
    use CGI qw(:standard);
    $file=param(load);
    print "Content-Type: text/html\n\n";
    open(F,$file);
    while(<F>) { print }
    close(F);
    __
    Проанализируем:
    1 строчка - путь к интерпретатору.
    2 строчка-подключаем необходимую библиотеку.
    3 строчка - присваиваем значение переменной $file параметра load .
    4 строчка выводим заголовок Content-Type
    5 строчка открываем файл какой именно указывет переменная $file
    6 строчка загоняем в цикл и выводим построчно
    7 закрываем файл
    __
    Т.е Передать значение $file можно прямо из браузера.
    Code:
    http://site.ru/script.pl?load=file
    Не трудно догадаться, что если мы передадим переменной $file значение к примеру ../../../../../../../etc/passwd, скрипт нам выдаст его содержимое. Ну тут ясно в чем ошибка, хочу обратить внимание на ещё один трюк, который мы можем проделать с этой ошибкой. Волшебный символ '|' разберемся, что он делает.
    Он заставляет наш скрипт, который открывает файл по-просту выполнить его. то есть если $file примет значение |ls , то в итоге нам будет выведен результат выполнения команды ls. С виду казалось, что ничего страшного в этом нет, а на самом-то деле все совсем иначе. Подходить к безопасности cgi надо очень серьезно
    способы защиты

    Первый способ
    универсальный способ, а именно фильтровать ненужные символы
    например
    Code:
    #!/usr/bin/perl
    use CGI qw(:standard);
    print "Content-Typ: text/html\n\n";
    $file=param(load);
    $file =~ s/([|])/\\$1/g;
    open(F,$file);
    while(<F>) { print }
    close(F);
    мы добавили фильтр
    Code:
    $file =~ s/([|])/\\$1/g;
    на '|' и теперь трюк с выполнением команд не прокатит. Однако читать файлы это не помешает нужны более жесткие фильтры типа
    Code:
    $file =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n])/\\$1/g;
    вот теперь уже далеко с чтением не уйти.
    А вообще у меня в мыслях более интересный подход к ситуации а именно
    Code:
    #!/usr/bin/perl
    use CGI qw(:standard);
    print "Content-Typ: text/html\n\n";
    $file=param(load);
    if ($file eq file1) {
    open(F,"файл, который вы хотите загрузить");
    while(<F>) { print }
    close(F);
    }
    if ($file eq file2) {
    open(F,"другой файл который вы хотите загрузить");
    while(<F>) { print }
    close(F);
    }
    else {
    print"файл не прочтен";
    }
    Думаю тут все ясно, идет отбор по условию, если запрашиваемая строчка не подходит ни к одному условию, мы заставляем скрипт ругаться то есть что-то print'ить. Единственный минус может всплыть, когда условий очень много. А так больше добавить нечего. На этом с первой ошибкой закончу. Подопытный скрипт слишком упрощен, чаще встречаются более сложные версии подобных скриптов и это вполне логично. Однако, если скрипт более наворочен-это не значит, что он является безопасным, и там вполне может быть допущена подобная ошибка. Ещё раз повторю, глаза на это лучше не закрывать.


    Ошибка # 2 Sendmail.​

    Просто отправка писем. Кажется, что безобидно, на самом деле все иначе. Вот пример бажного скрипта
    Code:
    #!/usr/bin/perl
    use CGI qw(:standard);
    print "Content-Type: text/html\n\n";
    $query = new CGI;
    $prog='| /usr/sbin/sendmail';
    $address= $query->param('mail');
    $from='hackme@localhost';
    open (MAIL,"$prog $address"); 
    print MAIL "From: $from\nSubject: YO!\n\n";
    print MAIL "; )\n"; 
    close MAIL;
    
    Проанализируем
    Думаю, что вы поняли суть работы скрипта.
    Для удобства иногда создают удобную формочку для отправки данных на скрипт, но это не важно.
    что будет, если мы присвоим $adrdess Значение |ls| ?
    | - заставит выполнится нашу команду, и результат ее выполнения будет нам выдан самым явным образом . Кроме того, хочу обратить внимание, передаваться пользователем может не только адрес почтового ящика, а все что угодно.
    способы защиты​

    Очевидно, что в данном случае можно также использовать фильтр, только на этот раз мы действуем с почтой, и тут надо быть внимательнее, так как в адресе почты используются некоторые символы, которые фильтровать просто недопустимо. Фильтровать, но с умом. Например символ @ (Собачк0) лучше оставить в покое. Хотя не совсем можно намутить некоторый шаблон. типа 'одно значение'@'другое значение', то есть передавать не одно значение ака почтовый адрес целиком. а два то есть имя почтового ящика и домайн.

    Дополнения​

    Если удается обнаружить бажный Perl скрипт, частенько не удается залить шелл чисто потому, что не работают программы, которые нам бы помогли залить шелл. Встречается часто. Но этих программ придуманно много.
    -wget
    -fetch
    -lynx
    -links
    -get
    -curl
    При помощи which можно посмотреть, какие установлены, обычно такие все-таки находятся. Просто часто отключают Wget.
    $IFS-пробел,табуляция,перевод строки - можно использовать вместо пробела, когда стандартный пробел не канает.
     
    #1 ImpLex, 14 Dec 2008
    Last edited: 14 Dec 2008
    4 people like this.
  2. ImpLex

    ImpLex Member

    Joined:
    12 Dec 2008
    Messages:
    23
    Likes Received:
    20
    Reputations:
    5
    продолжение

    Итак после того, как мы разобрались с ошибками характерных для perl, перейдем к следующему виду ошибок, которые касаются не только cgi, но и остальных приложений, например php

    Ошибка # 3 межсайтовый скриптинг

    Вы думали не актуально? ага щас... В perl подобное тоже присутствует.
    В чем же все заключается?
    Да все просто, эта ошибка начинается сразу после того, как мы ввели
    print "Content-Type: text/html\n\n";
    Теперь и Script тоже будет выполняться, и если программист разрешил пользователю скрипта присваивать значения некоторым переменным, которые в итоге выводятся в контенте страницы, причем без всяких ограничений, то это выливается в XSS рассмотрим наипростейший скрипт.
    Code:
    #!/usr/bin/perl
    use CGI qw(:standard);
    $parametr=param(load);
    print "Content-Type: text/html\n\n";
    print "$parametr";
    
    в последней строчке, мы просто выводим переменную, которую может определить пользователь, а ему ничто не мешает в качестве параметра передать.
    Code:
    www.site/cgi-bin/script.pl?load=<script>alert('xak')</script>
    То есть присвоить $parametr злое значение, которое в итоге выводится и выскакивает алертом. Многие программисты используют вывод в контент. Обычно можно наблюдать в полях поиска и в других ситуациях, когда нужна некая определенность.
    Защита

    Если уж сильно приспичило, выводите на здоровье, но поставьте хоть банальный фильтр на ненужные символы.
    Code:
    #!/usr/bin/perl
    use CGI qw(:standard);
    $parametr=param(load);
    print "Content-Type: text/html\n\n";
    $parametr =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n])/\\$1/g;
    print "$parametr";
    
    Такой код очень попортит затеи хакера, если попытаться присвоить нашей переменной то же самое значение
    Code:
    www.site/cgi-bin/script.pl?load=<script>alert('xak')</script>
    то фильтр хорошенько попортит скрипт и в результате выдастся что-то вроде.
    Code:
    \<script\>alert\(\'xak\'\)\</script\>
    Такое чучело конечно же не подлежит выполнению.


    Ошибка # 4 неаккуратное использование команды system()​

    Известны такие скрипты, которые используют для работы сие чудо. Эта функция несет самую, что есть прямую опасность.
    Code:
    #!/usr/bin/perl
    use CGI qw(:standard);
    $parametr=param(load);
    print "Content-Type: text/html\n\n";
    system($parametr);
    
    Опять же простенький скрипт. И если передать параметру Load передать значение id который потом присвоится переменной $parametr. В результате мы будем наблюдать. Результат выполнения этой команды. Что не есть хорошо. Скрипты испольщующие эту функцию иногда встречаются, не так часто как вышеперчисленный, но встречаются.
    Как защитить?​

    Выход всегда есть.
    Самое главное давать system'у только свои значения, нельзя, чтобы они как-то передавались пользователем скрипта.
    Code:
    #!/usr/bin/perl
    use CGI qw(:standard);
    $parametr=param(load);
    print "Content-Type: text/html\n\n";
    if ($parametr eq com1) {
    system("ваша команда");
    }
    if ($parametr eq com2) {
    system("другая ваша команда");
    }
    else {
    print"error";
    }
    
    вроде как ничего сложного, а обезопасить подобные скрипты всегда стоит.
    Ошибка # 5 sql injection​

    И в perl есть модули для работы с базами данных. На этом особо внимание зациклиать не буду, так как проведение sql inj, и защита в perl. Мало чем отличается от этого например в php.
    Google

    Сайтов-жертв найти можно ООЧЕНь большое количество. Можно использовать для этих целей гугл например:
    Code:
    inurl:"/cgi/bin/index.cgi?file="
    inurl:"/cgi/bin/index.pl?id="
    B тому подобные запросы. Уязвимых скриптов хватает.
    Заключение

    Вот и все, что я хотел на данный момент рассказать, если есть дополнения или ошибки, жду комментариев, чтоб поправить или дополнить. На этом все, спасибо за прочтение.
    (С)ImpLex
     
    #2 ImpLex, 14 Dec 2008
    Last edited: 14 Dec 2008
    1 person likes this.
  3. ImpLex

    ImpLex Member

    Joined:
    12 Dec 2008
    Messages:
    23
    Likes Received:
    20
    Reputations:
    5
    статья чисто моя.
    Писалась с нуля ... И использованы чисто мои знания.
    + статья не закончена. Ещё будет несколько пунктов
    А вообще, если сомнения терзают, найди такую же статью в интернете с более ранней датой публикации, тогда и говори, что я ее стырил, а если сомнения терзают, тогда лучше бы не оффтопил в моей теме
     
    #3 ImpLex, 14 Dec 2008
    Last edited: 14 Dec 2008
  4. ртуть

    ртуть Elder - Старейшина

    Joined:
    31 Aug 2007
    Messages:
    314
    Likes Received:
    389
    Reputations:
    29
    на qwerty.nanko.ws такое было, вгоду эдак 2000-2001..... перловые цги баги не актуальны! борода дремучая!
    в 8-м или 9-м выпуске defaced zine была статья с интересными финтами :Р вот там да!... а тут, автор звиняй. но ничего нового %\
    пс: а вообще напомнинает сборную солянку из древних паперов rst, kodsweb
     
    1 person likes this.
  5. ImpLex

    ImpLex Member

    Joined:
    12 Dec 2008
    Messages:
    23
    Likes Received:
    20
    Reputations:
    5
    Конечно, это правда, cgi баги-Довольно старая тема...
    Ну как же они не актуальны? Раз присутствуют на ресурсах интернета cgi, скрипты, значит, вполне ещё актуальная тема, что старо - ещё не значит, что неактуально
    Вот теперь статья дописана. Может тема и избита... Но достойного нормальных факов на античате я не находил... Да в интернете мало нормального материала
     
    #5 ImpLex, 14 Dec 2008
    Last edited: 14 Dec 2008
    1 person likes this.