July 7

Анализ репозиториев кода: GitHub, GitLab, Bitbucket — поиск секретов, утечек кода

Анализ репозиториев кода: GitHub, GitLab, Bitbucket — поиск секретов, утечек кода

Публичные репозитории кода — это один из наиболее недооцененных, но богатых источников информации в техническом OSINT. Разработчики часто случайно загружают в открытые репозитории конфиденциальные данные: API-ключи, пароли, токены, внутренние URL, логины к базам данных, комментарии с внутренней информацией и даже дампы баз данных. Для специалиста по разведке анализ репозиториев позволяет не только найти чувствительные данные, но и восстановить внутреннюю архитектуру, выявить используемые технологии и даже получить доступ к закрытым системам. Данная статья посвящена методам поиска секретов и утечек кода в публичных репозиториях GitHub, GitLab, Bitbucket и других платформах.

Почему публичные репозитории опасны для организации?

Основные платформы для поиска кода

Этап 1: Базовый поиск на GitHub

GitHub предоставляет мощную поисковую систему с операторами. Поиск можно выполнять как через веб-интерфейс, так и через API.

Основные операторы GitHub:

Примеры поисковых запросов:

  • Поиск ключей AWS: "AKIA" "SECRET" extension:txt
  • Поиск паролей: password extension:env
  • Поиск токенов GitHub: "ghp_" extension:txt
  • Поиск конфигов: filename:.env
  • Поиск SSH-ключей: "BEGIN RSA PRIVATE KEY"
  • Поиск по домену компании: "example.com" "password"

Использование GitHub API для поиска:

import requests

GITHUB_TOKEN = "YOUR_TOKEN"
headers = {
    "Authorization": f"token {GITHUB_TOKEN}",
    "Accept": "application/vnd.github.v3+json"
}

def search_github(query):
    url = "https://api.github.com/search/code"
    params = {
        "q": query,
        "per_page": 10
    }
    response = requests.get(url, headers=headers, params=params)
    if response.status_code == 200:
        return response.json()
    else:
        print(f"Ошибка: {response.status_code}")
        return None

# Поиск .env файлов в организации example
results = search_github("extension:env org:example")
if results:
    for item in results.get('items', []):
        print(f"{item['repository']['full_name']}: {item['path']}")

Этап 2: Поиск секретов с использованием TruffleHog

TruffleHog — это специализированный инструмент для поиска секретов в репозиториях. Он анализирует историю коммитов, а не только текущие файлы, и использует детекторы для различных типов секретов.

Установка и использование:

# Установка через pip
pip install trufflehog

# Сканирование репозитория по URL
trufflehog git https://github.com/example/repo.git

# Сканирование всей организации (требуется токен)
trufflehog github --org=example --token=GITHUB_TOKEN

Пример вывода:

🐷🔑🐷  TruffleHog. Unearth your secrets. 🐷🔑🐷

2024-01-15 10:30:45    INFO    Detector Name: AWS
2024-01-15 10:30:45    INFO    Commit: 3a4b5c6d7e8f9...
2024-01-15 10:30:45    INFO    File: config/credentials.yml
2024-01-15 10:30:45    INFO    Line: 12
2024-01-15 10:30:45    INFO    Secret: AKIAXXXXXXXXXXXXXXXX

Этап 3: Использование GitRob и GitGrab для поиска по организациям

GitRob — утилита для поиска ключей и паролей в репозиториях GitHub организаций.

gitrob example

GitGrab — аналогичный инструмент, фокусирующийся на поиске конфигурационных файлов.

Этап 4: Поиск по расширениям файлов

Поиск на GitHub через веб-интерфейс:

extension:env org:example
extension:yml "password" org:example
extension:json "api_key" org:example

Этап 5: Поиск по строковым шаблонам секретов

Регулярные выражения помогают находить секреты по их формату.

Типичные паттерны:

Пример скрипта для поиска по паттернам в скачанном репозитории:

import re
import os
import fnmatch

patterns = {
    'aws': re.compile(r'AKIA[0-9A-Z]{16}'),
    'github': re.compile(r'ghp_[0-9a-zA-Z]{36}'),
    'slack': re.compile(r'xox[bap]-[0-9a-zA-Z-]+'),
    'ssh': re.compile(r'-----BEGIN (RSA|OPENSSH|DSA|EC) PRIVATE KEY-----'),
}

def scan_file(filepath):
    try:
        with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read()
            for name, pattern in patterns.items():
                matches = pattern.findall(content)
                if matches:
                    print(f"{filepath}: {name} -> {matches[:3]}")
    except:
        pass

def scan_repo(repo_path):
    for root, dirs, files in os.walk(repo_path):
        for file in files:
            scan_file(os.path.join(root, file))

# Сканирование локального клона репозитория
scan_repo('/path/to/cloned/repo')

Этап 6: Поиск через PublicWWW

PublicWWW — поисковая система, индексирующая HTML, CSS и JavaScript. Можно искать по строкам, которые появляются в коде веб-страниц.

Использование:

https://publicwww.com/websites/%22AKIA%22/

ищет не только код в репозиториях, но и во всех открытых веб-страницах.

Этап 7: Поиск через SearchCode

SearchCode агрегирует данные из GitHub, Bitbucket, GitLab и других источников. У него есть API.

# Поиск через веб-интерфейс
https://searchcode.com/?q=AKIA&p=2

Этап 8: Мониторинг новых утечек через GitHub

Новые утечки появляются постоянно. Важно настроить мониторинг на появление новых файлов с секретами.

Инструменты для мониторинга:

  • GitHub Watch — подписка на изменения в репозиториях (вручную).
  • HawkScan — автоматическое сканирование новых коммитов в организациях.
  • LeakIX — поисковик утечек, отправляет уведомления.

Собственный мониторинг через GitHub API:

def monitor_new_commits(org, last_check_file):
    # Получение последних коммитов в организации
    # Сравнение с предыдущим состоянием
    # При обнаружении секретов — уведомление
    pass

Этап 9: Анализ истории коммитов (продвинутый уровень)

Git сохраняет историю изменений. Даже если секрет был удалён в последнем коммите, он может остаться в истории.

Поиск в истории через TruffleHog: (см. выше) сканирует всю историю.

Поиск в локально скачанном репозитории:

# Поиск по всем коммитам в Git
git log -p | grep -i "password"
git log -p | grep -i "AKIA"
git log -p | grep -i "ghp_"

Этап 10: Восстановление удалённых файлов из истории Git

Даже если файл был удалён, он может быть восстановлен через Git.

# Поиск файла в истории
git log --all --full-history -- "*config*"

# Восстановление файла
git show <commit_hash>:path/to/file

Этап 11: Поиск в GitLab и Bitbucket

GitLab: общедоступные проекты можно искать через поиск GitLab. Операторы: group:, project:.

Пример: https://gitlab.com/search?search=password&group_id=123

Bitbucket: аналогично, через поиск или API.

Сводная таблица инструментов поиска секретов

  • Никогда не используйте найденные секреты для несанкционированного доступа. Это уголовное преступление.
  • Если вы нашли секреты, принадлежащие организации, сообщите им через официальные каналы (security@example.com) или через программу Bug Bounty.
  • Не распространяйте найденные секреты публично.
  • При сканировании соблюдайте условия использования платформ (GitHub, GitLab) — чрезмерные запросы могут привести к блокировке IP.
  • В некоторых юрисдикциях даже поиск секретов может считаться нарушением, если он ведётся без разрешения. Ориентируйтесь на публичные данные.

Практический пример: расследование утечки токенов

Задача: найти все токены, связанные с организацией example.com, и проинформировать их.

  1. GitHub Search: "example.com" "token" extension:env → найдено 3 файла .env с токенами для Stripe, AWS и Slack.
  2. TruffleHog: сканирование организации example → обнаружен AWS-ключ в старом коммите (уже удалённом из кода, но оставшемся в истории).
  3. PublicWWW: поиск "AKIA" "example.com" → найден HTML-файл со скриптом, содержащим Google Maps API ключ.
  4. Связь: ключи принадлежат компании example.com (проверено по домену в комментариях).
  5. Сообщение: отправка письма на security@example.com с перечнем найденных токенов и рекомендацией по их отзыву и ротации.
  6. Результат: компания подтвердила получение, отозвала скомпрометированные ключи, обновила политику безопасности.

Анализ публичных репозиториев кода — один из самых результативных методов технического OSINT. Комбинация GitHub-поиска с операторами, специализированных инструментов (TruffleHog, GitRob) и анализа истории коммитов позволяет находить секреты, пароли и утечки кода, которые случайно попали в открытый доступ. Важно использовать полученную информацию ответственно и этично: сообщать о находках владельцам, а не использовать их для атак.