Вы, вероятно, знакомы с ситуацией, когда во время Пентеста вы сталкиваетесь с событием, где можно было получить начальную точку опоры, однако нет очевидных путей для эскалации/движения оттуда.
В таких ситуациях единственный возможный выход — просмотреть файловую систему компьютера и все доступные общие ресурсы, такие как общий ресурс SYSVOL контроллера домена или общие диски компании. Эти места часто содержат сценарии, журналы, документы и файлы, в которых также часто хранится конфиденциальная информация, такая как учетные данные и токены. Однако просмотр каталогов вручную занимает много времени, и можно легко что-то упустить.
В этом посте я расскажу о нескольких существующих методах эффективной работы со списками каталогов и поиска интересных файлов. Кроме того, я выпускаю инструмент .NET под названием Dir2json, чтобы расширить эти методы в дружественной к OPSEC форме.
Поиск в структуре каталогов
Помимо ручного просмотра структуры каталогов, существуют различные способы более простого поиска потенциально интересных файлов, которые впоследствии можно собрать вручную. В приведенных ниже примерах на диске C рекурсивно выполняется поиск файлов с расширением .kdb и .kdbx(база данных паролей KeePass), а также файлов, которые содержат строку password в имени файла. Эту строку поиска можно расширить, включив в нее множество шаблонов для идентификации потенциально интересных файлов. Более того, в примерах выводится только полный путь, но могут быть показаны и другие атрибуты, такие как размер файла и дата последнего изменения.
Командная строка (cmd.exe)
Используйте команду dir для поиска одного или нескольких шаблонов для идентификации файлов на диске. Вывод также можно перенаправить в файл, добавив > file.txt. Дополнительные примеры поиска с использованием dir можно найти в скрипте localrecon.cmd на GitHub BITSADMIN, скрипте, который я создал, когда работал над лабораторией OSCP.
PowerShell
Используйте Get-ChildItem командлет для поиска файлов, в которых параметр -Force гарантирует, что будут включены также скрытые и системные файлы. Исключения несанкционированного доступа можно скрыть, добавив -ErrorAction SilentlyContinue(сокращенно: -ea 0) к параметрам командлета Get-ChildItem. Вывод можно перенаправить в файл, передав его в Out-File file.txt.
Инструментарий управления Windows ( WMI )
В этом примере PowerShell используется для выполнения запросов WMI, но такой запрос может выполнять любой язык, способный взаимодействовать с WMI. Преимущество WMI заключается в том, что с помощью параметров -ComputerName или -CimSession такие запросы также можно выполнять к удаленным машинам, для которых доступен только порт 135/TCP (RPC) (или 5985/TCP/5986/TCP при использовании через WinRM), то есть порт 445/ TCP (Microsoft-DS) не требуется для перечисления. Однако необходимы административные привилегии на удаленном компьютере. Дополнительную информацию об удаленном взаимодействии с WMI можно найти в этой записи блога (https://blog.bitsadmin.com/extracting-credentials-from-remote-windows-system). Для поиска в определенной папке Path Like 'C:\\Users\\%'в запрос можно добавить условие. Более того, помимо CIM_LogicalFileclass также можно использовать класс CIM_DataFile.
Объектная модель компонента ( COM )
Этот параметр напрямую невозможен для быстрого перечисления файловой системы, однако, если его превратить в код, рекурсивно повторяющий структуру каталогов, его также можно использовать. Для полноты здесь добавлен фрагмент PowerShell для поиска в файловой системе с использованием COM, но, как и в случае с WMI , для перечисления файловой системы можно использовать любой язык, способный взаимодействовать с COM .
Итог и ограничения
Помимо использования различных интерфейсов, предлагаемых Windows для запроса файловой системы, другим вариантом является прямой доступ к главной таблице файлов NTFS (MFT). В этом блоге этот вариант не рассматривается, поскольку предполагается, что он находится в контексте с низкими привилегиями.
Хотя все вышеупомянутые подходы работают для идентификации файлов в файловой системе, они имеют различные ограничения:
- Всякий раз, когда вы хотите выполнить другой поисковый запрос, необходимо снова выполнить итерацию всей файловой системы;
- Если по результатам вы хотите вывести список остальных файлов в каталоге соответствующего файла, взаимодействие с целевой (файловой) системой потребуется снова.
В следующем разделе обсуждается альтернативный подход к поиску в структуре каталогов.
Построить дерево каталогов с помощью PowerShell.
Вместо поиска определенного шаблона в структуре каталогов другой вариант — создать (одноразовый) список файлов, который, помимо имени файла и пути, также содержит такую информацию, как размер файла, дату модификации и флаги режима. Впоследствии это дерево можно перетащить в систему злоумышленника и запросить его в автономном режиме различными способами. Никакого дальнейшего взаимодействия с целевой системой больше не потребуется до тех пор, пока не будет идентифицирован файл, который вы, как злоумышленник, захотите проанализировать дальше. Этот конкретный файл затем можно загрузить и оценить в автономном режиме. Поскольку в Windows могут возникнуть проблемы с длинными путями, в различные способы сбора были добавлены некоторые настройки, которые правильно обрабатывают длинные пути.
Windows PowerShell предустановлена во всех версиях Windows, начиная с Windows 7 SP1/2008 R2 SP1, и работает до версии 5.1. Помимо Windows PowerShell существует также PowerShell Core, который построен на платформе .NET Core и поэтому помимо Windows также работает под управлением операционных систем Linux и Mac и может быть получен по адресу https://aka.ms/pscore6 . Первой версией PowerShell Core является версия 6.0, и ее можно установить отдельно. Две редакции PowerShell в основном похожи, но имеют некоторые незначительные различия, приводящие к немного разным командным строкам для перечисления.
Windows PowerShell
Следующая командная строка создает список файлов диска C:\ и сохраняет его в Drive_C.csvь файле. Синтаксис пути DOS ( \\?\) используется во избежание проблем с длинными путями к файлам. Если необходимо создать список файлов общего сетевого ресурса, используйте \\?\UNC\MYSERVER\MyShare значение параметра -LiteralPath. Кроме того, обновите значение \\?\ \?\UNC в $_.FullName.Replace('\\?\',''). Если логика не встроена в сценарий, Windows PowerShell не поддерживает обход каталогов с символическими ссылками. Такие каталоги могут быть опасными, поскольку они могут ссылаться на себя и, следовательно, приводить к бесконечной рекурсии. В строке ниже максимальная глубина установлена на 25, чего в большинстве случаев должно быть достаточно для сбора всех соответствующих файлов и папок, однако при необходимости это число можно увеличить или заменить параметром, допускающим бесконечные рекурсии -Recurse.
Ядро PowerShell
Хотя однострочник Windows PowerShell также можно использовать в PowerShell Core, онлайн-лайнер PowerShell Core немного короче и выглядит немного чище. В отличие от Windows PowerShell, PowerShell Core по умолчанию не входит в символические ссылки каталогов. Это поведение можно изменить, добавив -FollowSymlink флаг в Get-ChildItem командлет. Более того, PowerShell Core также хорошо справляется с длинными путями, поэтому не нужно использовать синтаксис пути DOS. Как и в случае с Windows PowerShell, этот -Depth X параметр можно использовать вместо ограничения -Recurse глубины перечисления.
Во многих случаях Oneliners PowerShell будет достаточно для сбора деревьев файловой системы. Однако в некоторых случаях требуется скрытый подход, и выполнение PowerShell (или загрузка System.Management.dll) может вызвать срабатывание сигналов тревоги. В следующем разделе обсуждается недавно разработанный инструмент Dir2json , который позволяет осуществлять скрытый сбор данных.
Dir2json
Dir2json — это инструмент, который я написал, когда заметил необходимость в скрытом инструменте, который из памяти Cobalt Strike способен создавать список каталогов и, не касаясь диска, отправлять результаты обратно на сервер Cobalt Strike Team. Изначально я разработал версию инструмента на C++, чтобы практиковать знания, полученные на курсе «Системное программирование для Windows» Павла Иосифовича (@zodiacon). Этот инструмент работает хорошо, но потом я понял, что невозможно легко превратить его в объектный файл маяка (BOF). По этой причине вместо того, чтобы исправлять инструмент C++, чтобы он работал как BOF, я переписал инструмент Dir2json на C#, который позволяет выполнять выполнение в памяти и загружать файлы благодаря проекту BOF.NET Кери Коберн (@EthicalChaos ). Кроме того, проект также можно скомпилировать и выполнить как обычный исполняемый файл .NET. Версия Dir2json для C# доступна по адресу https://github.com/bitsadmin/dir2json/. На видео ниже показано, как выполнить инструмент из Cobalt Strike.
Выполнение в памяти
Поскольку инструмент работает в памяти а не (в отличие от Oneliners PowerShell) непосредственно сбрасывает идентифицированные файлы и папки на диск, ему сначала необходимо сохранить полный список каталогов в памяти, прежде чем отправлять его обратно на сервер Cobalt Strike Team. По этой причине вместо хранения полных путей к идентифицированным элементам он создает древовидную структуру, в которой подпапки и файлы связаны с его родительской папкой. Когда запускается загрузка дерева, дерево сериализуется в JSON, сжимается gzip, а затем отправляется обратно на сервер Cobalt Strike Team. Поскольку инструмент Dir2json может выполняться на компьютерах с нехваткой памяти или на дисках или общих папках, содержащих миллионы файлов, он также предоставляет возможность ( /EntriesPerFile=X) очищать память каждый раз X тысяч собранных элементов и загрузить частичные результаты на Team Server. Наконец, Dir2json можно поручить следовать символическим ссылкам, используя параметр /FollowSymlinks, который можно использовать в сочетании с параметром /MaxDepth=Y, чтобы ограничить рекурсию максимальным количеством Y каталогов, избегая при этом возможных бесконечных рекурсий.
JSON в CSV
Поскольку поиск в формате JSON не очень прост, репозиторий Dir2json содержит сценарий Json2csv.ps1 PowerShell, который принимает файл .json( .gz) в качестве входных данных, при необходимости распаковывает их, а затем сохраняет выходные данные в .csv выходной файл. Если в качестве входных данных предоставляется первый файл разделенного файла Dir2json, инструмент также немедленно объединяет их обратно в один .csv выходной файл. Поскольку сценарий также можно выполнить с помощью PowerShell Core, он также совместим с операционными системами, отличными от Windows.
Статистика
Чтобы лучше понять использование различных инструментов, приведем некоторую статистику выполнения. Тесты проводились на моем ноутбуке с твердотельным накопителем, который содержит в общей сложности 1,2 миллиона записей о файлах и папках.
В обеих версиях PowerShell перечисление занимает от 2,5 до 3,5 минут, тогда как перечисление Dir2json занимает всего 20 секунд. Что касается Windows PowerShell и PowerShell Core, можно было бы ожидать, что они дадут абсолютно одинаковые результаты, однако, поскольку однострочный файл Windows PowerShell не избегает символических ссылок, в Windows PowerShell папки внутри каталогов с символическими ссылками перечислены, тогда как в PowerShell Core эти каталоги избегаются. Например, это происходит с C:\Users\All Users каталогом, который является символической ссылкой на C:\ProgramDat a то место, где в случае Windows PowerShell эти файлы перечислены дважды в результирующем файле .csv.
Как упоминалось ранее, для преобразования .json.gz файла в файл .csvс помощью сценария Json2csv.ps1 можно использовать Windows PowerShell или PowerShell Core. В таблице ниже показано, что, хотя PowerShell Core использует в 1,5 раза больше памяти, он преобразует файл в 5 раз быстрее по сравнению с Windows Powershell. После .json.gz преобразования файла .csv будет содержать точно такие же данные, как и данные, созданные с помощью Oneliner PowerShell Core.
В следующих разделах качестве входных данных будет использоваться файл .csv , созданный с помощью инструмента PowerShell или Dir2json + Json2csv, и обсуждаются различные способы, которыми PowerShell может импортировать данные и запрашивать их для поиска интересных файлов.
Импорт csv в PowerShell
Существуют различные способы запроса данных в .csv файле: от использования grep и awk в Linux до анализа данных с помощью Python. В этом разделе будут обсуждаться мощные функциональные возможности PowerShell для работы со структурированными данными. Несмотря на то, что в этой статье использование .csv команд Linux не обсуждается, примеры выполнения эквивалентных запросов доступны в репозитории Dir2json в файле CheatSheet.sh.
PowerShell имеет встроенную поддержку импорта .csv файлов с помощью Import-Csv командлета. Во время импорта также можно различными способами дополнять импортированные данные, что за счет увеличения времени загрузки и использования памяти значительно улучшает запрос к набору данных после его загрузки. В следующих параграфах обсуждаются преимущества различных методов импорта, каждый из которых основывается на предыдущем, добавляя дополнительные атрибуты.
D0: обычный CSV-файл.
Простой импорт, безусловно, самый быстрый и позволяет выполнять поиск по подстановочным знакам в FullPath атрибуте. Однако ему не хватает возможности выполнять интеллектуальные запросы.
D1: Атрибут длины как целое число.
При использовании Import-Csv командлета PowerShell просто рассматривает все значения столбцов как строки. Это означает, что при сортировке и фильтрации, например, по размерам файлов, цифры будут сортироваться в алфавитном порядке, а не в ожидаемом порядке (например, 1, 10, 2, 3 вместо 1, 2, 3, 10). Принудительное преобразование строки в 64-битное целое число увеличит время импорта и использование памяти, однако приведет к повышению качества используемого набора данных.
D2: Атрибут расширения
Поскольку по расширению файла можно легко быстро идентифицировать интересные файлы, это еще один полезный атрибут, который нужно подготовить. Платформа .NET, доступ к которой можно получить из PowerShell, имеет встроенные функции для получения расширения на основе имени файла с использованием статического метода GetExtension в пространстве имен System.IO.Path. Поскольку функция не имеет никаких других входных данных, кроме строки имени, а каталог, содержащий точку, также можно спутать с файлом с расширением, однострочник D2 содержит проверку, чтобы убедиться, что элемент не является каталогом.
D3: Атрибут глубины
Поскольку в .csv иерархическая структура уплощена, становится сложнее составить список файлов в определенном каталоге, который, в свою очередь, также имеет подкаталоги. Чтобы иметь возможность перечислять файлы и папки в определенной папке, не перечисляя при этом подпапки, Depth можно использовать атрибут. В однострочном файле импорта (D3FullName атрибут), содержащий полный путь и имя файла или каталога, разделяется символом-разделителем каталогов (обратная косая черта - \), а количество каталогов подсчитывается для определения глубины.
D4: Атрибуты режима
Последний вариант — также преобразовать строковый атрибут режима в несколько логических значений, чтобы иметь возможность фильтровать и эти атрибуты. На практике при поиске интересных файлов для идентификации учетных данных атрибут Mode менее актуален, и время импорта значительно больше в 1,7 раза по сравнению с D3 , а использование памяти также увеличивается на 60%, поэтому в целом импорт с использованием D3 обеспечивает достаточные атрибуты. Более того, атрибут режима по-прежнему можно фильтровать, несмотря на то, что он является строкой.
Статистика в таблице ниже была получена с использованием PowerShell Core при импорте .csv файла с 1,2 миллионами записей, созданного ранее.
Запрос с помощью PowerShell
После импорта списка каталогов он доступен в $csv переменной. PowerShell поддерживает множество функций фильтрации, сортировки, группировки и манипулирования данными, которые мы можем использовать, чтобы быстро получить хорошее представление о файловой системе или общем ресурсе, который был перечислен. В этом разделе для большинства запросов требуется, чтобы данные были импортированы с использованием однострочного интерфейса D3 (или даже более расширенного D4 ).
Чтобы иметь возможность систематически оценивать выходные данные, команду также можно передать по конвейеру Out-Host -Paging (сокращение: oh -p) или сохранить в .csv файле, передав ее командлету Export-Csv). Дополнительную информацию об использовании этого Export-Csv командлета можно найти в разделе «Инструменты запросов Cypher» статьи блога «Работа с большими наборами данных BloodHound» .
Статистика
Некоторые цифры, чтобы дать представление о том, насколько велик набор данных.
Как упоминалось ранее, расширения файлов могут быть очень полезны для идентификации потенциально интересных файлов.
PS C:\> $exts = $csv | Group-Object Extension -NoElement | Sort-Object -Descending Count,Name
PS C:\> $exts | Format-Table Name,Count | Out-Host -Paging
Name Count
---- -----
189583
.dll 94405
.manifest 82083
.mui 50736
.cat 46573
.mum 43343
.js 22687
.png 16834
.pyc 15442
.xml 12666
.exe 12101
.py 10394
.rtf 9705
.go 8900
<SPACE> next page; <CR> next line; Q quit
Расширения файлов администратора
Некоторые расширения особенно интересны для изучения, если цель состоит в том, чтобы найти конфиденциальную информацию для использования эскалации или бокового перемещения. Чтобы получить представление о том, какие расширения, относящиеся к администраторам, присутствуют в системе, можно использовать следующие две строки.
В случае общих расширений администратора пути необходимо оценить и дополнительно отфильтровать, чтобы добраться до файлов, которые кажутся релевантными. Примеры таких запросов.
Расширения файлов Office
Как и расширения администратора, расширения Office также могут быть интересны, если вы ищете конкретную информацию, хранящуюся в документах и текстовых файлах.
Дополнительные интересные расширения файлов администратора и офиса можно найти по адресу https://filesec.io/ . После сохранения списка путей к файлам и подробностей можно систематически работать со списком и загружать потенциально интересные файлы для дальнейшего анализа.
Просмотр папок
Поскольку в нашем распоряжении есть полный список каталогов, а во время импорта атрибут Depth был рассчитан, также можно составить список каталогов, чтобы лучше понять структуру каталогов и размеры папок.
Будущая работа
Поскольку .csv структура данных не оптимизирована для такого просмотра файловой системы, я начал работать над поставщиком PowerShell , который позволял бы загружать .json собранные данные с помощью Dir2json и предоставлять диск (например d2j:\C\Users\) для просмотра, рекурсии ( Get-ChildItem -Recurse) и фильтрации файловой системы с использованием встроенного PowerShell функционирует через иерархическую структуру. Однако создание такого поставщика заняло больше времени, чем я ожидал, поэтому я делюсь с вами этой идеей на случай, если вы захотите попрактиковаться в написании кода на C# и узнать о внутреннем устройстве PowerShell.
Еще одной интересной задачей программирования могла бы стать реализация перечисления сред SharePoint. Это было бы актуально, поскольку в настоящее время, помимо дисков файловой системы и общих сетевых ресурсов, все больший объем информации хранится в средах SharePoint. Классы и функции из Microsoft.SharePoint.Client пространства имен кажутся хорошим началом реализации этой функциональности в C#.
Заключение
Вместо поиска конкретных файлов гораздо более эффективный метод — выполнить одноразовый сбор списка каталогов, а затем запросить файл в автономном режиме через PowerShell на наличие интересных файлов. Для выполнения сбора можно использовать либо однострочник PowerShell, либо инструмент Dir2json, который позволяет выполнять выполнение в памяти через BOF.NET в Cobalt Strike.
Анализ полученного CSV-файла, содержащего структуру каталогов, можно эффективно выполнить с помощью функций фильтрации, группировки и сортировки PowerShell, а любые обнаруженные интересные файлы можно загрузить и изучить. Запросы PowerShell, рассмотренные выше, а также различные другие запросы можно найти в файле CheatSheet.ps1 в репозитории Dir2json GitHub.
Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://blog.bitsadmin.com/digging-for-secrets
В таких ситуациях единственный возможный выход — просмотреть файловую систему компьютера и все доступные общие ресурсы, такие как общий ресурс SYSVOL контроллера домена или общие диски компании. Эти места часто содержат сценарии, журналы, документы и файлы, в которых также часто хранится конфиденциальная информация, такая как учетные данные и токены. Однако просмотр каталогов вручную занимает много времени, и можно легко что-то упустить.
В этом посте я расскажу о нескольких существующих методах эффективной работы со списками каталогов и поиска интересных файлов. Кроме того, я выпускаю инструмент .NET под названием Dir2json, чтобы расширить эти методы в дружественной к OPSEC форме.
Поиск в структуре каталогов
Помимо ручного просмотра структуры каталогов, существуют различные способы более простого поиска потенциально интересных файлов, которые впоследствии можно собрать вручную. В приведенных ниже примерах на диске C рекурсивно выполняется поиск файлов с расширением .kdb и .kdbx(база данных паролей KeePass), а также файлов, которые содержат строку password в имени файла. Эту строку поиска можно расширить, включив в нее множество шаблонов для идентификации потенциально интересных файлов. Более того, в примерах выводится только полный путь, но могут быть показаны и другие атрибуты, такие как размер файла и дата последнего изменения.
Командная строка (cmd.exe)
Используйте команду dir для поиска одного или нескольких шаблонов для идентификации файлов на диске. Вывод также можно перенаправить в файл, добавив > file.txt. Дополнительные примеры поиска с использованием dir можно найти в скрипте localrecon.cmd на GitHub BITSADMIN, скрипте, который я создал, когда работал над лабораторией OSCP.
PowerShell
Используйте Get-ChildItem командлет для поиска файлов, в которых параметр -Force гарантирует, что будут включены также скрытые и системные файлы. Исключения несанкционированного доступа можно скрыть, добавив -ErrorAction SilentlyContinue(сокращенно: -ea 0) к параметрам командлета Get-ChildItem. Вывод можно перенаправить в файл, передав его в Out-File file.txt.
Инструментарий управления Windows ( WMI )
В этом примере PowerShell используется для выполнения запросов WMI, но такой запрос может выполнять любой язык, способный взаимодействовать с WMI. Преимущество WMI заключается в том, что с помощью параметров -ComputerName или -CimSession такие запросы также можно выполнять к удаленным машинам, для которых доступен только порт 135/TCP (RPC) (или 5985/TCP/5986/TCP при использовании через WinRM), то есть порт 445/ TCP (Microsoft-DS) не требуется для перечисления. Однако необходимы административные привилегии на удаленном компьютере. Дополнительную информацию об удаленном взаимодействии с WMI можно найти в этой записи блога (https://blog.bitsadmin.com/extracting-credentials-from-remote-windows-system). Для поиска в определенной папке Path Like 'C:\\Users\\%'в запрос можно добавить условие. Более того, помимо CIM_LogicalFileclass также можно использовать класс CIM_DataFile.
Объектная модель компонента ( COM )
Этот параметр напрямую невозможен для быстрого перечисления файловой системы, однако, если его превратить в код, рекурсивно повторяющий структуру каталогов, его также можно использовать. Для полноты здесь добавлен фрагмент PowerShell для поиска в файловой системе с использованием COM, но, как и в случае с WMI , для перечисления файловой системы можно использовать любой язык, способный взаимодействовать с COM .
Итог и ограничения
Помимо использования различных интерфейсов, предлагаемых Windows для запроса файловой системы, другим вариантом является прямой доступ к главной таблице файлов NTFS (MFT). В этом блоге этот вариант не рассматривается, поскольку предполагается, что он находится в контексте с низкими привилегиями.
Хотя все вышеупомянутые подходы работают для идентификации файлов в файловой системе, они имеют различные ограничения:
- Всякий раз, когда вы хотите выполнить другой поисковый запрос, необходимо снова выполнить итерацию всей файловой системы;
- Если по результатам вы хотите вывести список остальных файлов в каталоге соответствующего файла, взаимодействие с целевой (файловой) системой потребуется снова.
В следующем разделе обсуждается альтернативный подход к поиску в структуре каталогов.
Построить дерево каталогов с помощью PowerShell.
Вместо поиска определенного шаблона в структуре каталогов другой вариант — создать (одноразовый) список файлов, который, помимо имени файла и пути, также содержит такую информацию, как размер файла, дату модификации и флаги режима. Впоследствии это дерево можно перетащить в систему злоумышленника и запросить его в автономном режиме различными способами. Никакого дальнейшего взаимодействия с целевой системой больше не потребуется до тех пор, пока не будет идентифицирован файл, который вы, как злоумышленник, захотите проанализировать дальше. Этот конкретный файл затем можно загрузить и оценить в автономном режиме. Поскольку в Windows могут возникнуть проблемы с длинными путями, в различные способы сбора были добавлены некоторые настройки, которые правильно обрабатывают длинные пути.
Windows PowerShell предустановлена во всех версиях Windows, начиная с Windows 7 SP1/2008 R2 SP1, и работает до версии 5.1. Помимо Windows PowerShell существует также PowerShell Core, который построен на платформе .NET Core и поэтому помимо Windows также работает под управлением операционных систем Linux и Mac и может быть получен по адресу https://aka.ms/pscore6 . Первой версией PowerShell Core является версия 6.0, и ее можно установить отдельно. Две редакции PowerShell в основном похожи, но имеют некоторые незначительные различия, приводящие к немного разным командным строкам для перечисления.
Windows PowerShell
Следующая командная строка создает список файлов диска C:\ и сохраняет его в Drive_C.csvь файле. Синтаксис пути DOS ( \\?\) используется во избежание проблем с длинными путями к файлам. Если необходимо создать список файлов общего сетевого ресурса, используйте \\?\UNC\MYSERVER\MyShare значение параметра -LiteralPath. Кроме того, обновите значение \\?\ \?\UNC в $_.FullName.Replace('\\?\',''). Если логика не встроена в сценарий, Windows PowerShell не поддерживает обход каталогов с символическими ссылками. Такие каталоги могут быть опасными, поскольку они могут ссылаться на себя и, следовательно, приводить к бесконечной рекурсии. В строке ниже максимальная глубина установлена на 25, чего в большинстве случаев должно быть достаточно для сбора всех соответствующих файлов и папок, однако при необходимости это число можно увеличить или заменить параметром, допускающим бесконечные рекурсии -Recurse.
Ядро PowerShell
Хотя однострочник Windows PowerShell также можно использовать в PowerShell Core, онлайн-лайнер PowerShell Core немного короче и выглядит немного чище. В отличие от Windows PowerShell, PowerShell Core по умолчанию не входит в символические ссылки каталогов. Это поведение можно изменить, добавив -FollowSymlink флаг в Get-ChildItem командлет. Более того, PowerShell Core также хорошо справляется с длинными путями, поэтому не нужно использовать синтаксис пути DOS. Как и в случае с Windows PowerShell, этот -Depth X параметр можно использовать вместо ограничения -Recurse глубины перечисления.
Во многих случаях Oneliners PowerShell будет достаточно для сбора деревьев файловой системы. Однако в некоторых случаях требуется скрытый подход, и выполнение PowerShell (или загрузка System.Management.dll) может вызвать срабатывание сигналов тревоги. В следующем разделе обсуждается недавно разработанный инструмент Dir2json , который позволяет осуществлять скрытый сбор данных.
Dir2json
Dir2json — это инструмент, который я написал, когда заметил необходимость в скрытом инструменте, который из памяти Cobalt Strike способен создавать список каталогов и, не касаясь диска, отправлять результаты обратно на сервер Cobalt Strike Team. Изначально я разработал версию инструмента на C++, чтобы практиковать знания, полученные на курсе «Системное программирование для Windows» Павла Иосифовича (@zodiacon). Этот инструмент работает хорошо, но потом я понял, что невозможно легко превратить его в объектный файл маяка (BOF). По этой причине вместо того, чтобы исправлять инструмент C++, чтобы он работал как BOF, я переписал инструмент Dir2json на C#, который позволяет выполнять выполнение в памяти и загружать файлы благодаря проекту BOF.NET Кери Коберн (@EthicalChaos ). Кроме того, проект также можно скомпилировать и выполнить как обычный исполняемый файл .NET. Версия Dir2json для C# доступна по адресу https://github.com/bitsadmin/dir2json/. На видео ниже показано, как выполнить инструмент из Cobalt Strike.
Выполнение в памяти
Поскольку инструмент работает в памяти а не (в отличие от Oneliners PowerShell) непосредственно сбрасывает идентифицированные файлы и папки на диск, ему сначала необходимо сохранить полный список каталогов в памяти, прежде чем отправлять его обратно на сервер Cobalt Strike Team. По этой причине вместо хранения полных путей к идентифицированным элементам он создает древовидную структуру, в которой подпапки и файлы связаны с его родительской папкой. Когда запускается загрузка дерева, дерево сериализуется в JSON, сжимается gzip, а затем отправляется обратно на сервер Cobalt Strike Team. Поскольку инструмент Dir2json может выполняться на компьютерах с нехваткой памяти или на дисках или общих папках, содержащих миллионы файлов, он также предоставляет возможность ( /EntriesPerFile=X) очищать память каждый раз X тысяч собранных элементов и загрузить частичные результаты на Team Server. Наконец, Dir2json можно поручить следовать символическим ссылкам, используя параметр /FollowSymlinks, который можно использовать в сочетании с параметром /MaxDepth=Y, чтобы ограничить рекурсию максимальным количеством Y каталогов, избегая при этом возможных бесконечных рекурсий.
JSON в CSV
Поскольку поиск в формате JSON не очень прост, репозиторий Dir2json содержит сценарий Json2csv.ps1 PowerShell, который принимает файл .json( .gz) в качестве входных данных, при необходимости распаковывает их, а затем сохраняет выходные данные в .csv выходной файл. Если в качестве входных данных предоставляется первый файл разделенного файла Dir2json, инструмент также немедленно объединяет их обратно в один .csv выходной файл. Поскольку сценарий также можно выполнить с помощью PowerShell Core, он также совместим с операционными системами, отличными от Windows.
Статистика
Чтобы лучше понять использование различных инструментов, приведем некоторую статистику выполнения. Тесты проводились на моем ноутбуке с твердотельным накопителем, который содержит в общей сложности 1,2 миллиона записей о файлах и папках.
В обеих версиях PowerShell перечисление занимает от 2,5 до 3,5 минут, тогда как перечисление Dir2json занимает всего 20 секунд. Что касается Windows PowerShell и PowerShell Core, можно было бы ожидать, что они дадут абсолютно одинаковые результаты, однако, поскольку однострочный файл Windows PowerShell не избегает символических ссылок, в Windows PowerShell папки внутри каталогов с символическими ссылками перечислены, тогда как в PowerShell Core эти каталоги избегаются. Например, это происходит с C:\Users\All Users каталогом, который является символической ссылкой на C:\ProgramDat a то место, где в случае Windows PowerShell эти файлы перечислены дважды в результирующем файле .csv.
Как упоминалось ранее, для преобразования .json.gz файла в файл .csvс помощью сценария Json2csv.ps1 можно использовать Windows PowerShell или PowerShell Core. В таблице ниже показано, что, хотя PowerShell Core использует в 1,5 раза больше памяти, он преобразует файл в 5 раз быстрее по сравнению с Windows Powershell. После .json.gz преобразования файла .csv будет содержать точно такие же данные, как и данные, созданные с помощью Oneliner PowerShell Core.
В следующих разделах качестве входных данных будет использоваться файл .csv , созданный с помощью инструмента PowerShell или Dir2json + Json2csv, и обсуждаются различные способы, которыми PowerShell может импортировать данные и запрашивать их для поиска интересных файлов.
Импорт csv в PowerShell
Существуют различные способы запроса данных в .csv файле: от использования grep и awk в Linux до анализа данных с помощью Python. В этом разделе будут обсуждаться мощные функциональные возможности PowerShell для работы со структурированными данными. Несмотря на то, что в этой статье использование .csv команд Linux не обсуждается, примеры выполнения эквивалентных запросов доступны в репозитории Dir2json в файле CheatSheet.sh.
PowerShell имеет встроенную поддержку импорта .csv файлов с помощью Import-Csv командлета. Во время импорта также можно различными способами дополнять импортированные данные, что за счет увеличения времени загрузки и использования памяти значительно улучшает запрос к набору данных после его загрузки. В следующих параграфах обсуждаются преимущества различных методов импорта, каждый из которых основывается на предыдущем, добавляя дополнительные атрибуты.
D0: обычный CSV-файл.
Простой импорт, безусловно, самый быстрый и позволяет выполнять поиск по подстановочным знакам в FullPath атрибуте. Однако ему не хватает возможности выполнять интеллектуальные запросы.
D1: Атрибут длины как целое число.
При использовании Import-Csv командлета PowerShell просто рассматривает все значения столбцов как строки. Это означает, что при сортировке и фильтрации, например, по размерам файлов, цифры будут сортироваться в алфавитном порядке, а не в ожидаемом порядке (например, 1, 10, 2, 3 вместо 1, 2, 3, 10). Принудительное преобразование строки в 64-битное целое число увеличит время импорта и использование памяти, однако приведет к повышению качества используемого набора данных.
D2: Атрибут расширения
Поскольку по расширению файла можно легко быстро идентифицировать интересные файлы, это еще один полезный атрибут, который нужно подготовить. Платформа .NET, доступ к которой можно получить из PowerShell, имеет встроенные функции для получения расширения на основе имени файла с использованием статического метода GetExtension в пространстве имен System.IO.Path. Поскольку функция не имеет никаких других входных данных, кроме строки имени, а каталог, содержащий точку, также можно спутать с файлом с расширением, однострочник D2 содержит проверку, чтобы убедиться, что элемент не является каталогом.
D3: Атрибут глубины
Поскольку в .csv иерархическая структура уплощена, становится сложнее составить список файлов в определенном каталоге, который, в свою очередь, также имеет подкаталоги. Чтобы иметь возможность перечислять файлы и папки в определенной папке, не перечисляя при этом подпапки, Depth можно использовать атрибут. В однострочном файле импорта (D3FullName атрибут), содержащий полный путь и имя файла или каталога, разделяется символом-разделителем каталогов (обратная косая черта - \), а количество каталогов подсчитывается для определения глубины.
D4: Атрибуты режима
Последний вариант — также преобразовать строковый атрибут режима в несколько логических значений, чтобы иметь возможность фильтровать и эти атрибуты. На практике при поиске интересных файлов для идентификации учетных данных атрибут Mode менее актуален, и время импорта значительно больше в 1,7 раза по сравнению с D3 , а использование памяти также увеличивается на 60%, поэтому в целом импорт с использованием D3 обеспечивает достаточные атрибуты. Более того, атрибут режима по-прежнему можно фильтровать, несмотря на то, что он является строкой.
Статистика в таблице ниже была получена с использованием PowerShell Core при импорте .csv файла с 1,2 миллионами записей, созданного ранее.
| # | Функции | Команда | Время импорта | Использование памяти |
|---|---|---|---|---|
| Д0 | Обычный CSV-файл | $csv = Import-Csv Drive_C.csv | 10 с | 1,9 ГБ |
| Д1 | D0 + CSV с длиной, преобразованной в целое число | $csv = Import-Csv Drive_C.csv | Select-Object Name,@{n='Length';e={[int64]$_.Length}},Mode,LastWriteTime,FullName | 13:56 | 2,9 ГБ |
| Д2 | D1 + атрибут расширения | $csv = Import-Csv Drive_C.csv | Select-Object Name,@{n='Length';e={[int64]$_.Length}},Mode,LastWriteTime,FullName,@{n='Extension';e={if($_.Mode[0] -ne 'd'){[System.IO.Path]::GetExtension($_.Name)}else{''}}} | 14:23 | 3,5 ГБ |
| Д3 | D2 + атрибут глубины | $csv = Import-Csv Drive_C.csv | Select-Object Name,@{n='Length';e={[int64]$_.Length}},Mode,LastWriteTime,FullName,@{n='Extension';e={if($_.Mode[0] -ne 'd'){[System.IO.Path]::GetExtension($_.Name)}else{''}}},@{n='Depth';e={$_.FullName.Split('\').Count - 1}} | 02:49м | 3,8 ГБ |
| Д4 | D3 + атрибут режима, все преобразовано в отдельные атрибуты | $csv = Import-Csv Drive_C.csv | Select-Object Name,@{n='Length';e={[int64]$_.Length}},Mode,LastWriteTime,FullName,@{n='Extension';e={if($_.Mode[0] -ne 'd'){[System.IO.Path]::GetExtension($_.Name)}else{''}}},@{n='Depth';e={$_.FullName.Split('\').Count - 1}},@{n='Directory';e={$_.Mode[0] -eq 'd'}},@{n='Archive';e={$_.Mode[1] -eq 'a'}},@{n='ReadOnly';e={$_.Mode[2] -eq 'r'}},@{n='Hidden';e={$_.Mode[3] -eq 'h'}},@{n='System';e={$_.Mode[4] -eq 's'}},@{n='ReparsePoint';e={$_.Mode[5] -eq 'l' -or $_.Mode[0] -eq 'l'}} | 04:47 | 6,1 ГБ |
Запрос с помощью PowerShell
После импорта списка каталогов он доступен в $csv переменной. PowerShell поддерживает множество функций фильтрации, сортировки, группировки и манипулирования данными, которые мы можем использовать, чтобы быстро получить хорошее представление о файловой системе или общем ресурсе, который был перечислен. В этом разделе для большинства запросов требуется, чтобы данные были импортированы с использованием однострочного интерфейса D3 (или даже более расширенного D4 ).
Чтобы иметь возможность систематически оценивать выходные данные, команду также можно передать по конвейеру Out-Host -Paging (сокращение: oh -p) или сохранить в .csv файле, передав ее командлету Export-Csv). Дополнительную информацию об использовании этого Export-Csv командлета можно найти в разделе «Инструменты запросов Cypher» статьи блога «Работа с большими наборами данных BloodHound» .
Статистика
Некоторые цифры, чтобы дать представление о том, насколько велик набор данных.
| Запрос | Длинный | Короткий | Примечания |
|---|---|---|---|
| Общее количество записей | $csv | Measure-Object | Select-Object -ExpandProperty Count | $csv | Measure | % Count | %это псевдоним для ForEach-Object. В этом случае он перебирает выходные данные Measure-Object(которые представляют собой только одну запись) и отображает Countатрибут. |
| Количество файлов | $csv | Where-Object Mode -NotMatch 'd.....' | Measure-Object | Select-Object -ExpandProperty Count | $csv | ? Mode -NotMatch 'd.....' | Measure | % Count | ?это псевдоним для Where-Object. Если использовался метод импорта D4Where-Object , он также может выглядеть следующим образом: ? -not Directory. |
| Количество каталогов | $csv | Where-Object Mode -Match 'd.....' | Measure-Object | Select-Object -ExpandProperty Count | $csv | ? Mode -Match 'd.....' | Measure | % Count | Если использовался метод импорта D4Where-Object , он также может выглядеть следующим образом: ? Directory. |
Как упоминалось ранее, расширения файлов могут быть очень полезны для идентификации потенциально интересных файлов.
| Составьте список лучших расширений | $exts = $csv | Group-Object Extension -NoElement | Sort-Object -Descending Count,Name | $exts = $csv | group Extension -NoElement | sort -Desc Count,Name |
| Показать список 25 лучших расширений | $exts | Select-Object -First 25 | Format-Table Name,Count | $exts | select -First 25 | ft Name,Count |
PS C:\> $exts = $csv | Group-Object Extension -NoElement | Sort-Object -Descending Count,Name
PS C:\> $exts | Format-Table Name,Count | Out-Host -Paging
Name Count
---- -----
189583
.dll 94405
.manifest 82083
.mui 50736
.cat 46573
.mum 43343
.js 22687
.png 16834
.pyc 15442
.xml 12666
.exe 12101
.py 10394
.rtf 9705
.go 8900
<SPACE> next page; <CR> next line; Q quit
Расширения файлов администратора
Некоторые расширения особенно интересны для изучения, если цель состоит в том, чтобы найти конфиденциальную информацию для использования эскалации или бокового перемещения. Чтобы получить представление о том, какие расширения, относящиеся к администраторам, присутствуют в системе, можно использовать следующие две строки.
В случае общих расширений администратора пути необходимо оценить и дополнительно отфильтровать, чтобы добраться до файлов, которые кажутся релевантными. Примеры таких запросов.
| Список файлов администратора от самых последних до самых старых | $admin | Sort-Object -Descending LastWriteTime | Format-Table LastWriteTime,Length,FullName |
| Файлы с расширением .cmd, не находящиеся ни в Program Filesпапках, ни в Windowsкаталоге | $admin | Where-Object Extension -EQ '.cmd' | Where-Object FullName -NotMatch 'C:\\(Program Files|Windows).*' | Format-Table FullName,Length,LastWriteTime,Mode |
Расширения файлов Office
Как и расширения администратора, расширения Office также могут быть интересны, если вы ищете конкретную информацию, хранящуюся в документах и текстовых файлах.
| Сбор офисных документов и сопутствующих файлов | $office = $csv | Where-Object Extension -Match '^\.((doc|xls|ppt|pps|vsd)[xm]?|txt|csv|one|pst|url|lnk)$' |
| Сохраните все сведения о найденных файлах в формате CSV. | $office | Sort-Object FullName | Select-Object FullName,Length,LastWriteTime,Mode | Export-Csv -NoTypeInformation C:\Tmp\office_files.csv |
Дополнительные интересные расширения файлов администратора и офиса можно найти по адресу https://filesec.io/ . После сохранения списка путей к файлам и подробностей можно систематически работать со списком и загружать потенциально интересные файлы для дальнейшего анализа.
Просмотр папок
Поскольку в нашем распоряжении есть полный список каталогов, а во время импорта атрибут Depth был рассчитан, также можно составить список каталогов, чтобы лучше понять структуру каталогов и размеры папок.
Будущая работа
Поскольку .csv структура данных не оптимизирована для такого просмотра файловой системы, я начал работать над поставщиком PowerShell , который позволял бы загружать .json собранные данные с помощью Dir2json и предоставлять диск (например d2j:\C\Users\) для просмотра, рекурсии ( Get-ChildItem -Recurse) и фильтрации файловой системы с использованием встроенного PowerShell функционирует через иерархическую структуру. Однако создание такого поставщика заняло больше времени, чем я ожидал, поэтому я делюсь с вами этой идеей на случай, если вы захотите попрактиковаться в написании кода на C# и узнать о внутреннем устройстве PowerShell.
Еще одной интересной задачей программирования могла бы стать реализация перечисления сред SharePoint. Это было бы актуально, поскольку в настоящее время, помимо дисков файловой системы и общих сетевых ресурсов, все больший объем информации хранится в средах SharePoint. Классы и функции из Microsoft.SharePoint.Client пространства имен кажутся хорошим началом реализации этой функциональности в C#.
Заключение
Вместо поиска конкретных файлов гораздо более эффективный метод — выполнить одноразовый сбор списка каталогов, а затем запросить файл в автономном режиме через PowerShell на наличие интересных файлов. Для выполнения сбора можно использовать либо однострочник PowerShell, либо инструмент Dir2json, который позволяет выполнять выполнение в памяти через BOF.NET в Cobalt Strike.
Анализ полученного CSV-файла, содержащего структуру каталогов, можно эффективно выполнить с помощью функций фильтрации, группировки и сортировки PowerShell, а любые обнаруженные интересные файлы можно загрузить и изучить. Запросы PowerShell, рассмотренные выше, а также различные другие запросы можно найти в файле CheatSheet.ps1 в репозитории Dir2json GitHub.
Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://blog.bitsadmin.com/digging-for-secrets
Последнее редактирование: