Исследователи показывают, как спрятать слона в муравейнике.
Специалисты Trustedsec опубликовали исследование Hiding in Plain Sight, которое предлагает новый и необычный бесфайловый метод скрытия данных с использованием структуры папок.
Традиционно антивирусное ПО и DLP-решения (Data Loss Prevention) фокусируются на файлах, где и хранится информация. Однако новое открытие исследователей ставит под сомнение привычную парадигму. Специалисты предложили использовать папки как контейнеры для хранения данных. Папки сами по себе не содержат данных, но их имена могут использоваться для кодирования информации.
Идея состоит в создании иерархической структуры папок (одна внутри другой), где каждая папка имеет уникальное имя, представляющее часть данных. Например, структура «папка1\папка2\папка3\папка4» может быть использована для кодирования строки данных. Если удалить разделители папок, получится непрерывная строка, содержащая информацию – «папка1папка2папка3папка4».
Для предотвращения использования специальных символов, которые могут вызвать подозрения, исследователи предлагают использовать GUID (Globally Unique Identifier) – стандартный формат идентификаторов, часто используемых в системах. GUID представляет собой строку из 32 символов, разделенных дефисами. Символы в такой записи случайны и не вызывают подозрений.
Для подтверждения концепции мы будем использовать небольшой фрагмент текста:
Пока мы используем текстовую строку для тестирования, легко заменить источник ввода на целевой файл. PowerShell легко читает из файла с помощью Get-Content. Сначала мы берем наши входные данные и преобразуем их в поток байтов. В этом случае мы можем преобразовать строку следующим образом:
$data_bytes = [System.Text.Encoding]::UTF8.GetBytes($example_data)
Затем поток байтов преобразуется в шестнадцатеричный:
$hexString = ($data_bytes | ForEach-Object { $_.ToString(“X2”) }) -join ‘’
Данные, преобразованные в шестнадцатеричную систему счисления
Теперь преобразуем нашу шестнадцатеричную строку в ряд путей, состоящих из папок с GUID в качестве имен, и создаем эти пути.
# Split the string into chunks
$chunks = [regex]::Matches($paddedString, ".{1,$chunkSize}") | ForEach-Object { $_.Value }
$i = 0
# Process each chunk
foreach ($chunk in $chunks) {
$prefix = $hexArray[$i]
# Prepend the prefix
$chunkWithPrefix = $prefix + $chunk
# Split the chunk into 32-char segments and format as GUIDs
$guids = [regex]::Matches($chunkWithPrefix, ".{1,32}") | ForEach-Object {
$segment = $_.Value
$formattedGuid = ($segment -replace '(.{8})(.{4})(.{4})(.{4})(.{12})', '$1-$2-$3-$4-$5')
[guid]$formattedGuid
}
# array to hold our folders before we create them
$tmp_path_array = @()
# Process our GUIDs
$guids | ForEach-Object {
#Write-Output $_
$tmp_path_array+="$_"
}
#echo "Making directories:"
$fifthline = "{0}\{1}\{2}\{3}\{4}" -f $tmp_path_array[0], $tmp_path_array[1], $tmp_path_array[2], $tmp_path_array[3], $tmp_path_array[4]
echo $fifthline
#this -p option creates any required parent folders
mkdir -p "$fifthline" | out-null
$i++
}
Ниже мы можем увидеть вывод кодировки. Это наш файл, закодированный в пути к папкам. Каждая строка представляет собой иерархию папок, содержащих часть нашей общей закодированной строки.
Вывод расширенных путей к папкам
У нас есть 44 папки на верхнем уровне. Первые шесть символов каждой строки — это рандомизированный 6-символьный шестнадцатеричный код, который был отсортирован в алфавитном порядке и добавлен к каждой строке. Это позволяет сортировать по имени и размещать каждую строку в том порядке, в котором она должна располагаться, при этом выглядя случайным образом.
Создание папок со значениями индекса
Существует несколько ограничений, связанных с этим методом. Во-первых, в Windows существует ограничение на длину пути в 260 символов. Это значит, что имена папок должны быть достаточно короткими, чтобы избежать превышения лимита.
Во-вторых, использование чистого шестнадцатеричного кодирования может выглядеть подозрительно. Поэтому было решено сохранять имена папок в формате GUID, что делает их менее заметными.
Пример структуры дерева папок
Наша базовая папка занимает ноль байт на диске. Обратите внимание на количество – 220 папок.
Свойства папки
Для декодирования мы смотрим на папки верхнего уровня в нашем целевом каталоге. Затем, в отсортированном порядке, мы погружаемся в каждую папку верхнего уровня, извлекая весь путь структуры папок. Шестнадцатеричное число добавляется к строковой переменной «hex stream».
После того, как все пути к папкам верхнего уровня считаны, поток hex преобразуется в байты и может быть отображен на экране или записан в файл.
$a = Get-Location
$b = ""
foreach ($f in (gci -Path $a -ad)) {
$c = (gci -Path $f.FullName -ad -r | sort { $_.FullName.Split('\').Count } -d)[0]
$d = ($c.Fullname.Split("\")[$a.Path.split('\').Count..($c.Fullname.Split("\").Length - 1)] -join '\')
$b += $d.Substring(6).replace("-","").replace("\","")
}
$e = [regex]::Matches($b, '..') | % { [Convert]::ToByte($_.Value, 16) }
$g = "$($a.Path)\decoded_output.txt"
sc -Path $g -Value $e -Encoding Byte
Декодированные данные. Внизу выведен расшифрованный текст
Этот метод имеет несколько потенциальных применений:
Однако, несмотря на свою креативность, метод имеет свои недостатки. Кодирование данных в структуре папок увеличивает общий размер данных при архивировании. Обычный текстовый файл может значительно вырасти в размере, увеличиваясь с 1 071 КБ до 21 688 КБ при использовании структуры папок.
Сравнение размеров
Идея использования папок для скрытия данных представляет собой интересный подход к проблеме защиты информации. Такой способ демонстрирует, что методы сокрытия данных ограничены только воображением исследователей. Однако реальная полезность метода в повседневной жизни вызывает сомнения, поскольку основная проблема заключается в обходе детектирования средств защиты, а не в самом скрытии данных. Проект, демонстрирующий метод, доступен на GitHub.
5778 К? Пф! У нас градус знаний зашкаливает!