11 Августа, 2011

Http Parameter Contamination (more)

Dmitriy Evteev
Продолжая исследование атаки Http Parameter Contamination (HPC) , мною был проведен примитивный фаззинг, в том числе в тех средах, которые не были затронуты Ivan Markovic в его оригинальном исследовании. Стоит сразу отметить, что ничего принципиально нового найдено не было. С другой стороны была выявлена интересная особенность интерпретатора Python, а также, получен боевой сплоит на отказ в обслуживании в отношении сервера Tomcat :) Но по последнему, пока non disclosure. Полученные результаты представлены на картинке ниже. name='more'> * символ "0" означает, что null-byte корректно обрабатывается приложением. Наиболее интересные особенности выделены темно-красным цветом. Менее интересные, но заслуживающие внимания, выделены бледно-красным цветом. Рассмотрим полученные результаты более подробно. Самую большую ценность для атакующего представляет особенность обработки поступающих данных веб-приложением на языке ASP. Дело в том, что приложение на ASP встретив символ "%" в имени параметра или в его значении попросту удаляет его, если он в свою очередь не образует "правильный" символ при URL-декодировании. Это позволяет довольно просто обходить различные фильтры безопасности и Web Application Firewall, которые используются до обработки поступающих данных приложением. Ivan Markovic в своем исследовании приводит следующий пример обхода правил Mod_Security при эксплуатации уязвимости Path traversal: http://192.168.2.105/test.asp?file=.%./bla.txt Более жизненно для платформы IIS является использование СУБД MSSQL и появление уязвимостей в приложении типа SQL Injection. Аналогичным образом, применяя этот метод можно воспользоваться и этой уязвимостью в обход соответствующих правил Mod_Security: ?id=1;selec%t+@%@version-- ?id=1;selec%t+convert(int,(selec%t+table%_name+from(selec%t+row_number()+over+(order+by+table%_name)+as+rownu%m,table%_name+from+information_schema.tables)+as +t+where+t.rownu%m=1))-- ... Тут стоит сделать оговорку, что речь идет только про обход базовых правил Mod_Security (base rules). В случае использования расширенных правил (optional и experimental) такие финты уже не проходят. Другая, не менее полезная особенность обработки поступающих данных, встречается в интерпретаторе PHP. Это неявное приведение типов (?param[]=123 -> param=Array), которое всем должно быть давно известно и возможность контролировать массив  $_SERVER["argv"] (?1+2) при установленной в конфигурации "register_argc_argv" в значении "on". Первой особенностью PHP атакующий может воспользоваться с целью обхода различного рода ограничений (например, при неявном сравнении переменных), а также с целью принудительного вывода сообщения об ошибке (аля раскрытие корневого каталога веб-сервера). Вторая особенность PHP позволяет обратиться к сценарию через веб-сервер и передать ему параметры, которые сценарий принимает из командной строки. Менее интересной особенностью PHP является замена символов "+", ".", "[" и "пробела" на символ нижнего подчеркивания ("_"). Почему это не столь опасно? Дело в том, что такое поведение PHP наблюдается только в именах передаваемых параметрах к веб-серверу, но не в их значениях. Это сильно снижает вероятность использования этой особенности в "живой природе". И последнее, на что хотелось обратить внимание, это на интерпретатор Python. Во время фаззинга было установлено, что Python встретив символы из диапазона %80-%FF возвращает сообщение об ошибке (аля раскрытие и бла-бла): (Приложение)  Для тестирования использовались сценарии, которые приведены ниже. PHP: <?php $G = &$_GET; foreach ($G as $k=>$v) { print $k."=".$v; } ?> ASP: <% for each var in Request.QueryString    Response.Write ( var & "=" & Request.QueryString ( var ) ) next %> JAVA: <% java.util.Enumeration names = request.getParameterNames(); while(names.hasMoreElements()){ String keyx = names.nextElement().toString(); out.println(keyx + "=" + request.getParameter(keyx)); } %> PERL: use CGI; my $cgi = new CGI; my @params = $cgi->param(); print <<ENDOFTEXT; HTTP/1.0 200 OK Content-Type: text/html ENDOFTEXT foreach my $parameter (sort @params) { print $parameter."=".$cgi->param($parameter); } PYTHON: import cgi, os print ('Status: 200 OK') print ('Content-type: text/html; charset=utf-8;') print("") query = os.environ.get('QUERY_STRING') pairs = cgi.parse_qs( query ) for key, value in pairs.items():     print (key,value)