Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Статьи (https://forum.antichat.xyz/forumdisplay.php?f=30)
-   -   Уязвимости SSI (https://forum.antichat.xyz/showthread.php?t=156536)

Root-access 14.11.2009 18:28

Уязвимости SSI
 
[Общие слова]



Немного погуглив, я не нашёл никаких статей о взломе сайтов через уязвимости в shtml-страницах и решил написать об этой теме в общих чертах.

Что такое SSI? Посмотрим в Википедии:

SSI (Server Side Includes — включения на стороне сервера) — несложный язык для динамической «сборки» веб-страниц на сервере из отдельных составных частей и выдачи клиенту полученного HTML-документа. Реализован в веб-сервере Apache при помощи модуля mod_include. Включённая в настройках по умолчанию веб-сервера возможность позволяет подключать HTML-файлы, поэтому для использования инструкций файл должен оканчиваться расширением .shtml, .stm или .shtm

Ну что сказать, синтаксис SSI весьма беден, так что простора для хакерства маловато. Но всё же я попытаюсь класифицировать уязвимости, которые могут возникнуть в shtml-страницах, и рассказать, как от них избавиться.


[Уязвимости include]



Собственно говоря, совершенно логично, что в страницах, написанных на языке Server Side Include может возникнуть include-уязвимость.

Рассмотрим следующий код:

Код:

<html>
<head>
<title>Тестинг</title>
</head>
<body>
<!--#config errmsg="Произошла ошибка!"-->
<!--#if expr="$QUERY_STRING" -->
<!--#include virtual="$QUERY_STRING" -->
<!--#else -->
<!--#include virtual="default.htm" -->
<!--#endif -->
</body>
</html>

Что делает этот код? Думаю Вы итак уже всё поняли, но всё же поясню.
Сначала мы объяснили интерпретатору, что в случае ошибки он должен сказать "Произошла ошибка!".
Затем идёт проверка условия: если переменная $QUERY_STRING непустая, то подключаем к странице файл, адресом которого является её значение.
Иначе подключаем файл default.htm.
Переменная $QUERY_STRING содержит GET-параметр переданный скрипту и зашифрованный в urlencode. То есть, к примеру, для запроса http://localhost/testing.shtml?la=la&la<> переменная $QUERY_STRING будет иметь значение la=la&lala%3C%3E.

Сразу видно, что в такой код уязвим: мы можем заинклудить любой файл на сервере (если хватит прав, конечно же), и, возможно, прочитать содержимое какого-нибудь файла.
Например, /etc/passwd: http://localhost/testing.shtml?/etc/passwd.

Параметр virtual оператора include может иметь в качестве значения относительный или абсолютный путь к файлу на сервере, но не может содержать имена протоколов или хостов, то есть инклуд происходит лишь локальный.

Как защититься от уязвимости? Можно, к примеру, описать все возможные GET-запросы. То есть, если у Вас немного различных файлов, которые надо инклудить, можно сделать так:

Код:

<html>
<head>
<title>Тестинг</title>
</head>
<body>
<!--#set var="warning" value="Модуль не существует!" -->
<!--#config errmsg="Произошла ошибка!" -->
<!--#if expr="$QUERY_STRING = default" -->
<!--#include virtual="default.htm" -->
<!--#elif expr="$QUERY_STRING = news" -->
<!--#include file="news.htm" -->
<!--#elif expr="$QUERY_STRING = articles" -->
<!--#include virtual="articles.htm" -->
<!--#elif expr="$QUERY_STRING = downloads" -->
<!--#include virtual="downloads.htm" -->
<!--#else -->
<!--#echo var="warning" -->
<!--#endif -->
</body>
</html>

Это аналог защиты от php-include с помощью функции in_array(), но средства языка SSI бедны, поэтому код более громоздкий.

Если у Вас много файлов, но все они одного расширения, то можно сделать так:

Код:

<html>
<head>
<title>Тестинг</title>
</head>
<body>
<!--#set var="warning" value="Модуль не существует!" -->
<!--#config errmsg="Произошла ошибка!" -->
<!--#if expr="$QUERY_STRING" -->
<!--#include virtual="$QUERY_STRING.htm" -->
<!--#else -->
<!--#include virtual="default.htm" -->
<!--#endif -->
</body>
</html>

В таком случае, изменяя GET-запрос, можно будет инклудить лишь .htm-файлы, а в них не содержится ничего секретного.
В PHP такая защита обходится с помощью null-байта. В SSI мне не удалось найти аналога этому методу. Если кто-то найдёт, буду благодарен.

Кроме того, рекомендуется использовать параметр file вместо virual в команде include, если Вам не нужно инклудить файлы с абсолютным путём.


[Уязвимости XSS]



В SSI уязвимость XSS к счастью (или к сожалению) не возникает, поскольку обработка GET-параметров идёт лишь с помощью переменной $QUERY_STRING, а она url-кодируется. Таким образом, следующий код неуязвим:

Код:

<html>
<head>
<title>Тестинг</title>
</head>
<body>
<!--#config errmsg="Произошла ошибка!" -->
<!--#echo var="QUERY_STRING" -->
</body>
</html>


[Уязвимости CGI]



Если Вы видите, что shtml-файл на каком-то сайте принимает много разных параметров, значит он передаёт их cgi-скрипту, поскольку сам обрабатывать их не умеет.
Происходит это с помощью того же оператора include. (Если Вам не нужно передавать пользовательских параметров cgi-скрипту, используйте команду exec с параметром cgi.)

Получается, если в cgi-скрипте есть уязвимости, они будут доступны атакующему через ssi-интерфейс.

Пример кода:

Код:

<html>
<head>
<title>Тестинг</title>
</head>
<body>
<!--#config errmsg="Произошла ошибка!" -->
<!--#include virtual="/cgi-bin/test.pl?$QUERY_STRING" -->
</body>
</html>

Чтобы уязвимостей не было, следите за безопасностью cgi-скриптов, но это уже совсем другая история.


[Уязвимости mod_include]



Как было сказано в начале статьи, SSI реализован в Apache при помощи модуля mod_include. А что если он уязвим?
Так и есть. Я правда не копал исходники mod_include.c, но кое-кто сделал это до меня. К сожалению бага уже старая (2004 год). Это локальное переполнение буфера.
Если у Вас есть ещё информация на этот счёт, будет интересно узнать о ней.
Вот статья от автора уязвимости и эксплойта:

http://www.securitylab.ru/vulnerability/source/210533.php

Для того, чтобы избежать уязвимости, просто не будьте археологом и не ставьте древние версии Apache.


[Общие слова]



Ну вот и всё пока. Я не претендовал на полное описание темы, но я указал на основные слабые места в SSI-скриптах, которые могут повлечь тяжкие последствия для web-мастера и хакера =).
Если у Вас есть чем дополнить данную заметку, я буду только рад. Удачи!


(c) BECHED (aka Root-access) 2009, http://ahco.ru/topic1876.html

Xex 14.11.2009 22:08

мало того что про уязвимости ни слова, так особенно порадовал раздел
[Уязвимости XSS]
=)

Root-access 14.11.2009 22:11

Цитата:

Сообщение от Xex
мало того что про уязвимости ни слова, так особенно порадовал раздел
[Уязвимости XSS]
=)

Эмм, мало того, что про уязвимости слова так есть, так ещё и подразумевается, что разделы будут пополняться. Поэтому не исключено, что в какие-то XSS появятся.

Xcontrol212 14.11.2009 22:51

Код:

<html>
<head>
<title>Тестинг</title>
</head>
<body>
<!--#config errmsg="Произошла ошибка!"-->
<!--#if expr="$QUERY_STRING" -->
<!--#include virtual="$QUERY_STRING" -->
<!--#else -->
<!--#include virtual="default.htm" -->
<!--#endif -->
</body>
</html>

Делаю запрос http://localhost/bugs.shtml?/bla/bla
Нифига не читается)



Цитата:

http://www.securitylab.ru/vulnerability/source/210533.php
Для того, чтобы избежать уязвимости, просто не будьте археологом и не ставьте древние версии Apache.
Думаю ни у кого данная версия Apache не стоит)

А так спасибо,интересный ЯП)

DarkMist 14.11.2009 22:59

актуально на сегодняшний день???
:confused:

Root-access 14.11.2009 23:25

Xcontrol212, странно, в документации сказано, что эта функция может инклудить файлы по абсолютному пути.

DarkMist, а почему, собственно, нет? Сайтов, использующих SSI пруд пруди.

ShAnKaR 15.11.2009 01:49

Цитата:

Сообщение от Root-access
Что делает этот код? Думаю Вы итак уже всё поняли, но всё же поясню.
Сначала мы объяснили интерпретатору, что в случае ошибки он должен сказать "Произошла ошибка!".
Затем идёт проверка условия: если переменная $QUERY_STRING непустая, то подключаем к странице файл, адресом которого является её значение.
Иначе подключаем файл default.htm.
Переменная $QUERY_STRING содержит GET-параметр переданный скрипту и зашифрованный в urlencode. То есть, к примеру, для запроса http://localhost/testing.shtml?la=la&la<> переменная $QUERY_STRING будет иметь значение la=la&lala%3C%3E.

Сразу видно, что в такой код уязвим: мы можем заинклудить любой файл на сервере (если хватит прав, конечно же), и, возможно, прочитать содержимое какого-нибудь файла.
Например, /etc/passwd: http://localhost/testing.shtml?/etc/passwd.

Параметр virtual оператора include может иметь в качестве значения относительный или абсолютный путь к файлу на сервере, но не может содержать имена протоколов или хостов, то есть инклуд происходит лишь локальный.

ты бы проверил

Root-access 15.11.2009 13:46

Это работает в зависимости от настройки сервера.
virtual указывает на путь относительно DocumentRoot, который указывается в httpd.conf

ShAnKaR 15.11.2009 17:55

Цитата:

Сообщение от Root-access
Это работает в зависимости от настройки сервера.
virtual указывает на путь относительно DocumentRoot, который указывается в httpd.conf

/etc/passwd будет возможно прочитать если DocumentRoot = /

Root-access 16.11.2009 22:44

Цитата:

Сообщение от ShAnKaR
/etc/passwd будет возможно прочитать если DocumentRoot = /

Да, разумеется.


Время: 20:22