В статье мы разработаем свой собственный Google, который можно будет запустить в любой локальной сети как атакующим, что ищут пароли, так и защитникам, которым небезразлична безопасность их родной локалки. И что примечательно, наш Google будет состоять на 99% из готовых компонентов, практически без дополнительного программирования. А внедрение такой системы потребует ввода всего пары команд.
Intro
На самых разных этапах продвижения по внутренней сети пентестер может столкнуться со сложностью, связанной с невозможностью быстрого анализа всех данных, хранящихся на общедоступных ресурсах. И каждый раз, когда он переходит на новый уровень доступа (initial access, доменный пользователь, доменный админ), объем этих файлов увеличивается экспоненциально.
Таким образом, потребность в системе поиска информации присутствует как на этапе развития атак, так и на постэксплуатации. В моей практике были ситуации, когда удавалось получить полные права к инфраструктуре, но отсутствие достаточных знаний о ней не позволяли идти дальше. Так что, даже если мы получили права доменного админа, мы всё ещё можем столкнуться со сложностями.
Большая сила открывает большие возможности. Но как обуздать эту силу? Как проанализировать сотни тысяч файлов на сотнях компьютеров? Ведь даже 1% хватило бы, чтобы найти тонну полезной информации. Вот если бы в локальной сети был Google...
1. Сетевые диски
Всякий раз при внутреннем пентесте можно столкнуться с некорректно настроенными сетевыми дисками. И справедливо это не только для сегментов Active Directory — автономные сетевые накопители также часто имеют некорректные настройки прав доступа.
Чувствительные данные на общедоступных ресурсах, пожалуй, самая большая проблема всех админов, и встречалась она мне даже во внутренних сетях очень крупных ИТ-компаний со зрелой ИБ. Там, среди обновленных серверов с безупречно защищенными конфигурациями, всё же присутствовали доступные сетевые диски, в глубине которых можно было отыскать секреты...
Что же касается рабочих станций, то ситуацию усугубляет политика, при которой каждый пользователь сам себе админ и может открыть доступ к явно излишней информации. Или «файлопомойки», доступ к которым имеет каждый сотрудник, и куда он может неаккуратно скопировать «чувствительные» файлы и сделать их доступными для всех.
При пентесте часто проверки сетевых дисков проводятся в ручном режиме, просто беглым просмотром наиболее интересных файлов и характерных каталогов (например, профили пользователей, корень "C:\" и другие диски).
В тоже время таких сетевых дисков может набраться несколько десятков и даже сотен. И ручная проверка может практически свестись на нет, что оставляет данный вектор слабо реализованным на практике.
1.1 SMB глазами хакера
Еще на самой ранней стадии продвижения по инфраструктуре, когда у атакующего нет ни одной учетки, он уже имеет шанс на обнаружение открытого сетевого диска через проверку анонимного доступа:
cme smb -d . -u 123 -p 123 --shares smb-hosts.txt
Для настройки прав иногда по ошибке используют встроенную группу Everyone — в неё входят абсолютно все пользователи, даже несуществующие. Тут важно понимать, что мы не угадываем пользователя, а наоборот, нам нужно его максимально не угадать, чтобы такого пользователя точно не было в системе и сработала группа Everyone.
Слабый пароль встроенных локальных учетных записей:
cme smb -u administrator -p <(head -n 10 rockyou.txt) --shares smb-hosts.txt
Так как локальные учетные записи часто не блокируются, а проверка доступа происходит достаточно быстро, то весьма целесообразно производить брутфорс.
Наконец, когда у нас есть доменная учетная запись, она откроет доступ уже к значительно большему числу сетевых дисков:
cme smb -d corp -u someuser -p somepass --shares smb-hosts.txt
Не редки ситуации, когда «Authenticated users» или «Domain users» включают по ошибке в группу локальные администраторы, делая возможным удаленное исполнение кода на данной машине любым доменным пользователем.
На различных этапах продвижения пентестеру будут открываться всё новые учетки, которые могут открыть новые уровни доступа к сетевым дискам через расширение присутствия методом pass-the-hash:
cme smb -u someuser -H :NT --shares smb-hosts.txt
Дальше, в зависимости от доступа, возможны три исхода:
Pwn3d, т.е. полный доступ к системе. Обычно пентестеры ожидают именно этот результат и, наверное, многие обратят внимание только на него.
-
Сетевые диски READ+WRITE позволяют:
положить ярлык и принять NetNTLM-хэш, чтобы его сбрутить или срелеить и получить доступ куда-то ещё;
положить файл enable_webclient.searchConnector-ms, который активирует службу WebDAV, что может быть использовано для LDAP Relay-атаки и последующего захвата компьютера, посетившего данный сетевой диск;
либо же просто пропатчить, скажем, EXE или DLL-файлы, или дописать что-нибудь в скрипты Ps1, VBS или BAT, что также может открыть последующий удаленный доступ.
Наконец, шара READ. Наверное, это самый скучный и бесперспективный случай, но самый частый, и именно о нём и пойдет речь во всей этой статье.
Локальные сети с Active Directory — это экосистема, при которой узлы находятся во взаимодоверительных отношениях, и им многое позволено в отношении друг друга. Доступ даже с доменной учетной записью «простого смертного» пользователя обычно открывает целую кучу сетевых дисков.
И в случае, если был получен READ на IPC$-шару доменного ПК, мы открываем для себя ряд дополнительных манёвров:
coerce;
enum local users, group;
sessions;
PrintNightmare, прочие CVE.
Всё это не связано напрямую с сетевыми дисками, а лишь с RPC, который, так сказать, соседствует рядом, и доступен на 445/TCP-порту (и не только там). Но вспомним главное предназначение сетевых дисков — хранение файлов. И в этих самых файлах может лежать абсолютно что угодно.
1.2 Анализ файлов
К проблеме поиска чувствительных данных возможны два подхода. Самый очевидный — анализ, основанный на имени файла и его расположении:
mount.cifs '//10.0.0.64/temp' /mnt/temp -o ro,dom=corp.local,user=username && find /mnt/temp -printf '%p | %k KB | %t\n' >> files.txt && umount /mnt/temp
или просто
cme smb -M spider_plus smb-hosts-anon.txt
Подход хорош тем, что достаточно быстр и способен «переварить» все файлы на всех доступных сетевых дисках. Он покажет имя файла, его размер, а также дату — что может быть полезно для некоторого ранжирования актуальности файлов.
Однако в итоге догадываться о содержимом нам остается лишь по названию. Поэтому такой анализ никак нельзя считать полным, скорее лишь первым шагом.
Нужно понимать, что далеко не всегда имя документа будет соответствовать содержимому. Иногда пользователи помещают важную информацию в файлики с названием «1.txt», «123.docx» или давая им названия, понятные только самим владельцам, что сводит на нет анализ содержимого по имени файла.
Анализ, основанный на содержимом файла, будет максимально полным, но потребует времени, особых решений и большого количества трафика. Так что за него в свою очередь придется «заплатить».
Первая проблема, которая возникает у пентестера — это как проанализировать не один сетевой диск, а сразу сотню или ещё больше. Тут явно нужна автоматизация и строгое понимание, что мы хотим найти. Проблему эту пока ещё можно легко решить, например, скриптом, который будет монтировать каждый сетевой диск, делая его локальным. И затем всякий раз рекурсивно искать по всем файлам то или иное вхождение:
cat smb-anon.txt | while read ip share
do echo $ip $share
mkdir "/mnt/$ip-$share" 2> /dev/null
sudo timeout 5 mount.cifs "//$ip/$share" "/mnt/$ip-$share" -o ro,dom=.,user=user,pass=pass
timeout 300 grep -r "s3cr3t" "/mnt/$ip-$share"
sudo umount "/mnt/$ip-$share"
done
Но далее возникает вторая проблема: существует множество не текстовых файлов, которые нельзя проанализировать одинаковым образом, например, простым grep. И именно тут отпадает большинство доступных решений.
Пользователям более привычно работать в Word, и, например, вот так они могут хранить чувствительные данные:
И такие данные уже так просто найти не удастся.
Существует ещё Excel, где могут храниться списки учеток:
Или PDF-документы, например, инструкции. Не стоит забывать и про картинки. Отсканированные документы могут также содержать чувствительную информацию. Например, это могут быть схемы:
Ведь на этапе продвижения злоумышленнику могут потребоваться не только пароли, но и схемы сети и адреса сегментов.
Из менее очевидных форматов файлов — исполняемые. EXE и DLL-файлы и их аналоги под Unix хоть и не являются текстовыми файлами, но все же могут содержать в себе обычные строки. И если в компании есть программисты и пишутся свои программы, то вполне возможно, что в исполняемом файле будет захардкоженный пароль. Пример тому — ODBC-строки для подключения к базам данных, что открытым текстом содержат пароль:
Наконец, разнообразные архивы: ZIP, RAR, TAR, 7zip — они могут содержать в себе все вышеперечисленные форматы файлов.
И ни один из вышеупомянутых типов файлов нельзя обрабатывать простым поиском по файлу — в каждом случае нужен свой парсер.
1.2.1. Парсим файлы
Нет никакого смысла писать парсеры с нуля: используя богатство GNU-утилит, мы можем выдернуть текст даже из самых экзотических форматов файлов. Ведь в Linux под любую задачу всегда найдется команда. И под любой тип файла можно найти утилиту или конвейер, который молча, без лишних вопросов (и ошибок!), обработает файл и вернет хранящийся в нём текст.
И так можно работать с чем угодно. Например, с помощью консольного браузера lynx мы в одну команду можем отрендерить HTML-файл и оставить только полезные данные — текст:
С помощью xls2csv можно получить текст из файлов Excel:
Утилита pdf2txt возвращает текст из PDF:
А экосистема Radare2 способна распарсить любой исполняемый файл и напечатать его строки:
Утилита tesseract распознает текст на изображениях:
А утилита vosk умеет распознавать текст в звуке:
Наконец, какой бы архив нам не встретился благодаря консольной утилите 7-Zip, мы можем обработать и его:
И какие бы файлы в нем ни были — текстовые, PDF, картинки, программы или даже вложенные архивы — все они будут последовательно обработаны с использованием данных парсеров.
В итоге, применяем принцип «разделяй и властвуй». Каждый из парсеров — это открытая и бесплатная утилита, которая может быть установлена в одну команду. И каждая из них работает достаточно быстро, за долю секунды возвращая результат для каждого нового файла.
Но как понять, какой парсер задействовать? Ведь расширение файла не очень надежный признак. Для этого используем MIME-type, и уже на основе него выбираем парсер:
В общем, я постарался решить проблему извлечения информации из документов максимально простым способом, не прибегая к программированию, и при этом получить максимальный эффект:
Видим, что такой подход позволяет достаточно точно определять тип файла и подбирать под него соответствующий парсер, который быстро выдергивает текст из документа. Нам практически не нужно ничего изобретать. Все необходимые примитивы уже доступны в виде отдельных консольных программ, отлично делающих своё дело. Нужно только соединить это всё воедино.
1.2.2. Работаем с протоколами
Но что насчёт протоколов? Ведь доступ до тех или иных документов в локальной сети может быть как через SMB на сетевой диск, так и через FTP или тот же HTTP. Но мы не хотим писать клиенты под каждый новый протокол со всеми его особенностями, нам нужны готовые решения, причем максимально простые.
И тут снова на помощь приходят всемогущие GNU-утилиты. В случае SMB мы можем примонтировать удаленный сетевой диск к своей файловой системе и сделать его локальным. Тем самым полностью абстрагировавшись от протокола:
Наконец, утилита find соединяет всё воедино. Она возвращает список файлов в указанном месте в виде полных путей, которые будут подхвачены утилитой file, определяющей тип файла, и на основе этого произойдет выбор соответствующего парсера:
Утилита find имеет обширный список опций, позволяющих тонко настроить краулинг: максимальный размер файла, глубина, игнорируемые пути и расширения файлов и так далее. Так, опция -depth позволит не провалиться в бесконечную структуру папок и собирать информацию на сетевых дисках слоями, а опция -size — не начать скачивать огромный бэкап. Самостоятельная реализация такого движка на Python заняла бы сотни, тысячи строк кода (и целую вечность на устранение encode/decode error), а тут мы всё делаем в одну команду.
Если подытожить и собрать всё воедино, то получается следующая архитектура краулера:
mount / wget → find → file → парсер → csv-файл
Конвейер из GNU-утилит, каждая из которых отлично выполняет свою задачу и имеет одинаковый консольный интерфейс.
В итоге вместо тысячи строк кода на Python мы имеем лишь один Bash-скрипт. Ведь ничего мощнее find+grep для поиска в современном мире не существует.
Но как быть, когда перед нами сотни сетевых дисков с кучей информации? Используем простой цикл:
cat smb-anon.txt | while IFS=$'\t' read ip share
do echo $ip $share
mkdir "/mnt/$ip-$share" 2> /dev/null
sudo timeout 5 mount.cifs "//$ip/$share" "/mnt/$ip-$share" -o ro,dom=.,user=user,pass=pass
timeout 300 ./crawl.sh "/mnt/$ip-$share" -mindepth $DEPTH -maxdepth $DEPTH -size -100k
sudo umount "/mnt/$ip-$share"
done
Такая система рано или поздно доберется до любого файла, как бы глубоко он ни был запрятан на сетевом диске, определит его тип, вне зависимости от расширения файла, и извлечет полезные данные.
1.2.3. Формируем индекс
Результатом работы краулера будет текст, извлеченный из документа — полезные данные, сохраняемые в CSV-формате:
Почему именно CSV? Потому что этот формат — золотая середина между типом, который можно как распарсить для дальнейшей машинной обработки и автомазации, так и применить к нему обычный поиск grep-ом и человеческий просмотр в блокноте. Каждый CSV-файл содержит исключительно полезные данные — текст, который мы смогли выдернуть из всех форматов файлов. А значит, для поиска чувствительной информации теперь уже простым grep мы можем искать данные как в текстовых файлах, так и в Word, Excel, PDF и даже на картинках и в аудио:
Примитивно, но пентестеру больше и не нужно.
И в принципе уже в этом месте задача поиска чувствительных данных в различных файлах решена. Но мы пойдем дальше.
1.2.4. Консольный Google
Ключевым моментом при анализе содержимого является создание предварительного индекса. Так как перед нами могут быть сотни сетевых дисков с тысячами файлов, выполнять каждый раз заново краулинг под очередной новый поисковый запрос — не оптимально. Суть краулинга в извлечении текста из максимального количества файлов и сохранении его в индексный файл вместе с информацией о расположении. А потом уже к локальному индексу мы можем применять куда более быстрый и гибкий поиск, используя всю мощь grep.
С помощью GNU-утилиты tre-agrep мы можем применить также нечеткий поиск и искать похожие слова. Например, по фразе «пароль» найти также слова «пароли», «паролем» и даже опечатки типа «пороль»:
Сделаем консольный аналог Google. Для придания чуть большего удобства поиска, легким движением руки можно импортировать все собранные данные в суперлегковесную автономную базу данных SQLite:
База SQLite прекрасно понимает CSV и к тому же имеет даже собственный полнотекстовый поиск.
И с помощью чрезвычайно простого скриптика мы имеем хакерский консольный Google:
#!/bin/bash
GREEN=$'\x1b[32m'
RESET=$'\x1b[39m'
MATCH=30
LIMIT=10
OFFSET=0
URI='%'
while getopts "m:c:o:u:" opt
do
case $opt in
m) MATCH=$OPTARG;;
c) LIMIT=$OPTARG;;
o) OFFSET=$OPTARG;;
u) URI=$OPTARG;;
esac
done
[[ $(($#-$OPTIND)) -lt 1 ]] && [[ $URI = '%' ]] && {
echo "$0 [opts] words.db QUERY"
echo "opts:"
echo " -m match"
echo " -c count"
echo " -o offset"
echo " -u fragment"
exit
}
DB="${@:$OPTIND:1}"
shift $OPTIND
IFS='=%='
echo "SELECT uri,text FROM words WHERE uri LIKE '$URI' and text LIKE '%$*%' limit $LIMIT offset $OFFSET;" | sqlite3 -separator '=%=' "$DB" | while read uri text
do
echo $GREEN"$uri"$RESET
echo "$text" | grep -i -o -P ".{0,$MATCH}$*..{0,$MATCH}" | grep -i --color=auto "$*"
done
Тут мы уже можем задавать количество совпадений, оффсеты и прочие вещи, основанные на мощи языка SQL:
Такой краулер, построенный лишь на GNU-утилитах wget, mount, find, file и ряде парсеров, чрезвычайно надежен. Ведь GNU — это один из самых качественных и надежных примеров ПО, что протестировано тысячами людей в течении десятков лет. И многие из этих утилит настолько надежны, что могут встречаться под капотом и у других программ, включая и эту систему.
2. Анализируем веб
Достаточно массивные интранеты могут иметь богатую экосистему внутренних сайтов. Подавляющее большинство вебов в локалке — это принтеры, IP-камеры и телефоны, различные устройства и формы аутентификации. Но могут встретиться и полноценные сайты — самописные информационные системы, порталы или базы знаний. У таких ресурсов контент может быть доступен без аутентификации, либо быть доступным каждому в домене. Следовательно, такие ресурсы также могут содержать ценную информацию.
Содержимое сайтов может быть клонировано с сохранением полной структуры с помощью обычной GNU-утилиты wget:
Утилита wget имеет обширный список опций, позволяющий гибко настроить её для обхода сайта.
В большинстве локальных сетей, где нет хорошей связности между сайтами через перекрестные ссылки, краулинг, скорее всего, заглохнет. И поэтому целесообразен краулинг каждого сайта по отдельности после предварительного сканирования всей сети с помощью nmap.
3. Анализируем FTP
И тоже самое с FTP. Утилита wget умеет работать не только с HTTP, но и с FTP (и даже IMAP), расширяя возможности применения краулинга:
После чего уже локальное содержимое может быть прокраулено, включая информацию о структуре, и знакомые нам GNU-утилиты вытащат все секреты.
Пришла пора поговорить о защите. И это тот самый случай, когда раздел защиты будет интереснее атаки. Ведь защищаться мы будем нападением!
Как можно защититься от утечки нежелательных данных на общедоступных ресурсах? Можно ограничить сетевой доступ, тонко настроить права, а можно самостоятельно контролировать содержимое. С первыми двумя вы прекрасно справитесь сами. Я же покажу, как можно контролировать содержимое: организуем непрерывный процесс краулинга и оформим его в красивый энтерпрайзный вид.
4. Полноценный Google
Поисковые движки Elasticsearch или OpenSearch прекрасно справляются с неструктурированными наборами документов в огромном количестве. И мы можем просто скидывать в них извлеченный текст из документов в формате ключевых слов, сильно напоминающих синтаксис Google:
А если идентифицировать документы на основе их расположения, то мы можем в последствии обновлять накопленные данные и сделать возможным непрерывный краулинг.
И после написания небольшого веб-интерфейса к OpenSearch (https://github.com/s0i37/crawl/tree/master/www) получаем свой Google в локальной сети:
Поисковый движок OpenSearch имеет всё необходимое. В частности, он позволяет реализовать автодополнение вводимого текста, на лету предлагая, что содержится в базе.
Результаты поиска ранжируются, исходя из приоритетов совпадений, а сами совпадения подсвечиваются опять же силами OpenSearch — ничего изобретать не нужно:
Ну а с помощью привычных Google-дорков можно более продвинуто искать те или иные данные:
Например, показать документы типа Word, в расположении которых указано слово «документы», а в теле встречается фраза «пароль».
Нажатие на синий текст в каждом совпадении откроет в новой вкладке расположение документа, а на зеленый — его кэш. Это может быть полезно, если проиндексированный файл удален, так мы можем посмотреть сохраненные данные документа. Словом, всё как у настоящего Google.
Для картинок, которые встречаются в ходе краулинга, происходит попытка распознавания текста с помощью Tesseract. Но также, с помощью Graphicsmagick картинка немного уменьшается в размере и сохраняется локально, тем самым делая возможным поиск изображений:
Так мы можем искать даже отсканированные документы или скриншоты.
4.1. Непрерывный краулинг и актуализация информации
Каким бы ни был размер локальной сети, все её ресурсы вряд ли удастся прокраулить подобным образом за один раз. Даже на одном сетевом диске спокойно может оказаться несколько сотен гигабайт данных. Однако, учитывая, что скрипт краулинга фиксирует свой прогресс, мы можем возобновлять его столько раз, сколько потребуется. И в теории можно организовать непрерывный краулинг всех открытых ресурсов с плавным накоплением индекса.
Мы можем полностью автоматизировать весь процесс. Сперва получаем список хостов в локальной сети:
Тут мы через LDAP запрашиваем список доменных компьютеров. С помощью DNS определяем IP-адрес каждого компьютера. Все IP-адреса объединяем в подсети по маске /24. И сортируем их в порядке обитаемости — для приоритезации краулинга.
Параллельно с этим сохраняем соответствие IP и доменного имени — так как многие компьютеры меняют свои IP-адреса, а нам нужно узнавать уже прокрауленные узлы.
Из-за того, что связности между сетевыми дисками, FTP и даже веб-сайтами в локальных сетях почти никогда не бывает, придется отдельно выискивать каждый ресурс с помощью сканирования портов:
Мы сканируем именно подсети (полученные от предыдущего скрипта), так как изначально запрашивали списки доменных компьютеров. Но рядом с ними в том же сетевом сегменте могут быть и не доменные компьютеры, например, Linux-серверы, и прочие устройства, которые также должны быть прокраулены.
На выходе получаем 3 файла: список компьютеров с сетевыми дисками, FTP и веб-сайты.
И для каждого списка целей запускаем свой скрипт-обёртку. Для SMB:
С помощью первого цикла мы получаем список сетевых дисков каждого компьютера, на которых у нас есть права чтения.
Наконец, во втором цикле для каждого сетевого диска мы запускаем краулинг на фиксированное время (например, на 5 минут). При этом мы указываем максимальный размер файла, чтобы случайно не начать скачивать какой-нибудь огромный бэкап. Также в данном цикле мы фиксируем глубину краулинга, плавно увеличивая её на каждой итерации. Так мы защищаем себя от возможности глубоко провалиться в структуру папок и утонуть там, не заметив важные файлы на поверхности.
В результате такого подхода мы плавно, слоями, снимаем всю информацию с сетевых дисков.
В случае с сетевыми дисками мы имеем одну уникальную возможность: выявлять новые недавно загруженные файлы благодаря тому, что протокол SMB предоставляет нам сетевой диск как файловую систему, содержащую также метаинформацию о файле (время создания, изменения, доступа). И с помощью утилиты find, которая является источником файлов для краулера, мы можем выделить недавно загруженные файлы:
Например, что было загружено за последний день.
В итоге на выходе мы имеем по CSV-файлу для каждого сетевого диска.
Для веб-ресурсов мы запускаем другой скрипт:
Он для каждого сайта в течение указанного времени скачивает его содержимое, превращая сайт в локальную папку, и после использует те же самые средства, что и для краулинга сетевых дисков.
Утилита wget достаточно умна и при повторном запуске возобновляет прерванную сессию, докачивая новые файлы и делая возможным постепенный краулинг веба.
Абсолютно аналогично с FTP:
Наконец, когда все ресурсы просканированы и полезные данные находятся в CSV-файлах, их можно импортировать в OpenSearch:
Собирая всё воедино в планировщике заданий cron мы можем настроить удобное время, когда целесообразно начинать сканирование, сколько по времени выделить на краулинг, пока сотрудники не выключили компьютеры, и в какие часы пополнять индекс:
Непрерывный краулинг рано или поздно должен начать актуализацию всех накопленных данных. В ходе краулинга фиксируется список проанализированных файлов, которые в дальнейшем игнорируются. И, предположим, раз в месяц мы можем сбросить прогресс и запустить краулинг с самого начала, актуализируя всю накопленную информацию:
Информация в самой поисковой системе при этом будет обновляться постепенно, по мере обхода краулерами документов. Именно поэтому в интерфейсе поисковика сделано поле «даты», показывающее, когда документ был проиндексирован.
4.2 Горизонтальное масштабирование
Чтобы процесс краулинга шел быстрее, его можно распараллелить между несколькими серверами. Это реализовано чрезвычайно простым образом — буквально в одну строчку. В каждом скрипте сделана простая конструкция, выбирающая каждый N-ный IP-адрес для краулинга:
И если, скажем, краулера два, то первый берёт чётные цели, а второй — нечётные. И так далее для трёх и более серверов краулеров.
4.3. Вертикальное масштабирование
Система краулинга открыта и прекрасно поддается вертикальному масштабированию. Всего в пару-тройку строчек кода мы можем добавить поддержку нового типа файла — важно лишь хотя бы приблизительно знать его MIME-type.
Например, можно прикрутить более качественный внешний OCR для распознавания картинок, который определит тип документа и промаркирует его соответствующим образом, чтобы впоследствии файл можно было легко отыскать в интерфейсе поисковой системы.
4.4. Автоматизация результатов
В сети интернет поисковики — это привычное дело. Что-то, без чего сложно представить себе современный мир. Но в локальных сетях они не распространены. И схожий класс решений, что анализирует общедоступные документы, называется DCAP.
Моё решение — это далеко не DCAP. Такие системы сложны и помимо индексации документов хранят историю каждого файла — кто и когда его загрузил, и кто получал доступ. От этого, DCAP системы сложны во внедрении, так как требуют агента на каждый компьютер. Но на мой взгляд, куда более ценной является не информация о происхождении файла, а банально о его наличии. Ведь в первую очередь файл следует удалить или ограничить к нему доступ. И уже в дальнейшем вести разбирательства — кто его загрузил, и кто успел посмотреть.
Также DCAP-системы не сохраняют извлеченный текст. Они изначально настраиваются на поиск нужной информации. И это, на мой взгляд, ещё один минус DCAP-систем. Так как паттерны могут дополняться, а значит, потребуется заново производить краулинг. Зачастую паттерны приходят в голову уже в процессе поиска.
DCAP-системы не требуют ручного поиска по накопленным данным и сами информируют о появлении тех или иных чувствительных документов. Поэтому, чтобы моё решение имело и некоторые схожие черты с привычным DCAP, и могло автоматически уведомлять о появлении нежелательных файлов, я просто сделал небольшой REST-API эндпоинт:
Просто по крону запускаем скрипт и запрашиваем те или иные данные. И если что-то вернулось — отправляем уведомление, например, в телеграм или почту.
4.5 Внедрение
Ну и раз уж большая часть поисковика — это наборы системных утилит, то всё оформлено в виде докер-контейнера, включающего также установленный OpenSearch и сопутствующие компоненты.
sudo docker build -t crawl
sudo docker run --cap-add SYS_ADMIN --cap-add DAC_READ_SEARCH --cap-add NET_BIND_SERVICE --cap-add CAP_SYSLOG -u 1000 -p 8080:8080 --name crawl -it crawl
А весь исходный код представлен в https://github.com/s0i37/crawl.
Так что, внедрение и использование системы — это ввод пары команд.
Теперь у нас в локальной сети есть свой Google!
Outro
Думаю, ни одна компания и ни один администратор не может быть уверенным на 100%, что в его SYSVOL, SCCM и прочих системных сетевых дисках не хранится где-нибудь, что-нибудь лишнее. Не то что в Plain-text в каком-нибудь скрипте, но и даже в скомпилированном самописном exe-шнике или архиве внутри архива. И уж тем более, никто не возьмет на себя ответственность за пользовательские сетевые диски, в особенности, если пользователи —локальные админы.
Коммерческие DCAP-решения дороги и сложны во внедрении. Представленная же система открыта, чрезвычайно проста и легко доступна для индивидуальных улучшений. Поэтому защитникам я предлагаю простой и бесплатный способ хоть как-то провести аудит своих общедоступных внутренних ресурсов, а нападающим пентестерам не забывать про то, что доменный админ может быть куда ближе, чем кажется.
Автор: Андрей Жуков, ведущий специалист по анализу защищенности УЦСБ
dissable
Это очень хорошо