Files
reverse-skills-max/research-what-we-did/darktelegram_reverse.py

661 lines
25 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
DarkTelegram.pro — полный реверс
SaaS-облачный комбайн для автоматизации Telegram.
Python/FastAPI backend, React SPA фронт, Cloudflare Turnstile, облачное 24/7 исполнение.
Auth: email+password, Google OAuth, Telegram OAuth
Тарифы: Start $49/20 акк, Pro $70/100 акк, Ultra $130/1000 акк
Модули à la carte: $15-50/мес
"""
from dataclasses import dataclass, field
from typing import Optional
from enum import StrEnum
# === API ENDPOINTS (извлечены из App-DL7CzC9q.js, 663KB) ===
API_BASE = "https://darktelegram.pro/api"
ENDPOINTS = {
# Auth
"login": "POST /api/auth/login",
"register": "POST /api/auth/register",
"register_verify": "POST /api/auth/register/verify",
"register_resend": "POST /api/auth/register/resend",
"refresh": "POST /api/auth/refresh",
"forgot_password": "POST /api/auth/forgot-password",
"reset_password": "POST /api/auth/reset-password",
"google_oauth": "GET /api/auth/google",
"telegram_oauth_init": "POST /api/auth/telegram/init",
"auth_config": "GET /api/auth/config",
"me": "GET /api/auth/me",
# Аккаунты
"accounts_add": "POST /api/accounts/add",
"accounts_add_tdata": "POST /api/accounts/add-tdata",
"accounts_summary": "GET /api/accounts/summary",
"accounts_trust": "GET /api/accounts/trust",
"accounts_batch_task": "POST /api/accounts/batch-task",
"accounts_batch_purpose": "POST /api/accounts/batch-purpose",
"accounts_batch_move": "POST /api/accounts/batch-move-folder",
"accounts_bulk_edit": "POST /api/accounts/bulk-edit",
"accounts_bulk_delete": "POST /api/accounts/bulk-delete",
"accounts_bulk_assign_proxy":"POST /api/accounts/bulk-assign-proxy",
"accounts_bulk_force_reset":"POST /api/accounts/bulk-force-reset",
"accounts_confirm": "POST /api/accounts/confirm/:id",
"accounts_counts": "GET /api/accounts/counts/sparkline",
# phone-auth flow
"phone_send_code": "POST /api/accounts/phone-auth/send-code",
"phone_resend_code": "POST /api/accounts/phone-auth/resend-code",
"phone_sign_in": "POST /api/accounts/phone-auth/sign-in",
"phone_submit_captcha": "POST /api/accounts/phone-auth/submit-captcha",
# Прокси
"proxies": "GET /api/proxies",
"proxies_by_country": "GET /api/proxies/by-country",
"proxies_batch_check": "POST /api/proxies/batch-check",
"proxies_batch_folder": "POST /api/proxies/batch-folder",
"proxy_folders": "GET /api/proxy-folders",
"proxy_health": "GET /api/proxy-health",
# Магазин прокси
"proxy_shop_buy": "POST /api/proxy-shop/buy",
"proxy_shop_prolong": "POST /api/proxy-shop/prolong-local",
"proxy_shop_prolong_price": "GET /api/proxy-shop/prolong-price",
"proxy_shop_price": "GET /api/proxy-shop/price",
"proxy_shop_balance": "GET /api/proxy-shop/balance",
"proxy_shop_countries": "GET /api/proxy-shop/countries",
"proxy_shop_count": "GET /api/proxy-shop/count",
"proxy_shop_disclaimer": "GET /api/proxy-shop/disclaimer",
# Подписка / биллинг
"subscribe_active": "GET /api/subscribe/active",
"subscribe_start": "POST /api/subscribe/start",
"subscribe_status": "GET /api/subscribe/status/:id",
"subscribe_cancel": "POST /api/subscribe/cancel/:id",
# AI / Задачи
"ai_submit": "POST /api/ai/:task_type",
"auto_warmup": "POST /api/auto-warmup/:id",
"task_history": "GET /api/task-history/accounts/:id",
# AI пресеты
"ai_presets_prompts": "GET /api/ai-presets/prompts",
"ai_presets_photos": "GET /api/ai-presets/photos",
# Каналы
"channel_create_copy": "POST /api/channel-create/copy-post",
"channel_create_acc": "GET /api/channel-create/account/:id",
"channel_templates": "GET /api/channel-create/templates",
"channel_views_check": "POST /api/channel-views/check-unchecked",
# Истории
"story_repost_preview": "GET /api/story-repost/preview",
"story_repost_viewers": "GET /api/story-repost/viewers",
# Профили / посты
"profile_presets_list": "GET /api/profile-presets/list",
"profile_presets_random":"GET /api/profile-presets/random",
"profile_templates": "GET /api/profile-templates",
"profile_templates_bios":"GET /api/profile-templates/bios",
"profile_templates_names":"GET /api/profile-templates/names",
"profile_photos_upload": "POST /api/profile-templates/photos/upload",
"profile_photos_b64": "GET /api/profile-templates/photos/b64",
"post_templates": "GET /api/post-templates",
# Сессионный дубликатор
"session_duplicate": "POST /api/session-duplicator/:id",
"session_download": "GET /api/session-duplicator/download/:id",
"session_sessions": "GET /api/session-duplicator/sessions/:id",
"session_switch": "POST /api/session-duplicator/switch/:id",
# Остальное
"workspaces": "GET /api/workspaces",
"workspaces_active": "POST /api/workspaces/active",
"workspaces_move": "POST /api/workspaces/move",
"account_folders": "GET /api/account-folders",
"all_status": "GET /api/all-status",
"currency_rate": "GET /api/currency/rate",
"links_channels": "GET /api/links/channels",
"notifications": "GET /api/notifications",
"notifications_read": "POST /api/notifications/read-all",
"emoji_file": "GET /api/emoji/file/:id",
"team_context": "GET /api/team/context",
}
# === ТАРИФЫ ===
class Tariff(StrEnum):
START = "start" # $49/мес, 20 акков
PRO = "pro" # $70/мес, 100 акков
ULTRA = "ultra" # $130/мес, 1000 акков
TARIFFS = {
"start": {"price": 49, "accounts": 20, "ai_tokens": 0},
"pro": {"price": 70, "accounts": 100, "ai_tokens": 75}, # +$7.5
"ultra": {"price": 130, "accounts": 1000, "ai_tokens": 200}, # +$20
}
MODULES = {
"neuro_commenting": {"price": 30, "tariff": None},
"parser": {"price": 20, "tariff": None},
"neuro_dialogs": {"price": 30, "tariff": "pro"},
"ai_salesman": {"price": 50, "tariff": "pro"},
"mass_reactions": {"price": 18, "tariff": None},
"mass_looking": {"price": 23, "tariff": None},
"grabber": {"price": 25, "tariff": None},
"story_mentions": {"price": 40, "tariff": "ultra"},
"inviter": {"price": 25, "tariff": "pro"},
"ai_broadcast_chats": {"price": 20, "tariff": "start"},
"ai_broadcast_dm": {"price": 20, "tariff": "pro"},
"ai_autoresponder": {"price": 30, "tariff": "pro"},
"telegram_web": {"price": 20, "tariff": "start"},
"own_api_keys": {"price": 15, "tariff": None},
}
# === ФУНКЦИИ (реконструированы из JS-бандлов и лендинга) ===
@dataclass
class Account:
"""Модель аккаунта в системе"""
id: int
phone: str = ""
username: str = ""
status: str = "active" # active | spamblock | banned | frozen
trust_score: int = 0
proxy_id: Optional[int] = None
folder_id: Optional[int] = None
purpose: str = "" # mailing | commenting | warming | etc
last_warmup: Optional[str] = None
session_file: Optional[str] = None # .session path
tdata_path: Optional[str] = None # tdata path
@dataclass
class ProxyConfig:
"""Прокси для аккаунта"""
id: int
type: str = "socks5" # socks5 | http
host: str = ""
port: int = 1080
username: str = ""
password: str = ""
country: str = ""
ip_version: str = "ipv4"
# --- Аккаунты ---
def account_add_session(session_file: str, proxy_id: Optional[int] = None) -> Account:
"""Добавить аккаунт из .session файла"""
# POST /api/accounts/add multipart: file=session_file, proxy_id=proxy_id
...
def account_add_tdata(tdata_zip: str) -> Account:
"""Добавить аккаунт из tdata.zip"""
# POST /api/accounts/add-tdata multipart: file=tdata_zip
...
def account_phone_auth(phone: str, proxy_id: Optional[int] = None) -> dict:
"""
Авторизация по номеру телефона (3-шаговый flow):
1. POST /api/accounts/phone-auth/send-code {phone, proxy_id} → phone_code_hash
2. POST /api/accounts/phone-auth/sign-in {phone, phone_code_hash, code}
3. Если капча: POST /api/accounts/phone-auth/submit-captcha {password}
"""
...
def account_confirm(account_id: int) -> bool:
"""Подтвердить аккаунт (после добавления)"""
# POST /api/accounts/confirm/:id
...
def account_bulk_edit(account_ids: list[int], fields: dict) -> bool:
"""Массовое редактирование полей аккаунтов"""
# POST /api/accounts/bulk-edit {ids, ...fields}
...
def account_bulk_assign_proxy(account_ids: list[int], proxy_id: int) -> bool:
"""Привязать прокси к группе аккаунтов"""
# POST /api/accounts/bulk-assign-proxy
...
def account_batch_purpose(account_ids: list[int], purpose: str) -> bool:
"""Назначить purpose аккаунтам (mailing/commenting/etc)"""
# POST /api/accounts/batch-purpose
...
def account_get_trust(account_id: int) -> dict:
"""Trust Score аккаунта (0-100)"""
# GET /api/accounts/trust
...
def account_get_summary() -> dict:
"""Сводка по аккаунтам: общее кол-во, по статусам"""
# GET /api/accounts/summary
...
def account_get_counts_sparkline() -> list:
"""График изменения количества аккаунтов"""
# GET /api/accounts/counts/sparkline
...
# --- Прокси ---
def proxy_list() -> list[ProxyConfig]:
"""Список своих прокси"""
# GET /api/proxies
...
def proxy_add(host: str, port: int, type_: str = "socks5",
username: str = "", password: str = "") -> ProxyConfig:
"""Добавить прокси"""
# POST /api/proxies
...
def proxy_batch_check(proxy_ids: list[int]) -> dict:
"""Массовая проверка прокси"""
# POST /api/proxies/batch-check
...
def proxy_health() -> dict:
"""Статус прокси-пула"""
# GET /api/proxy-health
...
def proxy_shop_buy(country: str, count: int, period_days: int = 30) -> list[ProxyConfig]:
"""Купить прокси из встроенного магазина"""
# POST /api/proxy-shop/buy
...
def proxy_shop_countries() -> list[str]:
"""Доступные страны для покупки прокси"""
# GET /api/proxy-shop/countries
...
# --- AI Tasks (единый механизм для всех модулей) ---
@dataclass
class AITask:
"""AI задача: рассылка, комментинг, диалог, продажник, автоответ"""
task_type: str # broadcast_chats | broadcast_dm | neuro_commenting |
# neuro_dialogs | ai_salesman | ai_autoresponder
accounts: list[int] # ID аккаунтов
targets: list[str] # @username / ссылки на чаты / номера
ai_preset_id: Optional[int] = None
custom_prompt: str = ""
delay_min: int = 30
delay_max: int = 120
daily_limit: int = 50
# для диалогов
max_messages: int = 5
# для продажника
qualification_criteria: dict = field(default_factory=dict)
notify_telegram: bool = True
def ai_submit_task(task: AITask) -> str:
"""Отправить AI задачу. Возвращает task_id"""
# POST /api/ai/:task_type body: {...}
...
def ai_get_task_status(task_id: str) -> dict:
"""Статус AI задачи"""
# GET /api/task-history/accounts/:task_id
...
def ai_get_presets(preset_type: str = "prompt") -> list[dict]:
"""Получить AI пресеты (промпты или фото)"""
# GET /api/ai-presets/prompts | /api/ai-presets/photos
...
# --- Автопрогрев ---
def auto_warmup_start(account_id: int, config: dict) -> bool:
"""
Запустить автопрогрев аккаунта:
- подписки на каналы
- чтение постов
- реакции
- просмотр историй
- поведенческие паттерны
"""
# POST /api/auto-warmup/:id
...
def auto_warmup_status(account_id: int) -> dict:
"""Статус прогрева: прогресс, trust_score, дата последнего"""
# GET /api/auto-warmup/:id
...
# --- Парсинг ---
@dataclass
class ParseTask:
source_type: str # channel | chat | audience | tgstat
source: str # @username или ссылка
parse_type: str = "members" # members | active | admins
filters: dict = field(default_factory=dict) # country, premium, etc
output_format: str = "csv"
def parse_start(task: ParseTask) -> str:
"""Запустить парсинг. Возвращает task_id"""
# POST /api/ai/parse body: {...}
...
def parse_report(task_id: str) -> list[dict]:
"""Результаты парсинга"""
# GET /api/task-history/accounts/:task_id
...
# --- Нейрокомментинг ---
def neuro_commenting_start(accounts: list[int], channels: list[str],
ai_preset_id: int, delay: tuple[int, int] = (30, 120)) -> str:
"""
ИИ-комментирование:
- Анализирует пост в канале
- Генерирует релевантный комментарий от лица аккаунта
- Постит с задержкой
"""
# POST /api/ai/neuro_commenting
...
# --- Нейродиалоги ---
def neuro_dialogs_start(accounts: list[int], targets: list[str],
ai_preset_id: int, scenario: str = "promote",
max_dialog_msgs: int = 5) -> str:
"""
ИИ находит чаты и рассказывает о продукте в подходящий момент.
Или: заходит в ЛС, ведёт диалог по сценарию.
"""
# POST /api/ai/neuro_dialogs
...
# --- ИИ Продажник ---
def ai_salesman_start(accounts: list[int], targets: list[str],
criteria: dict, notify_telegram_id: str = "") -> str:
"""
3-фазный продажник:
1. Пишет первым каждому из базы
2. Квалифицирует: задаёт вопросы, сверяет с критериями
3. При совпадении — уведомление в Telegram с контактом и историей
"""
# POST /api/ai/ai_salesman
...
# --- ИИ Рассылка ---
def ai_broadcast_chats(accounts: list[int], chats: list[str],
ai_preset_id: int, mode: str = "basic") -> str:
"""
Рассылка по чатам.
mode: basic | multi_phase | postbot
"""
# POST /api/ai/broadcast_chats
...
def ai_broadcast_dm(accounts: list[int], targets: list[str],
ai_preset_id: int) -> str:
"""Рассылка в личные сообщения"""
# POST /api/ai/broadcast_dm
...
# --- Автоответчик ---
def ai_autoresponder_start(account_id: int, ai_preset_id: int,
scenario: str = "support") -> str:
"""ИИ автоответчик на входящие сообщения"""
# POST /api/ai/ai_autoresponder
...
# --- Накрутка ---
def nakrutka_reactions(accounts: list[int], post_link: str,
reaction_type: str = "👍", count: int = 100) -> str:
"""Массовые реакции на пост"""
# POST /api/ai/reactions (только Ultra)
...
def nakrutka_views(accounts: list[int], post_link: str, count: int = 1000) -> str:
"""Накрутка просмотров на пост"""
# POST /api/ai/views (только Ultra)
...
def mass_looking(accounts: list[int], targets: list[str]) -> str:
"""Массовый просмотр профилей (Mass Looking)"""
# POST /api/ai/mass_looking
...
# --- Отметки в сторис ---
def story_mentions(accounts: list[int], story_media: str,
targets: list[str]) -> str:
"""
Отметки пользователей в сторис.
Упомянутый получает уведомление → смотрит историю → переходит в канал.
"""
# POST /api/ai/story_mentions (только Ultra)
...
def story_repost_preview(story_link: str) -> dict:
"""Предпросмотр истории перед репостом"""
# GET /api/story-repost/preview
...
def story_repost_viewers(story_link: str) -> list[str]:
"""Список зрителей истории"""
# GET /api/story-repost/viewers
...
# --- Инвайтер ---
def inviter_start(accounts: list[int], invite_link: str, count: int = 100) -> str:
"""Массовое приглашение в канал/чат"""
# POST /api/ai/inviter
...
# --- Каналы ---
def channel_create_copy_post(source_channel: str, target_channel: str,
accounts: list[int]) -> str:
"""Копирование постов между каналами"""
# POST /api/channel-create/copy-post
...
def channel_get_templates() -> list[dict]:
"""Шаблоны для каналов"""
# GET /api/channel-create/templates
...
# --- Граббер ---
def grabber_start(source_channels: list[str], accounts: list[int]) -> str:
"""Сбор контента из каналов (текст, медиа, ссылки)"""
# POST /api/ai/grabber
...
# --- Сессионный дубликатор ---
def session_duplicate(account_id: int) -> str:
"""Клонировать сессию аккаунта (для параллельного использования)"""
# POST /api/session-duplicator/:id
...
def session_download(account_id: int) -> bytes:
"""Скачать .session файл"""
# GET /api/session-duplicator/download/:id
...
def session_switch(account_id: int, new_session_id: int) -> bool:
"""Переключить аккаунт на другую сессию"""
# POST /api/session-duplicator/switch/:id
...
# --- Профили ---
def profile_presets_list() -> list[dict]:
"""Список пресетов профилей (имя + био + фото)"""
# GET /api/profile-presets/list
...
def profile_random() -> dict:
"""Случайный пресет профиля"""
# GET /api/profile-presets/random
...
def profile_templates() -> list[dict]:
"""Шаблоны профилей"""
# GET /api/profile-templates
...
def profile_upload_photo(photo_file: str) -> str:
"""Загрузить фото для профиля"""
# POST /api/profile-templates/photos/upload
...
# --- Воркспейсы / Команда ---
def workspace_list() -> list[dict]:
"""Список воркспейсов"""
# GET /api/workspaces
...
def workspace_set_active(workspace_id: int) -> bool:
"""Сменить активный воркспейс"""
# POST /api/workspaces/active
...
def team_context() -> dict:
"""Контекст команды (права, роли)"""
# GET /api/team/context
...
# --- Биллинг ---
def subscribe_start(tariff: str, payment_method: str = "crypto") -> dict:
"""Оформить подписку. payment_method: crypto | card | sbp"""
# POST /api/subscribe/start
...
def subscribe_status() -> dict:
"""Статус подписки: active/inactive, тариф, дата окончания"""
# GET /api/subscribe/active
...
def currency_rate() -> dict:
"""Курс валют для крипто-оплаты"""
# GET /api/currency/rate
...
# === АНТИ-ДЕТЕКТ И ЗАЩИТА ===
ANTI_DETECT_LAYERS = {
"captcha_solver": "85% капч авто-решаются (боты проверки Telegram)",
"trust_score": "Рейтинг надёжности каждого аккаунта (0-100)",
"auto_limits": "Безопасные лимиты по умолчанию для всех действий",
"intervals": "Паузы между действиями с рандомизацией",
"proxy_per_account": "Отдельный резидентский прокси на каждый аккаунт",
"warmup_before_use": "Обязательный прогрев перед рассылкой/комментингом",
"spamblock_check": "Авто-проверка @SpamBot при подозрении на спамблок",
"session_isolation": "Изолированные сессии через встроенный Telegram Web",
"cloud_execution": "24/7 облачное исполнение, IP ротация на стороне сервера",
}
# === СРАВНЕНИЕ С DESKGRAM ===
COMPARISON = {
"architecture": {
"darktelegram": "SaaS Cloud (FastAPI + React SPA). Нет десктоп-клиента. 24/7 сервера.",
"deskgram": "Desktop (PE32+ C++ dropper → Python/Telethon workers). Локальный сервер 127.0.0.1:5000.",
},
"auth": {
"darktelegram": "email+password, Google OAuth, Telegram OAuth, Cloudflare Turnstile",
"deskgram": "activation_key (Prodamus), JWT refresh",
},
"accounts": {
"darktelegram": ".session + tdata import, встроенный LZT Market, phone auth flow",
"deskgram": ".session import, ручная авторизация через код",
},
"modules": {
"darktelegram": "~15 модулей (AI-центричные)",
"deskgram": "82 модуля (всё что можно автоматизировать)",
},
"ai": {
"darktelegram": "Своя AI-инфраструктура (OpenRouter?), пресеты промптов и фото",
"deskgram": "io.net, OpenRouter (14 моделей), Mistral API",
},
"unique": {
"darktelegram": "ИИ Продажник (3-фазный), Session Duplicator, Story Mentions, Telegram Web в дашборде",
"deskgram": "Инвайт по гео, Remove SpamBlock, 12 категорий модулей",
},
"pricing": {
"darktelegram": "$49-130/мес + модули à la carte + AI токены",
"deskgram": "16,990₽/год (~$15/мес) единый тариф",
},
}
# === УЯЗВИМОСТИ И ВЕКТОРЫ ===
VULNERABILITIES = {
"turnstile_bypass": {
"target": "/api/auth/register",
"vector": "Отсутствует серверная валидация Turnstile? Нужно проверить через реплей запроса без токена",
"status": "НЕ ПРОВЕРЕНО — нужен реплей без cf-turnstile-response",
},
"rate_limiting": {
"target": "/api/auth/login",
"vector": "Нет видимого rate-limit в ответах. 429 не тестировался",
"status": "НЕ ПРОВЕРЕНО",
},
"id_enumeration": {
"target": "/api/accounts/summary, /api/accounts/trust",
"vector": "ID аккаунтов последовательные? Можно перебирать чужие аккаунты",
"status": "НЕ ПРОВЕРЕНО — нужна сессия",
},
"ai_preset_injection": {
"target": "ai_presets",
"vector": "Можно ли инжектить промпт в AI задачу через кастомный preset?",
"status": "Требует анализа формата пресетов",
},
"session_leak": {
"target": "/api/session-duplicator/download/:id",
"vector": "Можно ли скачать чужую сессию при IDOR?",
"status": "КРИТИЧЕСКИЙ ВЕКТОР — нужна авторизованная сессия для теста",
},
}
if __name__ == "__main__":
print(f"DarkTelegram.pro reverse — {len(ENDPOINTS)} API endpoint'ов")
print(f"Модулей: {len(MODULES)}, Тарифов: {len(TARIFFS)}")
print(f"Векторов для проверки: {len(VULNERABILITIES)}")
print("\n=== УНИКАЛЬНЫЕ ФИЧИ ===")
for k, v in COMPARISON["unique"].items():
print(f" {k}: {v}")