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

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

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

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

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

Категории

Все категории
Loading categories
phantomstars — Автоматическое обнаружение и отслеживание фальшивой активности на GitHub — ежедневный CI, без инфраструктуры | Kitploit
Инструменты/GitHubGitHub/tg12/phantomstars
OSINT (Разведка открытых источников)РазведкаСкриптинг и автоматизацияСбор информацииРазведка угрозОбучение и ОбразованиеКраулерПодобранные РесурсыАнти-Бот
GitHubtg12/phantomstars

phantomstars

Автоматическое обнаружение и отслеживание фальшивой активности на GitHub — ежедневный CI, без инфраструктуры

74342 месяцев назадПроверено Kitploit

Популярное

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

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

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

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

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

phantomstars Python 3.13 Apache 2.0 GitHub Actions Daily

phantomstars

Автоматическое обнаружение и отслеживание накрутки активности на GitHub

Проект JS Labs — часть инициативы AI Slop Intelligence.
Запускается каждый день. Оценивает каждый подозрительный аккаунт. Обнаруживает скоординированные бот-кампании.
Открывает issues напрямую в скомпрометированных репозиториях, чтобы мейнтейнеры могли отреагировать.


Поддержите этот проект

BTC   3QjWqhQbHdHgWeYHTpmorP8Pe1wgDjJy54
ETH   0x5851e6145F4773d1585b8686095FB16E368a4dA1
ZEC   t1KSR5YkNPbjqRSCoLKo5AddFWdm9Kzxh1B


Зачем это существует

Звёзды GitHub — это сигнал доверия. По ним разработчики решают, что оценивать, от чего зависеть и что рекомендовать. Этот сигнал систематически портится.

Во время ИИ-бума 2024–2026 годов появилась индустрия ферм ботов, создающих видимость надёжности для низкокачественных, часто вредоносных репозиториев. Проект с 800 звёздами за 48 часов выглядит легитимным для разработчика, просматривающего результаты поиска. В этом и смысл. Цель накрутки — не сами звёзды, а социальное доказательство, которое они создают, и последующие решения, на которые это доказательство влияет.

Закономерность легко распознать. Аккаунты, созданные на одной неделе, без био, без подписчиков, без собственных репозиториев, ставящие звёзды одним и тем же 15 репозиториям в течение двух часов. Не одна кампания, а десятки, работающие одновременно, каждый день, через тысячи аккаунтов. Данные показывают репозитории, где 185 из 185 вовлечённых — боты. 100% фальшивки. Целые позиции в трендах построены на пустоте.

phantomstars был создан, потому что эта задача решаема. Соотношение сигнала и шума в публичном API GitHub пока ещё достаточно высокое, чтобы скоординированные кампании оставляли чёткие отпечатки. Этот проект считывает эти отпечатки, публикует сырые данные и напрямую уведомляет мейнтейнеров затронутых репозиториев.

Это часть более широкой работы AI Slop Intelligence в JS Labs — продолжающегося исследования механизмов и измеримых последствий низкокачественного ИИ-контента, заполоняющего экосистему разработчиков. Накрутка — не периферийная проблема. Это механизм распространения, который доставляет мусорный контент реальным пользователям.


Что он делает

phantomstars запускает ежедневное задание GitHub Actions, которое:

  1. Парсит страницу GitHub Trending в поисках репозиториев, набирающих звёзды сегодня
  2. Запрашивает GitHub Search API для репозиториев, созданных за последние 7 дней с внезапной звёздной активностью (более широкое окно ловит многодневные кампании, пропущенные 24-часовыми сканами)
  3. Добавляет дополнительные репозитории-кандидаты из недавних постов Reddit в r/osinttools и r/coolgithubprojects, извлекая ссылки на GitHub-репозитории за последние 2 дня
  4. Получает недавние события вовлечённости (звёзды, форки) через Events API (последние 24 часа на репозиторий)
  5. Загружает полный профиль каждого вовлечённого аккаунта через GraphQL: дату создания аккаунта, количество подписчиков/подписок, био, историю репозиториев
  6. Оценивает каждый аккаунт по композитной модели эвристик: возраст аккаунта, полнота профиля, паттерны репозиториев и история активности
  7. Обнаруживает скоординированные кампании с помощью кластеризации по времени и union-find: кластеры подозрительных аккаунтов, вовлечённых в течение 3-часового окна
  8. Применяет список исключений для ложных срабатываний перед записью в журнал, расчётом долей по репозиториям, дашбордами и уведомлениями, чтобы каждая видимая метрика использовала одну и ту же совокупность
  9. Добавляет всех подозреваемых в append-only JSONL-журнал, фиксируемый в этом репозитории
  10. Публикует аналитическую ленту по каждому репозиторию, показывающую, какие репозитории атакуются, какие источники обнаружения их нашли и было ли окно Events API полным или ограниченным
  11. Открывает issues напрямую в целевых репозиториях, чтобы мейнтейнеры видели данные кампании в своём трекере
  12. Записывает форматированный отчёт сканирования в сводку задания GitHub Actions

Никаких серверов. Никаких баз данных. Никаких расходов на инфраструктуру.


Часто задаваемые вопросы

Уведомляет ли он целевой репозиторий?

Да. Когда доля накрутки репозитория превышает 40% или обнаружена скоординированная кампания, phantomstars открывает issue прямо в этом репозитории. Issue содержит полную таблицу подозреваемых, состав кампании, композитные оценки и даты создания аккаунтов: всё, что нужно мейнтейнеру для расследования и обращения в GitHub.

Если в целевом репозитории отключены issues, уведомление молча пропускается и фиксируется в журнале сканирования.

Можно ли запросить проверку конкретного репозитория?

Да.

  • Для обычной разовой проверки укажите репозиторий в форме owner/repo и запустите таргетированное сканирование.
  • Для пожизненного аудита используйте разовый режим полного анализа. Он отделён от ежедневного сканирования.

Почему такое разделение:

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

Можно ли сообщить о ложном срабатывании?

Да. Если ваш аккаунт появился в data/suspects.jsonl и вы считаете классификацию неверной, откройте issue о ложном срабатывании, используя предоставленный шаблон. Сообщения проверяются вручную перед добавлением в список исключений. Список исключений хранится в data/allowlist.txt; аккаунты из него исключаются из всех будущих сканов и из журнала подозреваемых.

Что такое ID кампании?

ID кампании (например, c-a3f9b2e1) — это детерминированный 8-символьный шестнадцатеричный отпечаток, полученный из SHA-256 хеша отсортированного набора логинов участников этой кампании. Одна и та же группа аккаунтов будет давать один и тот же ID кампании при независимых запусках сканирования, что позволяет отслеживать динамику. Это не имя репозитория, не имя пользователя и не внешний идентификатор.

Стабильность: ID стабилен, пока набор участников кампании не меняется. Если боты добавлены или заблокированы между сканами, ID меняется, потому что изменился состав. Это ожидаемо и отражает реальное изменение состава бот-ферм.

Проверяет ли он даты создания аккаунтов?

Да. Дата создания каждого аккаунта берётся из GitHub GraphQL API (поле createdAt) и сохраняется в каждой записи подозреваемого как account_created_at. Это также основной вход для оценки возраста аккаунта — самого сильного сигнала для фейковых аккаунтов. Аккаунты, созданные в течение 2 дней до вовлечённости, получают 1.0 только за возраст.

Насколько он уверен?

Индивидуальные оценки несут значимый уровень ложных срабатываний. Новый разработчик с незаполненным профилем легитимно получает 0.75+. Инструмент учитывает это, требуя доказательств уровня кампании перед открытием issues; одного подозрительного аккаунта недостаточно. Скоординированный кластер из 40+ аккаунтов, созданных на одной неделе, с оценками 0.75+, вовлечённых в течение 90 минут, — это другое дело. Вот где уверенность становится применимой на практике.

Данные всегда вероятностные. Об этом прямо сказано в тексте issues. Цель — дать мейнтейнерам сигнал и сырые доказательства для собственного решения.


Живой дашборд


Самые атакуемые репозитории сегодня


Модель оценки

Каждый аккаунт получает композитную оценку подозрительности (0.0 = чисто, 1.0 = вероятно фейк) по четырём сигналам:

Пороги классификации:

ОценкаКлассификация
≥ 0.75likely_fake
≥ 0.45suspicious
< 0.45clean (не сохраняется)

Обнаружение кампаний

Кампания — это группа из ≥ 4 подозрительных аккаунтов, которые все взаимодействовали с одним и тем же репозиторием в течение 3-часового окна. Алгоритм использует union-find для построения связных компонентов; аккаунты, взаимодействовавшие в пределах окна, объединяются, и любой компонент, превышающий минимальный размер, помечается как скоординированная кампания.

ID кампаний — стабильные SHA-256 отпечатки отсортированного набора участников. Одна и та же кампания, обнаруженная в последующие дни, будет иметь тот же ID, пока состав не изменился.

Почему кампании — настоящий сигнал: Индивидуальные оценки имеют значимый уровень ложных срабатываний. Новый разработчик с незаполненным профилем может получить 0.80 в одиночку. Сорок аккаунтов с оценками 0.75+, созданных на одной неделе и ставящих звёзды одному репозиторию в течение 90 минут, — это не совпадение. Сигнал кампании — это место, где данные становятся применимыми на практике: разница между подозрительной точкой данных и доказательством скоординированной операции.


Формат данных

Все находки фиксируются в data/suspects.jsonl и data/repos.jsonl — по одной JSON-записи на строку, только добавление. Сводка задания GitHub Actions (видна в UI Actions после каждого запуска) предоставляет форматированный отчёт по каждому сканированию.

suspects.jsonl — одна запись на каждый помеченный аккаунт за каждое сканирование:```json { "login": "user98432", "account_age_score": 0.9, "profile_score": 0.8, "repo_pattern_score": 0.8, "activity_score": 0.85, "composite": 0.842, "classification": "likely_fake", "campaign_id": "c-a3f9b2e1", "scan_date": "2026-05-17", "account_created_at": "2026-05-15", "target_repos": ["owner/repo-a", "owner/repo-b"] }

root@kitploit:~
**repos.jsonl** — одна запись на каждый целевой репозиторий за каждое сканирование:```json
{
  "full_name": "owner/suspicious-repo",
  "total_scanned": 87,
  "likely_fake": 62,
  "suspicious": 18,
  "known_likely_fake": 27,
  "known_likely_fake_ratio": 0.310,
  "repeat_offenders": 11,
  "allowlisted_excluded": 3,
  "fakeness_ratio": 0.713,
  "classification": "likely_fake",
  "campaign_count": 3,
  "discovery_sources": ["github_search_recent", "reddit_osinttools"],
  "event_sample_complete": false,
  "scan_date": "2026-05-17"
}

Примеры запросов:```bash

All likely_fake accounts from today

jq 'select(.scan_date == "2026-05-17" and .classification == "likely_fake") | .login' data/suspects.jsonl

Accounts created in the last 3 days that were flagged

jq 'select(.account_created_at >= "2026-05-14") | [.login, .account_created_at, .classification] | @tsv' -r data/suspects.jsonl

Which repos were targeted today, sorted by fakeness ratio

jq 'select(.scan_date == "2026-05-17") | [.full_name, .fakeness_ratio, .likely_fake] | @tsv' -r data/repos.jsonl | sort -t$'''\t''' -k2 -rn

Repos with the highest recycled-bot share from previously seen likely_fake accounts

jq 'select(.scan_date == "2026-05-17") | [.full_name, .known_likely_fake_ratio, .repeat_offenders] | @tsv' -r data/repos.jsonl | sort -t$'''\t''' -k2 -rn

All members of a specific campaign

jq 'select(.campaign_id == "c-a3f9b2e1") | [.login, .account_created_at, .composite] | @tsv' -r data/suspects.jsonl

Repos a specific account targeted

jq 'select(.login == "user98432") | .target_repos[]' data/suspects.jsonl

High-confidence repos: fakeness ratio above 60%

jq 'select(.fakeness_ratio >= 0.6) | [.full_name, .fakeness_ratio, .campaign_count] | @tsv' -r data/repos.jsonl | sort -t$'\t' -k2 -rn

root@kitploit:~
---

## Настройка

### 1. Сделайте форк этого репозитория

Ваш форк владеет данными. Результаты после каждого ежедневного запуска коммитятся обратно в `data/suspects.jsonl` и `data/repos.jsonl` в вашем форке.

### 2. Добавьте секрет GitHub PAT

Создайте **классический** персональный токен доступа (Personal Access Token) с областями:
- `public_repo`: чтение событий публичных репозиториев и списков звёзд, создание issues в публичных репозиториях
- `read:user`: получение профилей пользователей через GraphQL

**Настройки &rarr; Секреты и переменные &rarr; Actions &rarr; Новый секрет репозитория** &rarr; назовите его `GH_TOKEN`.

> У `GITHUB_TOKEN` по умолчанию ограничены скоростные лимиты, и он не может вызывать пользовательскую конечную точку GraphQL в полном объёме. Требуется PAT.

### 3. Включите Actions

**Actions &rarr; Включить GitHub Actions** в вашем форке. Рабочий процесс запускается ежедневно в **07:00 по времени Великобритании** с использованием часового пояса `Europe/London`:
- **06:00 UTC** в период британского летнего времени
- **07:00 UTC** в период среднего времени по Гринвичу

Никакая дополнительная переменная окружения для расписания не требуется. Cron в GitHub Actions работает только по UTC, поэтому рабочий процесс срабатывает в оба часа UTC и продолжает выполнение, только когда местное время в Лондоне равно 07:00. Ручной запуск доступен через **Actions &rarr; Daily Phantom Stars Scan &rarr; Запустить рабочий процесс**.

После каждого запуска отформатированный отчёт о сканировании виден в **Actions &rarr; [run] &rarr; Сводка**.

### 4. Запуск локально```bash
git clone https://github.com/YOUR_USERNAME/phantomstars.git
cd phantomstars
python -m venv venv && source venv/bin/activate
pip install -e .
GH_TOKEN=ghp_your_token python -m phantomstars.main

Для разового локального запуска после настройки:```bash GH_TOKEN=ghp_your_token python -m phantomstars.main

root@kitploit:~
Чтобы просканировать один репозиторий вместо обычного набора обнаружения:```bash
PHANTOMSTARS_TARGET_REPO=owner/repo GH_TOKEN=ghp_your_token python -m phantomstars.main

One-off requests

Users can request a one-off repo check in two ways:

  1. Open the Repo Check Request issue template and provide the target repo plus requested depth.
  2. Use Actions -> Daily Phantom Stars Scan -> Run workflow and optionally set:
    • target_repo: owner/repo
    • request_depth: recent or lifetime-request

Current behavior:

  • recent: runs the targeted recent-engagement scan immediately.
  • lifetime-request: runs a targeted lifetime scan across historical stars and forks for that repo only.
  • The daily scheduled scan remains unchanged and continues to use the recent-engagement method.

Guardrails for lifetime mode:

  • only available for explicit one-off targeted requests
  • capped by configured repository-size limits before the scan starts
  • slower and more API-intensive than the daily scan

Структура проекта```

phantomstars/ ├── .github/ │ ├── workflows/daily-scan.yml # Runs daily at 07:00 Europe/London │ └── ISSUE_TEMPLATE/false_positive.yml ├── src/phantomstars/ │ ├── config.py # All constants, no argparse, no env parsing │ ├── models.py # Frozen dataclasses │ ├── github_client.py # REST + GraphQL, tenacity retries, rate-limit aware │ ├── heuristics.py # Per-user composite scoring engine │ ├── campaigns.py # Timestamp clustering + union-find │ ├── storage.py # JSONL append + query helpers │ ├── reporter.py # README dashboard injector │ ├── notifier.py # GitHub Issues notifier (files on targeted repos) │ └── main.py # Orchestration entry point ├── tests/ │ ├── conftest.py │ ├── test_heuristics.py │ └── test_campaigns.py ├── data/ │ ├── suspects.jsonl # Append-only account findings ledger │ ├── repos.jsonl # Append-only per-repo intelligence │ └── allowlist.txt # Accounts excluded from future scans └── pyproject.toml

root@kitploit:~
---

## Ограничения и известные сценарии отказов

- **Ограничение Events API:** максимум 300 последних событий на репозиторий. Репозитории с тысячами звёзд в день имеют частичное покрытие.
- **Флаг покрытия:** репозитории, достигшие лимита в 300 событий, помечаются как `capped` в отчётах и дашбордах; показатели по этим репозиториям являются консервативными выборками, а не полнодневными подсчётами.
- **Задержка поискового индекса:** поисковый индекс GitHub в конечном счёте консистентен. Репозитории, созданные за секунды до границы сканирования, могут быть пропущены.
- **Дрейф эвристик:** операторы ботов адаптируются. Веса оценок могут требовать периодической настройки; отрегулируйте константы в `config.py`.
- **Индивидуальные ложные срабатывания:** новый разработчик с неполным профилем в изоляции набирает 0.75+. Членство в кампании — сигнал высокой уверенности.
- **Дрейф ID кампании:** если состав бот-фермы меняется между сканированиями (боты заблокированы, добавлены новые боты), ID кампании изменяется. Это отражает реальную эволюцию кампании, а не ошибку.
- **Лимиты API:** 5 000 запросов в час на аутентифицированный PAT. С большим запасом укладывается в лимиты для стандартных размеров страниц трендов.
- **Отключённые issues:** некоторые целевые репозитории отключают issues. Уведомления по этим репозиториям молча пропускаются.

---

## Процесс обработки ложных срабатываний

Если ваш аккаунт появился в `data/suspects.jsonl` и вы считаете, что он классифицирован неверно:

1. Найдите свою запись: `jq 'select(.login == "YOUR_LOGIN")' data/suspects.jsonl`
2. [Откройте issue о ложном срабатывании](../../issues/new?template=false_positive.yml) с указанием вашего логина, классификации, даты сканирования и объяснения
3. Отчёты проверяются вручную. Подтверждённые ложные срабатывания добавляются в `data/allowlist.txt` и исключаются из всех будущих сканирований, показателей репозиториев и уведомлений об issues.

Примечание: открытие issue не изменяет и не удаляет существующие данные. Журнал подозреваемых — только на добавление. Список исключений влияет только на будущие сканирования.

---

## Внесение вклада```bash
pip install -e ".[dev]"
python -m black .
python -m ruff check .
python -m mypy src
python -m pytest

All four must pass before a PR.


Отказ от ответственности

Этот инструмент выполняет анализ только для чтения публичных данных GitHub с использованием официального GitHub API. Когда на целевых репозиториях открываются issue, они содержат вероятностные результаты и явно помечены как автоматические. Находки — это индикаторы, а не обвинения. Ложные срабатывания существуют, и это ожидаемо.

Создан с использованием ИИ в качестве партнёра по программированию, в ответ на проблему экосистемы, частично созданную ИИ.


Лицензия

Apache 2.0. См. LICENSE


Автор

Создано tg12 · GitHub

Проект JS Labs · AI Slop Intelligence Dashboards

Скачать инструмент
ДатаПровереноВероятно фейкПодозрительныеКампанииНовые фейки (24ч)
2026-06-161846221162556190
2026-06-152274418185661397
2026-06-141953355159844310
2026-06-132012301171147251
2026-06-122298336196257300
2026-06-111957385157242356
2026-06-102043687135650665
2026-06-092199690150944632
2026-06-081913450146350424
2026-06-071797658113930618
2026-06-062625712191340620
2026-06-052403673173053617
2026-06-042237441179641367
2026-06-032331488184353431
2026-06-022795773202237616
2026-06-012490533195739355
2026-05-312302458184432280
2026-05-302576530204620356
2026-05-292838733210542369
2026-05-282748694205439396
2026-05-272193560163332491
2026-05-261930236169443190
2026-05-251526214131232158
2026-05-242170358181239265
2026-05-232548426212243317
2026-05-222318340197847247
2026-05-211981348163325277
2026-05-201613268134523163
2026-05-195463630412167442
2026-05-1888386707950128340
РепозиторийВовлеченоВероятно фейкИзвестный фейк %Накрутка %КампанииОхватИсточники
freeCodeCamp/freeCodeCamp264260.0%9.8%1полныйgithub_trending
Lolner95/use-kimi-on-cursor1161726.7%14.7%1полныйgithub_search_recent
zmustafa/AzureSupportAgent331636.4%48.5%1полныйgithub_search_recent
Free-TV/IPTV291140.3%4.8%1полныйgithub_trending
Panniantong/Agent-Reach292140.3%4.8%1ограниченgithub_trending
jwasham/coding-interview-university288120.3%4.2%1ограниченgithub_trending
Alex-Shayo/bakkes-mod-install37100.0%27.0%1полныйgithub_search_recent
Timgt86/yt-downloader-savetube37100.0%27.0%1полныйgithub_search_recent
devassisthub/Zelda-TP-PC-Port3590.0%25.7%1полныйgithub_search_recent
imohammedyasin/steam-tools3590.0%25.7%1полныйgithub_search_recent
lol-toolkit/ltk-manager-lol3590.0%25.7%1полныйgithub_search_recent
tor-browser-download/tor-browser3690.0%25.0%1полныйgithub_search_recent
claude-code-ai-anthropic/free-claude-code-ai-desktop-app3890.0%23.7%1полныйgithub_search_recent
vitaliikapliuk/modelharness60931.7%15.0%1полныйgithub_search_recent
shiyu-coder/Kronos28291.1%3.2%1полныйgithub_trending
snanas/Forza-Horizon-Spotify-Radio3480.0%23.5%1полныйgithub_search_recent
bingook/bingo4582.2%17.8%2полныйgithub_search_recent
darricke/claude-fable-5-desktop-free4980.0%16.3%1полныйgithub_search_recent
Ponzuu84/MaaNTE3270.0%21.9%1полныйgithub_search_recent
iDesignStudioz/yellowkey-bitlocker3370.0%21.2%1полныйgithub_search_recent
chatwoot/chatwoot23070.0%3.0%1полныйgithub_trending
Open-Builders/pumpfun-bundler-pump.fun-bundler-solana-token-bundler-bot18633.3%33.3%1полныйgithub_search_recent
taisly/agent23617.4%26.1%2полныйgithub_search_recent
iptv-org/iptv19360.0%3.1%1полныйgithub_trending
itsfatduck/optimizerDuck29360.3%2.0%1полныйgithub_trending
СигналВесИзмерение
Возраст аккаунта35%< 2 дня → 1.00 · < 7 дней → 0.90 · < 30 дней → 0.55 · < 90 дней → 0.20 · старше → 0.00
Полнота профиля30%Баллы за: нет био (+0.25), нет локации (+0.15), нет компании (+0.10), ноль подписчиков (+0.30), ноль подписок (+0.10), имя-паттерн бота (+0.20)
Паттерн репозиториев25%Ноль репозиториев → 0.90 · все репозитории — форки → 0.80 · доля форков >85% → 0.55
История активности10%Аккаунты старше 14 дней с нулём репозиториев и нулевым социальным графом → 0.80 (аккаунты-призраки). Только ноль репозиториев → 0.60. Все форки + нет социального графа → 0.50