Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
sift — Триаж раскрытия учётных данных и конфиденциальных данных для файловых ресурсов | Kitploit
Инструменты/GitHubGitHub/hotstartlabs/sift
Оборонительные ИнструментыЦифровая криминалистикаОбнаружение СекретовРеагирование на Инциденты
GitHubhotstartlabs/sift

sift

Триаж раскрытия учётных данных и конфиденциальных данных для файловых ресурсов

Репозиторий
1681 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Sift Secrets

tests

Триаж утечек учётных данных и чувствительной информации для файловых ресурсов.

Когда появляется открытый файловый ресурс, вопрос никогда не звучит как «есть ли в этом репозитории утёкший ключ». Он звучит так: «что именно оказалось раскрыто, и что мне нужно отозвать до конца рабочего дня». sift создан именно для этого вопроса: высокая полнота поиска, быстрая очередь просмотра и цикл обратной связи, благодаря которому всё, что вы заметите невооружённым глазом, превращается в правило, которое находит остальные двести копий.

Очередь триажа: находки слева, совпадение выделено в окружающих его строках
справа

Python 3.11+, только стандартная библиотека. Без pip install, без интернета, без шага сборки. Он работает на изолированном ноутбуке для реагирования на инциденты — именно там, где он вам нужен.```bash sift survey \fileserver\openshare # how big is this thing sift copy \fileserver\openshare C:\IR\case-4471 # take a throttled copy sift scan C:\IR\case-4471 # scan it, opens the triage UI

root@kitploit:~
Сканирование на месте тоже работает. Сначала попробуйте его на сетевом ресурсе с вымышленными учётными данными:```bash
sift demo C:\temp\demoshare

sift.cmd — это лаунчер, который работает из любого каталога. Чтобы вводить sift вместо полного пути, добавьте C:\Dev\sift в PATH:```bash setx PATH "%PATH%;C:\Dev\sift"

root@kitploit:~
Для машины без Python вообще `python build_portable.py` собирает
`dist/sift-secrets-<version>-portable-win64.zip`: официальный встраиваемый рантайм python.org плюс это дерево исходников, распакуй и запускай через прилагаемый `sift.cmd`. ~11 МБ, без установки, без прав администратора, и в нём ничего не компилируется и не переупаковывается — см. docstring в `build_portable.py`, почему это лучше замороженного .exe на заблокированном ноутбуке для IR.

---

## Почему не просто gitleaks или trufflehog

Оба — хорошие инструменты, решающие другую задачу.

Это **точные** инструменты, созданные для CI, где ложное срабатывание стоит разработчику целого дня, поэтому они в основном срабатывают на то, что по форме похоже на известный API-ключ вендора. trufflehog идёт дальше и предпочитает секреты, которые можно *проверить*, вызвав API вендора, — это действительно отличный сигнал, который regex не способен воспроизвести.

Триаж на файловом ресурсе переворачивает экономику. Человек и так читает каждое срабатывание, так что ложное срабатывание стоит три секунды. По-настоящему дорого обходится **пропуск**.

API-ключи вендоров действительно утекают на файловых ресурсах — бэкап корня веб-сервера, скрипт деплоя, чья-то проектная папка, скопированная на общий диск, и там лежит `.env` с живым ключом Stripe. Их ловить стоит, и sift их ловит. Но это как раз та часть, с которой gitleaks и trufflehog уже отлично справляются. Пробел — всё остальное, и на файловом ресурсе это большая часть всего:

| Что пропускают CI-сканеры | Почему они проходят мимо |
|---|---|
| `web.config` с SQL-строкой подключения | Не известный формат ключа, нет вендора для проверки |
| `Map-Drives.ps1` с `net use ... /user:` | Просто shell-команда со словом после неё |
| `New Hire Setup Guide.docx` | Office-файл, читается как бинарный, полностью пропускается |
| `unattend.xml`, GPP `Groups.xml` | Артефакты развёртывания Windows, для которых никто не написал детектор |
| `confCons.xml`, `.rdg`, WinSCP.ini | Обратимо сохранённые пароли, но не «секретный формат» |
| `passwords.xlsx` | Это ZIP. Сканеры plain-text видят бинарные данные и идут дальше |
| `.kdbx`, `.pfx`, `id_rsa` | Непрозрачные байты — *имя файла* и есть находка |
| `.bak` со строкой подключения внутри | Бинарный, поэтому никогда не читается |

sift покрывает и это, поставляет собственные правила для ключей вендоров и **импортирует наборы правил и результаты других инструментов** — правила gitleaks в TOML, Kingfisher/Titus в YAML и trufflehog в JSON, — так что вам не приходится выбирать между инструментами.

Ближайший аналог — [Snaffler](https://github.com/SnaffCon/Snaffler), который отлично справляется с половиной этой задачи — классификацией по именам файлов — и послужил прямым источником вдохновения для правил имён файлов. Чего в нём нет — и что на деле оказывается узким местом, когда у вас 400 срабатываний, — так это цикла ревью.

---

## Цикл

1. **Просканируйте** ресурс.
2. **Работайте с очередью.** Каждая находка показывает окружающие строки с подсвеченным совпадением. Стрелки расширяют контекст; один клик открывает весь файл в VS Code на этой строке или в Notepad.
3. **Замечаете пропуск.** Так и будет. Подсветите его в предпросмотре и нажмите `r`.
4. **sift предлагает паттерны** и в реальном времени показывает, сколько раз каждый из них совпадёт со всем уже прочитанным.
5. **Сохраните его.** Кэшированное повторное сканирование занимает около секунды, и новые находки появляются в очереди, а ваши предыдущие решения по триажу остаются нетронутыми.

Шаг 5 — та часть, ради которой всё остальное. Находки идентифицируются по `(path, rule, line, value-hash)`, поэтому повторное сканирование вставляет те же строки, а ваш статус, заметки и ответственный сохраняются. Без этого вам пришлось бы заново просматривать те же 300 срабатываний на каждой итерации, и вы бросили бы это на третьей.

---

## Команды```bash
# size it up first: file count, total bytes, biggest folders, transfer estimates
sift survey \\fileserver\share

# take a rate-limited local copy (resumable; gentle = 5 MB/s by default)
sift copy \\fileserver\share C:\IR\case-4471 --speed gentle

# scan a share and open the triage UI
sift scan \\fileserver\share

# maximum recall: more noise, but a human is reading anyway
sift scan D:\dfs\dept --tier 3

# re-open the UI over the most recent scan
sift ui

# build a share of fabricated credentials, scan it, open the UI
sift demo C:\temp\demoshare

# inherit other tools' vendor-key rules, then use them in the live rescan loop
sift import-rules gitleaks.toml                    # gitleaks TOML
sift import-rules path/to/kingfisher/data/rules    # a directory of YAML

# pull in what the other scanners found, into the same queue
trufflehog filesystem \\fileserver\share --json > th.json
sift import-findings th.json

# hand off to the incident record (redacted unless you say otherwise)
sift export --fmt pdf --status confirmed --out ir-4471.pdf
sift export --fmt csv --out ir-4471.csv
sift export --fmt pdf --no-redact       # plaintext; handle as evidence

sift rules                              # what is loaded
sift selftest                           # detection tests against a synthetic share

# ask vendors whether confirmed findings are still live. NETWORK. Opt-in.
sift validate --status confirmed

В любом месте, где встречается sift, вы можете использовать python -m sift вместо этого, из каталога C:\Dev\sift.

Полезные опции

Где хранится состояние

Находки попадают в папку для каждой цели внутри %LOCALAPPDATA%\sift\, никогда — в рабочую директорию: база данных содержит учётные данные в открытом виде, и запуск инструмента из домашней директории не должен молча создавать такую базу там. Каждый общий ресурс получает собственное хранилище, поэтому два расследования никогда не делят очередь триажа. sift ui без аргументов снова открывает последнее; --data DIR переопределяет.

Пользовательские правила — глобальные, в файле %LOCALAPPDATA%\sift\user-rules.json, поэтому шаблон, написанный в ходе одного расследования, помогает на следующем общем ресурсе, который вы смотрите.


Перед сканированием: осмотр и копирование

Обе функции находятся в шапке интерфейса, рядом с полем пути, и в CLI.

Проверка размера — это обход только через stat. Ничего не открывается, поэтому это дёшево даже по SMB, и она сообщает количество файлов, общий объём в байтах, самые большие папки, разбивку по расширениям, сколько sift на самом деле прочитает и сколько времени займёт копирование на каждой скорости. Направить сканер на неизвестный корень DFS и ждать — вот как исчезает полдня.

Локальное копирование сначала стягивает общий ресурс в локальную папку. Это стоит делать, потому что:

  • сканирование локальной копии намного быстрее, чем тысячи SMB-запросов;
  • это повторяемо, поэтому добавление правила и повторное сканирование не нагружает файловый сервер повторно;
  • оригинал остаётся нетронутым, а это разница между «мы посмотрели» и «мы сохранили», если инцидент переходит в юридическую плоскость.

Передача ограничена по скорости и по умолчанию составляет 5 МБ/с. Насыщение канала до производственного файлового сервера в 14:00 превращает ваше расследование во второй инцидент. Увеличивайте её, когда знаете, что канал свободен.

РежимСкорость
щадящий (по умолчанию)5 МБ/с
обычный25 МБ/с
быстрый100 МБ/с
без ограниченийсколько даст канал

Передачи возобновляются: целевой файл с тем же размером и mtime пропускается, поэтому прерванное на 80% копирование продолжается с места остановки. Заблокированные или недоступные файлы записываются и пропускаются, а не прерывают выполнение.


Отчёты

PDF, CSV, MD и JSON — из шапки интерфейса или через sift export --fmt.

PDF — это документ для передачи в материалы инцидента: титульная страница с целью, итоги по критичности и статусу триажа, самые частые правила, значения, переиспользуемые в разных файлах, а затем находки, сгруппированные по критичности. Он формируется напрямую, без библиотеки PDF, поэтому работает на машине, где никогда не было pip.

Экспорты по умолчанию замаскированы. Значения маскируются, каждая страница помечена баннером, и эндпоинт отключает маскирование только при явном redact=0 — усечённый или повреждённый запрос не может вызвать утечку. Отключение маскирования в интерфейсе требует подтверждения предупреждающего диалога, и итоговый файл на каждой странице помечен баннером UNREDACTED - CONTAINS PLAINTEXT CREDENTIALS.

База данных находок по-прежнему хранит настоящие значения, потому что аналитику нужно знать, какой пароль утёк, чтобы понять, что менять. Граница проходит по тому, что покидает инструмент.


Работа с очередью

Всё кликабельно. Элемент сортировки вверху списка результатов переупорядочивает по критичности, пути файла, правилу, статусу триажа или новизне, с кнопкой для обратного порядка. Фильтры на боковой панели отбирают по критичности, категории, правилу и переиспользуемому значению. Триаж, расширение контекста, открытие файла и создание правила — всё это кнопки.

Приведённые ниже горячие клавиши — это ускорители для длинной очереди, а не единственный способ управления ею.

Кнопка snapshot преобразует выделенный фрагмент в PNG для вставки в тикет инцидента; copy snippet делает то же самое в виде markdown.


Безопасность

Интерфейс отображает живые учётные данные в открытом виде в окне браузера, поэтому:

  • привязывается только к 127.0.0.1 и отклоняет всё остальное без --unsafe-bind;
  • требует случайный токен на каждый запуск, передаваемый в URL запуска и затем хранящийся в cookie SameSite=Strict;
  • проверяет заголовок Host, поэтому враждебная страница не может сделать DNS-ребинд на него;
  • отправляет CSP вообще без внешних источников — ничто на странице не может экфильтровать то, что она отображает;
  • отказывается читать или открывать любой путь, которого нет в базе данных находок, поэтому /api/context — это не произвольное чтение файлов, а /api/open — не произвольный запуск процессов.

База данных находок намеренно содержит учётные данные в открытом виде — аналитику реагирования на инциденты нужно знать, какой пароль утёк, чтобы понять, что менять. Относитесь к %LOCALAPPDATA%\sift\<target>\findings.db как к доказательству: обращение как с самим общим ресурсом, и удалите её, когда расследование завершится. Используйте --redact, если она покинет границы инцидента.

И очевидное: запускайте sift только против систем, к которым у вас есть разрешение на доступ.


Как устроены правила

sift/rules_builtin.py — правила содержимого. sift/rules_filename.py — правила имён файлов. Оба — простой Python с raw-строками в качестве шаблонов, поэтому они читаемы и пригодны для diff; пользовательские правила находятся в JSON в .sift/user-rules.json.

Три уровня позволяют обменивать точность на полноту:

  • Уровень 1 — однозначные. Форматы ключей вендоров, блоки PEM, GPP cpassword, дампы NTLM, пароли привязки LDAP. Одна форма — уже доказательство.
  • Уровень 2 (по умолчанию) — правила близости. «Слово, похожее на секрет, рядом со значением». Здесь обитает большинство реальных утечек на общих ресурсах.
  • Уровень 3 — немаркированные строки с высокой энтропией, длинные hex-последовательности, IBAN. Шумно, но при оценке масштаба утечки лучше прочитать 400 срабатываний, чем пропустить одно.

Правило может также нести min_digits, min_lowercase, min_uppercase и min_special, поэтому одно шумное правило можно ужесточить, не трогая остальные, а также examples — строки, которым оно всё ещё обязано соответствовать.

Правила, которые проверяют сами себя

examples — полезная половина. sift selftest прогоняет каждое правило по строкам, для которых оно было написано, через весь путь: сопоставление, извлечение, затем фильтры подавления. Именно этот последний шаг важен, потому что реальная регрессия — это не шаблон, который перестал совпадать, а фильтр шума, ужесточённый по веским причинам в другом месте, незаметно съедающий реальную находку на выходе.

Это сразу окупается. Добавление примеров к существующим правилам выявило реальный пробел: подчёркивание — это символ слова, поэтому ведущий \b в правиле универсального присваивания отказывался срабатывать внутри DB_PASSWORD, MYSQL_PASSWORD или REDIS_PASSWORD — трёх самых распространённых имён переменных для учётных данных на свете, — молча пропуская их. Пример выглядел явно правильным, но не совпал, — именно для этого он и нужен.

Правила, которые вы пишете в интерфейсе, получают это автоматически: выбранная строка сохраняется как пример правила, поэтому правило, отредактированное через шесть месяцев, сообщит вам, когда оно перестало совпадать с тем, что побудило вас его написать.

Импорт наборов правил других инструментов

sift import-rules принимает .toml gitleaks, .yml в стиле Kingfisher/Titus или каталог с ними. На наборе Kingfisher это 1 073 из 1 082 импортированных правил — с их порогами энтропии, требованиями к цифрам и регистру и примерами. YAML читается модулем sift/yamlmini.py — средством чтения подмножества, используемого этими наборами, — без зависимостей, и он возбуждает ошибку на якорях и тегах, а не делает вид, что понимает их.

Две вещи намеренно отбрасываются на входе:

  • Блоки validation:, которые задают URL для каждого правила. sift связывается только с хостами, жёстко прописанными в validate.py. Набор правил, который мог бы указывать эндпоинт, выбирал бы, куда отправляются ваши находки, а файл правил — это данные, а не решение.
  • Любое правило, чей шаблон больше не совпадает с его собственным документированным примером. Наборы написаны для Rust и Hyperscan, где [[:alnum:]] — это POSIX-класс; Python читает его как набор литеральных символов, успешно компилирует и сопоставляет не то, что нужно. Перевод проверяется по примерам каждого правила, поэтому шаблон, переживший компиляцию, но изменивший смысл, отвергается, а не молча никогда не срабатывает. Двенадцать правил Kingfisher не проходят эту проверку и не импортируются.

То, что собственное подавление sift могло бы отбросить конкретный пример, не дисквалифицирует правило, — эти наборы поставляются с намеренно фальшивыми образцами (keyXXXXXXXX, ...EXAMPLE), поэтому фильтр плейсхолдеров прав насчёт примера и ничего не говорит о шаблоне. Строгость в этом вопросе отбросила 121 рабочее правило, прежде чем различие было проведено.

Подавление работает не меньше, чем обнаружение

Общие правила для секретов забрасывают из-за шума, поэтому фильтры шума настраиваются так же тщательно, как и шаблоны. При измерении на реальном дереве из 6 000 файлов приведённые ниже правила подавления сокращают находки с 1 088 до 257 без потери полноты на тестовом корпусе:

  • Ссылки на код через точку. password: process.env.DB_PASS — это переменная, а не значение. Это одно подавление убирает большую часть шума общих правил в деревьях исходного кода.
  • Аннотации типов. def login(user: str, password: str) — это сигнатура.
  • Значения, начинающиеся с пунктуации, — это регулярное выражение, обрезанное на полпути, а не учётные данные.
  • Проза требует цифру или символ. Без этого правило читает английский текст об учётных данных — «a credential in the URL is reported and stripped» даёт «reported». Этому научили 99 ложных срабатываний на одном дереве.
  • Каталоги сборки и кэша (.wrangler, .next, site-packages, node_modules, …), а также минифицированные бандлы и source maps пропускаются. Машинный текст порождает только машинные ложные срабатывания.

Намеренно нет контентного правила https://user:pass@host с нестрогим хвостом. Очевидная версия сработала 476 раз на одном dev-дереве, потому что в минифицированном JSON нет пробелов, и шаблон тянулся от одного URL через кавычки и запятые, пока не находил посторонний @ сотнями символов позже.


Тесты```bash

python tests/run_all.py

root@kitploit:~
Двенадцать наборов тестов: обнаружение на синтетической шаре (разделено на «то, что уже ловят CI-сканеры», «разрыв, который закрывает этот инструмент», и «приманки, которые должны оставаться тихими»), командная строка, ранжирование правил-подсказок, опрос и регулируемый сбор данных (включая измерение лимита скорости относительно настенных часов), генератор PDF (разобранный обратно так, как это сделал бы читатель, чтобы доказать, что редактирование достигло содержимого страницы), импортёры gitleaks/trufflehog, HTTP API со всеми средствами защиты, статический анализ интерфейса и чтение блоков для файлов сверхбольшого размера (проверка того, что секрет в последнем блоке по-прежнему сообщает свой истинный номер строки во всём файле).

Чтобы получить шару для экспериментов:```bash
sift demo C:\temp\demoshare

Все учётные данные в этом корпусе сфабрикованы.


Проверка

Два уровня, потому что они несут очень разные риски.

Контрольные суммы бесплатны и всегда включены. Токены ghp_, npm_, Atlassian ATATT, Bitbucket ATCTT и маршрутизируемые токены GitLab glpat- содержат CRC32 по собственному телу. Пересчёт этой суммы позволяет в офлайне ответить на вопрос, на который раньше требовался интернет: настоящий ли это токен или пример, который кто-то вставил в README? Находки в очереди помечаются как checksum ok или malformed. Контрольная сумма доказывает форму, а не жизнь - правильно сформированный токен мог быть отозван год назад.

Живая проверка отключена, пока вы её не запустите. sift validate спрашивает у вендора, работают ли учётные данные до сих пор. Это отдельная команда, а не флаг для scan, и она заставляет вас ввести validate в приглашении, которое сначала перечисляет все конечные точки, с которыми она свяжется. Правила безопасности:

  • Конечные точки жёстко прописаны в sift/validate.py. Ни одно правило - встроенное, написанное пользователем или импортированное из чужого пакета - не может указать URL. Без этого импорт пакета правил был бы достаточен, чтобы отправить все учётные данные на общем ресурсе на адрес по выбору автора пакета.
  • Секрет передаётся в заголовке, никогда в URL или строке запроса, поэтому он не попадает в журналы прокси и журналы доступа вендора.
  • Перенаправления не отслеживаются. Код 302 - это инструкция отправить учётные данные куда-то ещё.
  • Отправляются только те учётные данные, которые уже прошли проверку контрольной суммы, поэтому очевидные подделки никогда не покидают машину.
  • Он отказывается работать с хранилищем --redact: если значения замаскированы, потому что база данных покидает границы инцидента, передача открытого текста - это именно то, от чего защищаются.
  • Каждый вызов записывается в validation-log.json рядом с базой данных находок
    • провайдер, конечная точка, время, результат - чтобы можно было точно сказать, с чем был контакт.

Попытки проверки попадают в журналы аудита владельца учётных данных и приписываются вашему адресу в тот самый момент. Иногда это именно то, что нужно, а иногда это насторожит противника, который следит. Решите, прежде чем запускать; именно поэтому он и спрашивает.

Сейчас это GitHub, npm, Slack и Stripe. trufflehog по-прежнему проверяет гораздо больше - запустите его и import-findings, чтобы получить и то и другое.


Известные ограничения

  • Проверка узкая. Контрольные суммы охватывают пять семейств токенов; живая проверка охватывает четырёх провайдеров. trufflehog проверяет сотни - запустите его и import-findings; подтверждённые находки оказываются в начале списка.
  • Зашифрованные контейнеры определяются только по имени файла. .kdbx или .pfx сообщается по имени; sift не пытается его открыть.
  • Базы данных SQLite читаются как таблицы, а не как байты. Они определяются по заголовку, а не по расширению, открываются только для чтения и в неизменяемом режиме, поэтому рядом с файлом, который является уликой, ничего не записывается. Таблицы конфигурации «ключ/значение» объединяются в name=value, без чего секретное слово и его значение находятся в разных столбцах, и ни одно правило не видит эту пару.
  • .7z, .rar и вложенные архивы помечаются, но не распаковываются. Внутри читаются только форматы на основе ZIP и сообщения .eml.
  • Файлы, превышающие --max-size, читаются блоками, а не кэшируются. Они сканируются (строка подключения в 4-гигабайтном .bak находится по её реальному номеру строки), но текстовый кэш вмещает только то, что помещается, поэтому односекундное повторное сканирование с кэшем их не покрывает - новое правило достигает большого файла при следующем полном сканировании.

Лицензия

Apache-2.0. См. LICENSE.

Тестовый корпус детектирования (sift/selftest.py, tests/) содержит намеренно сфабрикованные, но корректные по формату учётные данные; оповещения секретного сканирования для этих путей подавляются через .github/secret_scanning.yml.

Скачать инструмент
ФлагДействие
--tier 1|2|3Регулятор полноты. 1 = высокий сигнал, 2 = по умолчанию, 3 = не пропустить ничего
--redactМаскирует значения в хранилище и экспортах. Используйте, если БД покидает границы инцидента
--no-uiЗаполняет хранилище и завершает работу, для скриптовых запусков
--no-browserЗапускает UI-сервер, но не открывает браузер (полезно через RDP)
--include/--exclude GLOBСужает обход
--no-archivesНе открывает контейнеры docx/xlsx/zip
--no-stringsНе выполняет проход strings по бинарным файлам
--no-largeПропускает файлы больше --max-size вместо чтения блоками
--jobs NРабочие процессы (по умолчанию: авто)
--max-size MBПропускает файлы больше этого размера (по умолчанию 25)
--port NПорт UI (по умолчанию 8973)
КлавишаДействие
j / kследующая / предыдущая находка
↑ / ↓расширить контекст вверх / вниз
c / fподтвердить / пометить ложным срабатыванием
xпереключить выбор для массового триажа
o / nоткрыть в VS Code на строке / открыть файл в Блокноте
rсоздать правило из выделенного текста
yскопировать значение
/поиск
  • Никакого перечисления общих ресурсов. Укажите ему путь, который у вас уже есть. Поиск открытых общих ресурсов - задача другого инструмента.
  • .doc/.xls/.pdf (до 2007 года и PDF) обрабатываются проходом по строкам, а не настоящим парсером, поэтому полнота обнаружения для них ниже, чем для форматов OOXML.