• XSS.stack #1 – первый литературный журнал от юзеров форума

HTTP-граббер

Homez

floppy-диск
Пользователь
Регистрация
08.07.2011
Сообщения
7
Реакции
0
Здравствуйте, Уважаемые! Пишу на C++ HTTP-граббер, инжектищайся в IE и Firefox. Возникли две следующих проблемы:

1. С IE не удается перхватывать все запросы методом POST. Например, логин на сайте free-lance.ru, С Firefox вроде таких неудач нет, в логе вижу вводимые мной при авторизации логин и пароль. А с IE - нет. Хотя, в то же время, в логе могу наблюдать данные другого POST-запроса. А именно аторизации - нет. Со многими другими сайтами - та же байда. Перехватывал HttpSendRequest и HttpSendRequestEx и ансишной и юникодной версии, а также InternetWriteFile, вроде все учел, не пойму, как некоторые запросы проходят мимо моих хуков? Где я мог допустить оплошность?

2. Проблемы при замене части содержимого страниц, выдаваемых пользователю браузером. Для примера я сделал подмену заголовка страницы, соответственно, в ее тексте искал тэги <title> и </title> и подменял текст между ними на что-то вроде Hello! Работает почему-то не везде. Я не говорю о тех случаях, когда тэги написаны заглавными буквами, у меня пока поиск без учета регистра, настроен на строчные символы. С сайтом http://www.kurort.ru/ в файрфоксе все нормально, тайтл подменяется. А вот, например, с http://jimm2009.ru/ - уже нет. Хоть тэги и в нижнем регистре, они не находятся и тайтл не заменяется. Такое чувство, что опять-таки, какие-то страницы открываются в обход моих хуков. В файрфоксе я хукнул PR_Read, думая, что этого достаточно. Но вот, опять не все гладко.

С ие в этом отношении тоже есть проблема. Причем здесь уже несколько по-другому. У ненавистной вебальты тайтл подменяется, если нажимать F5 и не подменяется, если после http://webalta.ru/ в адресной строке нажать энтер. Крайне странно. Были хукнуты InternetReadFile и InternetReadFileEx.

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

Добавлено в [time]1310137081[/time]
1. С IE не удается перхватывать все запросы методом POST. Например, логин на сайте free-lance.ru, С Firefox вроде таких неудач нет, в логе вижу вводимые мной при авторизации логин и пароль. А с IE - нет. Хотя, в то же время, в логе могу наблюдать данные другого POST-запроса. А именно аторизации - нет. Со многими другими сайтами - та же байда. Перехватывал HttpSendRequest и HttpSendRequestEx и ансишной и юникодной версии, а также InternetWriteFile, вроде все учел, не пойму, как некоторые запросы проходят мимо моих хуков? Где я мог допустить оплошность?
оплошности нет. сайт не передает логин или пароль в привычном запросе.
при нажатии "войти" генерируется страница в которой появляются строки
Код:
<link href="/static.php?t=MDovc3R5bGVzLmNzczovY3NzL25hdi5jc3M6L2Nzcy9wcm9tby5jc3M6L2ZsMi5jc3M=" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="/static.php?t=MTovc2NyaXB0cy9zd2ZvYmplY3QuanM6L2ZyZWVsYW5jZXJzL3BsYXllci5qczovd2FybmluZy5qczovc2NyaXB0cy9tb290b29scy1uZXcuanM6L3NjcmlwdHMvbW9vdG9vbHMtbW9yZS5qczovc2NyaXB0cy9uZXdfc2l0ZS5qczovc2NyaXB0cy9uZXcuanM6L3NjcmlwdHMvbmF2Lmpz"></script>
они то и передают зашифрованый логин и пасс

Добавлено в [time]1310137189[/time]
вобщем логин и пасс шифруются яваскриптом и передаются зашифроваными при помощи get
такие формы чаще всего грабятся при помощи инжектов
 
DeusEx
никто не призывает копировать. как наглядный пример - вполне сгодится для освоения
 
в сорцах зевса ответа на 1й вопрос тса не содержится
по второму вопросу. не смог у себя воспроизвести ни одну из твоих проблем.
титл http://jimm2009.ru/ в фф подменяется
титл http://webalta.ru/ в ие тоже подменяется, кстати InternetReadFileEx я совсем не хукал. этой апишкой страницы не грузятся, графика восновном которую точно подменять не нужно.
перепроверь конфиг этих инжектов. возможно где-то там ошибка.

еще у http://jimm2009.ru/ есть маленькая особенность
Код:
<html><head><title>Jimm - ICQ для телефона</title>
тайтл не с новой строки а в одной строке с хтмл и хедом.
возможно твой код ищет вместро строки "<title>" строку CR+LF+"<title>"
(тоесть тайтл с новой строки), и не находит его конечно.

у http://webalta.ru/ перед тайтлом стоит таб
<title>Поисковая система Webalta</title>
возможно он при водит к такой-же проблеме.

если не поможет, то под отладчиком смотри в чем проблема.
или выкладывай код, будем курить.
 
2 DeusEx:
Ну вообще-то программе по барабану, есть ли там таб или или символы перевода строки перед тэгом тайтла, поиск начинается строго с символа "<".

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

Опять 2 DeusEx:
А как ты хукал апи? Из зевса взял?
И это, что оплошности нет, ты говоришь именно про free-lance? Почему же тогда в файрфокс делается пост-запрос, а в ие - гет?
 
апи хукаю трамплином, меняю первые байты. код не из зевса. как реализовано в зевсе хз.
перепроверил free-lance на ие, пост с логином и пассом в лог упал. урл не был включен в вебфильтрах \=
если ты точно уверен в алгоритме который берет инжект из списка и вставляет его в страницу
то тебе только остается вариант смотреть работу браузера под отладчиком в момент инжекта
 
Гм, жаль.
А что такое трамплин?
С отладкой что-то не получается. Длл же моя запускается в составе процесса браузера, не имею представления, как подцепить его в отладчике вижуал студио и привязать символы. В перпективе думаю сделать даже и не встраивание длл, а перенос в адресное пространство процесса браузера только кода функций, это посложнее будет. Как тогда прикажешь отлаживать.
 
только что проверил свой граббер на free-lance.ru, все четко, как в ие, так и в огненном лисе.
Код:
referer: http://www.free-lance.ru/
data: action=login&login=fl&passwd=123

referer: http://www.free-lance.ru/remind.php?incorrect_login=1
data: xjxfun=GetNewMsgCount

referer: http://www.free-lance.ru/
data: action=login&login=rrrr&passwd=tttt

referer: http://www.free-lance.ru/remind.php?incorrect_login=1
data: q=79267654321
запости кодес, может чего и подскажу.
 
трамплин это когда первые несколько инструкций апи копируются в другое место, а на их место вставляется переход на функцию обработчик, которая после выполнения направляет на скопированые инструкции а затем на оригинальную апи.

отладить можно через ollydbg
запускаешь ие с подгруженой дллкой, подключаешься дебагером, view > executable modules, ищешь в списке wininet, правой кнопкой по ней и выбираешь show names, в списке ишешь апишку которая перехвачена твоей дллкой и ставишь на нее бряк. далее жмешь f9 и в браузере идешь на какой-нибудь сайт. сработает бряк - отлаживай.
 
У меня возник еще один вопрос. Пока подмена у меня делается в Firefox только каждом чанке данных, независимо от других для данного запроса. Это не есть гут, так как из-за того что длина исходных данных и данных с выполненой подменой может различаться, данные местами могут съехать, что-то перекрыть и т.п. Кроме того, меня надоумили, что некоторые сайты могут возвращать тексты страниц в gzip, и чтобы получить доступ к исходным данным, мне надо сделать их декомпрессию, а это возможно только если я свяжу все чанки для одного запроса воедино. Поэтому вопрос такой: как мне вычислить, какие куски данных, возвращаемых функцией PR_Read, относятся к одному запросу, а какие - нет? Как-то на основе структуры fd, первого параметра этой функции, но как именно?
 
чтоб сайты не возвращали тексты страниц в gzip можешь удалять или модифицировать заголовок "Accept-Encoding: ..." из запросов.
например в зевсе этот заголовок меняется на "Accept-Encoding: identity".
значение "identity" означает запрет любого кодирования.
 
Ну думаю, лучше сделаю дешифровку/шифровку gzip. Да и в любом случае, надо знать, как разные фрагменты данных по одному запросу в файрфокс связать. С ИЕ все понятно, там уникальные айдишники, а здесь как-то мудрено
 
Чтобы избавиться от chunked необходимо делать запрос HTTP 1.0. Этот протокол не поддерживает разбиение данных и ты получишь все оптом за один присест.
 
Firstly I want to apologize for not replying in Russian. I'm just not able to speak it, bur I will add a google translated version of this.

I don't know if it was already said but the problem that some sites just can't get grabbed may be because of the Protected Mode. You can circumvent that simply by disabling it (For a example take a look at ZeuS.)

About the HTML-Injection issues:
Patching "Accept-Encoding" is absolutely fine.
The next easiest solution is to return -1 (Error try again later) until the complete stream has been loaded, then decompress and inject, and return the newly compressed string.
--------
Я не знаю, если уже было сказано, но проблема, что некоторые сайты просто не может получить схватил может быть из-защищенном режиме. Вы можете обойти это, просто отключив его (Для примера взгляните на ZeuS.)

О HTML-инъекция вопросы:
Исправление/Splicing/Hooking "Accept-Encoding" абсолютно нормально.
Следующим простым решением является возврат -1 (Ошибка, повторите попытку позже), пока весь поток был загружен, то распаковывать и инъекции, и вернуться вновь сжатые строки.
 
2 TrueUser:
Прошу прощения, что отвечаю спустя довольно большое время, но сейчас я вернулся к проблеме. Пытаюсь разобраться с заменой содержимого с учетом того, что данные могут возвращаться за несколько вызовов функции в IE. Спасибо, это хорошая идея с версией HTTP, я склоняюсь к использованию этого.

Однако, меня гложут сомнения. Ведm кол-во вызовов, например, InternetReadFile не зависит напрямую от числа пакетов HTTP, если данные разбиты по ним, а зависят от размера передаваемого этой функции буфера. И мне кажется, что по крайней мере перед первым вызовом IE не может догадываться о размере всей читаемой страницы, поэтому и в случае, когда страница передается в одном только пакете HTTP, вызовов функции чтения должно быть как минимум два. И тогда проблема увязки содержимого нескольких буферов все равно остра.

Или я что-то неправильно понимаю, и в случае HTTP 1.0 обращение к IntenetReadFile всегда будет одно? Или это Вы меня неправильно поняли? Под чанками я подразумевал не куски данных, передаваемые в разных пакетах, а куски данных, передаваемые в разных обращениях к функции чтения.

Дело в том, что этот вопрос для меня сейчас действительно критический. Чтобы корректно выполнить замены в содержимом, мне требуется иметь цельный образ страницы, для чего я в первом обращении к InternetReadFile выполняю несколько вызовов к оригинальной функции, пока вся страница не прочитается, делаю подмену и затем в каждом вызове моей InternetReadFile со стороны IE возвращаю очередной кусок данных. По непонятным мне причинам, IE на этом виснет:( Код, действительно, не самый простой, я где-то мог и намудрить. Если бы было всего одно чтение, этой проблемы бы не было.
 
Загрузку страницы в один запрос вы все равно не получите. Видимо прийдется использовать какие то глобальные массивы буфферов чтобы хранить промежуточные данные и общим скопом потом их выдавать. Что касается протокола - я озвучил решение одной из насущьных проблем более актуальной пожалуй для сниффера чем для подмены контента. Этот метод позволяет избежать зипания (через спец заголовок добавляемый к запросу) и собственно технологии chunked пакетов. В чем прикол? Еще и в том, что контент страницы (или любого другого файла) будет передаваться в одной сессии сокета и она гарантированно не порвется. Пердача чанков же не обязательно проходит в одной сессии.
Когда файл полностью передается по HTTP 1.0 то сессия рвется. Это позволяет удобнее синхронизировать потоки выкачивания, чтобы чанки не перепутались ненароком в случае использования HTTP 1.1.

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

А вообще, молодой человек, имело бы смысл почтитать спецификацию на протокол HTTP, сразу бы отпала куча вопросов, жаль что только на буржуйском я видал ее..
 
перед тем как вызвать InternetReadFile осел узнает сколько байт доступно InternetQueryDataAvailable
причем каждая из этих апи может вернуть ошибку ERROR_IO_PENDING (читай про асинхронные запросы)
после которой обращаться к этому сокету можно только после того как это разрешит InternetStatusCallback которую осел устанавливает с помощью InternetSetStatusCallback


Еще и в том, что контент страницы (или любого другого файла) будет передаваться в одной сессии сокета и она гарантированно не порвется. Пердача чанков же не обязательно проходит в одной сессии.
Когда файл полностью передается по HTTP 1.0 то сессия рвется. Это позволяет удобнее синхронизировать потоки выкачивания, чтобы чанки не перепутались ненароком в случае использования HTTP 1.1.
чтоб точно сопоставить чанки нужно их идентифицировать по параметру
__in HINTERNET hFile


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


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


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

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

на этом этапе можно сделать инжект

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

удачи
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх