Как написать кейлоггер на C#

Написать кейлоггер на C

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

Статья предназначена для профессиональных пентестеров и «белых хакеров». Ни автор статьи, ни редакция сайта spy-soft.net не несут ответственности за любой возможный вред, причиненный материалами данной статьи.

Создание кейлоггера на C#

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

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

Еще жертва может пользоваться парольным менеджером, тогда в логе мы получим только Ctrl-C и Ctrl-V. На этот случай будем мониторить еще и содержимое буфера обмена.

Подробнее об атаках на парольные менеджеры читайте в статье «Взлом KeePass».

Писать будем на C# в Visual Studio. Забегая вперед, скажу, что в результате у меня получилось две версии программы — одна работает через перехват WinAPI, другую я про себя называю «костыльной». Но эта менее красивая версия дает другие результаты при проверке антивирусами, поэтому расскажу и о ней.

Теория создания клавиатурного шпиона на C#

Когда вы нажимаете на кнопку, операционная система посылает уведомления тем приложениям, которые хотят об этом узнать. Поэтому самый простой метод перехватить нажатие на клавиатуре — это принимать сообщения о нажатиях клавиш. Если мы этого сделать не можем (например, функция SetWindowsHookEx запрещена антивирусом или еще чем-либо), можно тянуть сырой ввод и без нее. Есть такая функция — GetAsyncKeyState, которая принимает номер клавиши и позволяет узнать, зажата она или отжата в момент вызова. Собственно, алгоритм действий будет такой: раз в N мс опрашиваем все кнопки и узнаем их состояние, занося нажатые в специальный список. Затем список обрабатываем, учитывая состояние клавиши Caps Lock, Num Lock, Shift, Ctrl и так далее. Полученные данные будут записываться в файл.

Написание кейлоггера на C#

Для начала откроем Visual Studio и создадим новый проект Windows Forms (.NET Framework). Почему именно Windows Forms? Если мы выберем обычное консольное приложение, то при каждом запуске будет создаваться некрасивое черное окошко, а ведь пользователь не хочется беспокоить. Также, пока мы не создали форму (а создавать ее мы и не будем), никаких значков в таскбаре не появится — важная часть скрытой работы. Теперь удаляйте автоматически созданный файл Form1.cs со всеми потрохами и открывайте Program.cs.

Кейлоггер на C
Заглушка Main

Здесь нас уже поджидает шаблон программы, но он не будет работать просто так. Первым делом надо убрать строчки 10–12 и 16–18. Теперь меняем объявление метода со static void Main() на static void Main(String[] args). Нужно это для того, чтобы мы могли определить свои аргументы при перезапуске.

Еще по теме: Кейлоггер на Visual C++

Теперь добавим using System.IO; для работы с файлами, System.Runtime.InteropServices для работы с WinAPI и System.Threading для приостановки потока. Если вы не хотите писать костыльный вариант, лучше пропустите этот раздел и сразу переходите к следующему.

Импортируем GetAsyncKeyState из user32.dll:

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

Кейлоггер на C. Расшифровывать такой лог будет неудобно
Расшифровывать такой лог будет неудобно

Выглядит не очень красиво, а про читабельность вообще можно забыть. Во-первых, наш код тянет ввод не только с клавиатуры, но и с мыши (всякие LButton и RButton). Поэтому давайте не будем записывать нажатие, если это не символьная клавиша. Заменим содержимое if в цикле на это:

После такого редактирования лог стал намного чище (см. рисунок).

Кейлоггер на C. Выглядит уже аккуратнее
Кейлоггер на C. Выглядит уже аккуратнее

Так уже намного лучше! Теперь нужно добавить обработку кнопок Shift и Caps Lock. Добавим в начале цикла следующий код:

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

исходники кейлоггера c

Следующая проблема — это сообщения вида <Oemcomma>, <ShiftKey>, <Capital> и другие подобные. Они значительно усложняют чтение лога, так что придется это исправлять. Например, <Oemcomma> — это обычная человеческая запятая, а <Capital> — не что иное, как Caps Lock. Немного потестировав логгер на своем компьютере, я собрал достаточно материала, чтобы привести лог в порядок. Например, некоторые символы можно сразу заменить.

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

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

  • Num Lock;
  • функциональные клавиши;
  • Print Screen;
  • Page Up и Page Down;
  • Scroll Lock;
  • сочетание Shift + цифровая клавиша;
  • Tab;
  • Home и End;
  • Пуск;
  • Alt;
  • клавиши со стрелками.

Добавляем еще проверки и замены, и лог приобретает читабельный вид. В целом уже неплохо! Из недостатков: нет поддержки русской раскладки, что, впрочем, не так важно, если наша цель — получить пароли.

Смотрим, что скажет антивирус…

Реакция антивируса при принудительном сканировании
Реакция антивируса при принудительном сканировании
keylogger c#. Реакция при запуске (позже говорит, что все ок)
Реакция при запуске (позже говорит, что все ок)

Загружаем образец на VirusTotal, чтобы проверить на остальных. Результат: только 8 из 70 антивирусов что-то подозревают.

кейлоггер c#

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

Теперь попробуем сделать более правильно и будем перехватывать сообщения о нажатии клавиш на клавиатуре. Первые шаги те же: создаем проект Windows Forms и придумываем неприметное название (например, WindowsPrintService). В заглушке, которую нам создала Visual Studio, меняем void Main() на void Main(String[] args). Теперь сделаем простую проверку аргументов:

Дальше довольно много кода, не буду приводить его весь. Там есть флаги Caps Lock, Shift и прочее, а нажатия определяются гигантским Switch. Но показать я хочу не это, а установку хука на клавиатуру.

Кейлоггер на c#. Устанавливаем хук на клавиатуру
Устанавливаем хук на клавиатуру

Сначала мы помещаем ссылку на нашу функцию в переменную callback, потом получаем handle нашей программы, затем устанавливаем хук. А дальше вечно обрабатываем получаемые сообщения каждые 5 мс (PeekMessageA). Важный момент — объявление callback-функции, которая должна точно соответствовать WinAPI, а также передача управления нижележащим обработчикам (см. ниже).

А тут мы передаем управление дальше по цепочке хуков:

Кейлоггер на c#. Листинг callback-функции
Листинг callback-функции

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

как сделать кейлоггер
Switch, который разбирает Shift + цифровая клавиша

На этом скриншоте видна обработка нажатий цифровых клавиш с зажатым шифтом, а на следующем — ситуация с Caps Lock и Shift.

как сделать кейлоггер
Определяем регистр введенного символа

Клиппер для вытаскивания данных из буфера обмена

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

Создадим новую форму Windows, удалим файлы <ИмяФормы>.Designer.cs и <ИмяФормы>.resx. Теперь перейдем в режим редактирования, нажав F7, и приступим к написанию кода. Добавим using System.Runtime.InteropServices и импортируем WinAPI (на скриншоте — в отдельном классе).

Как написать кейлоггер. Класс, импортирующий методы WinAPI
Класс, импортирующий методы WinAPI

В конструктор формы вставляем следующий код:

Первый вызов сделает наше окно способным к восприятию системных сообщений, а второй назначит обработчик поступающих сообщений.

Eще по тем: Кейлоггер на Python

Теперь объявим переменную типа String и назовем ее lastWindow. Теперь мы переназначим стандартную функцию обработки сообщений (void WndProc(ref Message m)):

Для работы этого кода я взял уже готовый класс, который можно просто добавить в проект и не заморачиваться с созданием оберток вокруг WinAPI. Взять его можно на Pastebin.

Запустить клиппер несложно: добавляем ссылку на сборку System.Windows.Forms.dll, добавим using для System.Windows.Forms и System.Threading и добавим в метод запуска логгера следующие строки:

Просто? Вот именно. Только добавлять этот вызов нужно после назначения обработчика для Trace, иначе весь вывод улетит в неизвестные дали.

Сбор логов

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

Использование тоже весьма примитивное: достаточно создать объект нашего сервера, и он автоматически займет адреса localhost:34000 и <InternalIP>:34000 под HTTP и на этих же адресах порт 34001. Сервер будет возвращать список файлов и папок в виде списка или содержимое файла, если запрошен файл.

В конструктор нужно передать путь к папке, в которую пишутся логи (или любой другой, которая может понадобиться). По умолчанию логи пишутся в текущую папку, значит, в конструктор передаем Environment.CurrentDirectory.

Чтобы автоматизировать добавление нашей программы в белый список файрвола, вы можете воспользоваться Windows Firewall API. В этом вам помогут библиотеки-обертки FirewallManager, WindowsFirewallHelper и YFW.Net.

Автозапуск кейлоггера

Есть много способов попасть в автозагрузку: тут и папка «Автозагрузка», и куча мест в реестре, и установка своего драйвера, и создание службы… Однако реестр и драйверы отслеживаются любым приличным антивирусом, а создание службы слишком кривой вариант, который может сломаться в любой момент, хотя на крайний случай неплохо.

Мы же просто создадим задачу в планировщике заданий и попросим его запускать наш логгер с нужными параметрами при каждом входе юзера в систему. Для работы с планировщиком заданий берем пакет Microsoft.Win32.TaskScheduler из NuGet. Код для работы с ним я выложил на Pastebin. Не забудьте поправить путь, на который ссылается запись в планировщике.

Алгоритм действий логгера при запуске я показал на картинке.

Как написать кейлоггер. Алгоритм действий
Алгоритм действий

Реакция антивирусов на кейлоггер

Проверка более красивого варианта на VirusTotal показывает, что его обнаруживает большее число антивирусов, чем раньше, — 15 из 70. Однако среди оставшихся — почти все популярные у нас домашние антивирусы.

как написать кейлоггер

В общем, главное — не нарваться на «Авиру» или NOD32.

Проверка заголовка окна

Если наша предполагаемая жертва сразу после входа в систему пошла логиниться в ВК, то, считайте, вам повезло. Но что, если вместо этого она села играть в контру? Пароль придется вытаскивать из тонн символов W, A, S, D и пробелов, а с «костыльным» вариантом это еще сложнее. Поэтому давайте прокачаем наш логгер: будем записывать сигналы клавиатуры только тогда, когда активно окно браузера с формой входа. Для этого вернемся к WinAPI, а конкретно к функции GetForegroundWindow.

Написать кейлоггер на c. Импорт WinAPI
Импорт WinAPI

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

  1. Создадим функцию IsForegroundWindowsInteresting. Ее код будет таким:
  2. В самом начале нашей функции CallbackFunction вставляем

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

Поиск по логу

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

По понятным причинам логи мы будем анализировать на своей машине, так что сделаем отдельную программу. Чтобы использовать регулярки, добавим using System.Text.RegularExpressions и сделаем метод, который принимает на вход путь к файлу лога, а на консоль выводит все найденные телефонные номера.

Пароль будет идти следом за номером телефона.

Если пароль сохранен в браузере, то тут наш кейлоггер бессилен. Однако на сайте была статья, посвященная написанию стилера, так что переписываем то же самое на C# и радуемся.

Итого

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

Еще по теме: Клавиатурный шпион на Delphi

ВКонтакте
OK
Telegram
WhatsApp
Viber

4 комментария

  1. Гость

    И какого черта на вирустотал заливать? Через время, начнёт ваш кейлоггер палиться всеми антивирями.

  2. V

    Гость, ну вы о чём, а как проверить на 100%? А крипторы зачем? Нормальный вирь хоть заливай, хоть нет — вирь. Есть конечно платные сервисы, которые «не сливают» вирям, но редки.

  3. Дмитрий

    buf — переменная?

  4. Urij

    Там ошибочка в коде во время проверки кода клавиши условие такое:
    else if ((vKey >= 48 && vKey = 186 && vKey <= 192))
    но потом в swich'е проверяются клавиши с кодами 219-222, поэтому логгер их упускает.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *