I recently analyzed a live toolkit targeting Telegram users across East Africa. The campaign combines three techniques that individually look harmless but chain together into a highly effective account takeover: fabricated social proof, Mini App phishing, and persistent session theft via the Telegram MTProto API.
What makes this attack particularly dangerous is that it exploits Telegram's own infrastructure. The victim receives a real SMS code from Telegram, clicks a real Telegram link, and interacts with what looks like a real Telegram UI — and still loses their account.
The Full 11-Step Kill Chain
Color key: ■ Attacker ■ Victim ■ System
Spam Bot Posts Fake "Winners"
An automated bot floods large Telegram groups every 5–10 minutes with fabricated winning messages. Phone numbers are randomly generated Ethiopian numbers, masked as +25191****789. Prize amounts (5,000–50,000 birr) and member counts are random integers. None represents a real person.
Victim Sees the "Winner" Post
Because the bot posts repeatedly, the group appears flooded with winners. Volume creates false legitimacy. The victim cannot distinguish fabricated phone numbers from real ones.
Victim Clicks the t.me Link
The post contains a t.me domain link. Because it is Telegram-native, it feels safe. The link opens a Telegram Mini App — a web application running inside the official Telegram client.
Telegram Mini App Opens
The Mini App loads inside the official Telegram client with full Telegram UI chrome around it. It uses Telegram's own SDK and native components. There is no visual difference between this and an official Telegram feature.
"Share Phone Number" Prompt Appears
The app shows a "Share your phone number to claim your prize" screen, implemented using Telegram's native RequestPhone button — a real Telegram UI element. The victim has no visual cue to distrust it.
Phone Number Harvested via Webhook
When the victim taps "Share", their real Telegram-registered phone number is sent to the attacker's webhook endpoint and logged immediately. The victim sees a loading screen.
Attacker Calls the Telegram MTProto API
The server immediately calls send_code_request(phone) using a registered App API ID and hash. This is a legitimate Telegram API call that triggers a real system event on Telegram's infrastructure.
Real Telegram SMS Code Sent to Victim
The victim receives a genuine Telegram verification code via SMS or in-app notification from "Telegram". It is the same code as any legitimate login — completely authentic, because it is.
Victim Enters the Code on the Fake Page
The Mini App displays a "Enter your confirmation code to verify and claim your prize" field. Having just received a code from Telegram, the victim enters it. The code is submitted to the attacker's server.
Session File Created — Account Stolen
The attacker calls sign_in(phone, code). Telegram authenticates the request. A .session file — a permanent authentication token — is saved on the attacker's server. No password needed. No 2FA triggered. No notification to the victim.
Victim's Account Weaponized
The stolen session is loaded into a web-based session manager. send_to_all() blasts the same scam to up to 50 of the victim's groups and channels. Because it comes from a trusted contact, click rates are dramatically higher. The cycle repeats exponentially.
Why the Mini App Looks Legitimate
The attack exploits Telegram's own UI components. There is no visual difference between a real Telegram feature and the fake Mini App — because the attacker uses Telegram's own SDK to build it.
What a Stolen Session File Grants
A Telegram .session file is a persistent authentication token that bypasses every login layer except physical device revocation.
Exponential Spread
Each compromised account immediately becomes a new attack vector, reaching tens of thousands of trusted contacts.
Inside the Toolkit
Pseudocode representations of the core mechanisms. Function names and identifiers generalized for this publication.
# All phone numbers, win amounts, and member counts are random def generate_ethiopian_number(): prefixes = ["+25191", "+25192", "+25193", ...] # all fabricated return random.choice(prefixes) + random_digits(6) def generate_message(): phone = mask(generate_ethiopian_number()) # e.g. +25191****789 members = random.randint(50, 500) prize = random.randint(5000, 50000) return f"🎉 {phone} added {members} members → won {prize:,} birr!\n👇 {APP_LINK}" async def auto_poster(): while True: await bot.send_message(GROUP_ID, generate_message()) await asyncio.sleep(random.randint(300, 600)) # 5–10 min
# Uses stolen .session files to spam all of a victim's contacts async def _send_to_all(session_id, message): dialogs = await get_all_dialogs(session_id) for dialog in dialogs[:50]: # up to 50 per stolen account if dialog['type'] in ['group', 'channel']: entity = await client.get_entity(dialog['peer_id']) await client.send_message(entity, message) # ↑ Sent AS the victim — from a trusted contact await asyncio.sleep(0.2) # rate-limit evasion
# Receives phone number when victim taps "Share Contact" @app.route('/webhook/<token>', methods=['POST']) def webhook(token): contact = request.json['message']['contact'] harvest({ 'phone': contact['phone_number'], # ← victim's real number 'name': contact['first_name'], 'id': contact['user_id'], }) # Immediately trigger SMS code to victim via MTProto API telegram_api.send_code_request(contact['phone_number'])
How to Protect Yourself
Four actions that break this attack chain completely — even if you click the link.
The single most effective defense. With 2FA active, an SMS code alone is not enough — the attacker also needs your password, which this attack cannot retrieve.
Telegram never asks for verification codes inside a Mini App, bot, or website. If anything prompts for it, close it immediately — regardless of how it looks.
Telegram lists every device and session with access to your account. Review regularly and terminate anything unfamiliar immediately — there is no grace period.
Groups flooded with prize posts are running bots. Even if the sender is a known contact, their account may already be compromised. Report the post and leave the group.
Findings Log
RESEARCH_ID = "LOG-2026-006" DATE = "2026-04-18" RESEARCHER = "Habtamu Bitew Gashu" METHOD = "Static code analysis — no live accounts targeted" REGION = "East Africa (Ethiopian phone number patterns)" # ── Components Analyzed ────────────────────────────────── COMPONENT_1 = "Spam bot (aiogram) — auto-generates fake winner messages" COMPONENT_2 = "Session manager (Flask + Telethon) — manages stolen .session files" COMPONENT_3 = "Contact harvesting webhook — captures phone numbers via Mini App" # ── Attack Metrics ─────────────────────────────────────── CHAIN_LENGTH = 11 # steps from first post to account takeover DIALOGS_SPAMMED = 50 # max per stolen session ESTIMATED_REACH = "85,000+ users per compromised account" AUTH_BYPASS = True # no password, no 2FA, no notification # ── Mitigations ────────────────────────────────────────── MITIGATIONS = [ "Enable Two-Step Verification (breaks step 10 completely)", "Never enter Telegram codes in Mini Apps or websites", "Audit active sessions monthly via Settings > Devices", "Report prize-recruitment spam immediately", ]