Дисклеймер: всё ниже — реальный кейс, домены и IP не вымышленные. Не ходите туда с основного браузера и тем более с залогиненным Telegram.

0. Точка входа: сообщение в 5 утра

Будит уведомление — 5:03. Сообщение в Telegram от хорошего знакомого:

Привет UserName, могу я тебя попросить

В благотворительном соревновании детских рисуночков принимает участие

ребёнок моих родственников — Мария Янкова.

Выигрыш — это возможность получения гранта.

Если найдёшь пару минут — за Янкову Машу отметишь пожалуйста

Вот здесь 👉 http://risk.fun-fix.shop/deti/lot

Спасибо тебе! Передай знакомым 💓

В пять утра, от знакомого. Само сообщение читается живо и по‑человечески, но взгляд уже цепляется за детали:

  • домен risk.fun‑fix.shop — ну такое;

  • HTTP, не HTTPS, в 2026-м;

  • финал «передай знакомым» с сердечком — это самораспространение: автор схемы хочет, чтобы вы сами добавили легитимности ссылке среди ваших контактов;

  • в пять утра тыкать в незнакомую ссылку с основного устройства — то ещё удовольствие.

Пишу отправителю в ответ — попробовать уточнить, что это вообще. Отправитель не отвечает: ни тут же, ни через час, ни ответом по другому каналу. Стандартная картина — аккаунт уже видимо не его, а сидящий там атакующий не заинтересован объясняться с подозрительными контактами.

Окей, значит разбираемся сами.

1. Сначала curl, и сюрприз — 403

Заходить с браузера в незнакомый HTTP‑сайт в пять утра не очень хочется, поэтому первый инструмент — curl:

curl ‑vvv http://risk.fun‑fix.shop/deti/lot \

‑H “User‑Agent: Mozilla/5.0 (X11; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0”

В ответ — HTTP 403 и интересный набор заголовков:

* Trying 94.26.35.126:80...

* Connected to risk.fun‑fix.shop (94.26.35.126) port 80

> GET /deti/lot HTTP/1.1

..

< HTTP/1.1 403 Forbidden

< Server: nginx

< Access‑Control‑Allow‑Origin: *

< Set‑Cookie: 7c7891ef8afa36f19f67ab826580b16a=YTo0OntpOjA7aTowO2k6MTtpOjE7aToyO2E6NTp7aTowO2k6MDtpOjE7aTowO2k6MjtpOjA7aTozO2k6MTtpOjQ7aTowO31pOjM7aToxNzc4MTU3MjI2O30%3D; expires=Thu, 07 May 2026 12:33:46 GMT; Max‑Age=86400; path=/; HttpOnly; SameSite=None

403 + cookie с expires=+24h — это не «сервер упал», это клоакер / TDS (Traffic Distribution System) намеренно прячет содержимое от не‑целевых посетителей. URL‑decode → base64-decode значения cookie даёт PHP‑serialize():

a:4:{i:0;i:0;i:1;i:1;i:2;a:5:{i:0;i:0;i:1;i:0;i:2;i:0;i:3;i:1;i:4;i:0;}i:3;i:1778157226;}

Что в этом массиве:

[0] = 0 // visit counter / state flag

[1] = 1 // флаг «видели»

[2] = [0,0,0,1,0]// массив из 5 флагов проверок (UA, Referer, JS, geo,...)

[3] = 1 778 157 226 // unix‑timestamp, ~ +24ч от текущего, expiry

Имя cookie — md5-подобный хэш, формат — PHP‑serialize(). Это либо рукописный, либо коробочный (типа Keitaro/BlackTDS‑подобный) PHP‑фильтр, который:

  • на каждом заходе ставит cookie со «своими галочками»;

  • по этим галочкам решает: отдать 200 + редирект на боевую страницу или 403.

То, что cookie выдают даже при 403, — нормально: они хотят пометить визит, чтобы при последующих заходах с той же связкой IP+UA ничего полезного не показывать.

Почему мой curl получил 403, понятно: с точки зрения клоакера он выглядит как «олень из зоопарка» — нет Accept‑Language, нет Referer, Accept: /, а UA — Firefox 58 на Linux x86_64 в 2026-м.

Если прикинуться мобильным пользователем из Telegram, страница уже отдаёт нормально:

curl ‑vvv 'http://risk.fun‑fix.shop/deti/lot' \

‑H 'User‑Agent: Mozilla/5.0 (Linux; Android 13; SM‑G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36' \

‑H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \

‑H 'Accept‑Language: ru‑RU,ru;q=0.9,en;q=0.8' \

‑H 'Accept‑Encoding: gzip, deflate' \

‑H 'Referer: https://t.me/' \

‑H 'Upgrade‑Insecure‑Requests: 1' \

‑compressed ‑L

Вот теперь сервер счастлив и говорит, куда же он на самом деле хочет нас отправить.

2. Двухступенчатый редирект

Бейт‑домен никаких голосований сам не показывает. Если клоакер пропустил — отдаётся редирект на турецкий домен:

GET /deti/lot HTTP/1.1

Host: risk.fun‑fix.shop

HTTP/1.1 302 Found

Location: https://dobro‑vesna.com.tr/help‑vision/20

Это типичная архитектура «бейт + рабочий домен»:

  • бейт risk.fun‑fix.shop сжигается спам‑фильтрами быстро, его держат у одного провайдера;

  • боевой клон Telegram Web dobro‑vesna.com.tr живёт у другого, его жалко терять.

И ровно поэтому у них разные IP и разные хостинги — мы это разберём в разделе про инфраструктуру.

На https://dobro‑vesna.com.tr/help‑vision/20 встречает красиво стилизованная «страница голосования за детский рисунок».

Куча шумовых классов, скрытые блоки с ирелевантным текстом, конфликтующие CSS‑объявления — всё, чтобы автоматические сканеры не цеплялись за ключевые слова. Кнопка «ПРОГОЛОСОВАТЬ» — просто триггер для следующего перехода:

<button

class=“dxtyavbk_vBRxZ dxtyavbk_AUTu dxtyavbk_yHtcLzZN dxtyavbk_ZLlb”

dxtyavbk_RQTfTfrV dxtyavbk_woqw dxtyavbk_zMVXRa dxtyavbk_ttNr’

data‑columns=“dxtyavbk_LZfiWut”>

ПРОГОЛОСОВАТЬ

</button>

<script>

document.addEventListener('DOMContentLoaded', function () {

const voteButtons = document.querySelectorAll(“.dxtyavbk_vBRxZ”);

voteButtons.forEach(button => {

button.addEventListener('click', function () {

window.location.href = '/help‑vision/D5oRKcN';

});

});

});

</script>

Кликнули — поехали на /help‑vision/D5oRKcN. И вот тут начинается интересное.

3. Клон Telegram Web

На /help‑vision/D5oRKcN встречает пиксель‑в-пиксель копия Telegram Web с экраном логина по номеру. Дизайн, шрифты, анимация лого — всё как у настоящего.

Если ввести любой номер (даже несуществующий) — страница начинает грузить большой обфусцированный JS‑бандл и регистрировать service worker.

И вот тут уже не «фейковая форма с POST в /steal.php». Это форк настоящего Telegram Web (tweb/webK‑подобный клиент), переклеенный на инфраструктуру атакующих. Доказательств в коде хватает.

3.1. Имена кэшей — один в один

Telegram Web использует характерный набор имён Cache Storage. В DevTools → Application → Cache Storage и параллельно в коде service worker:

const CACHES = [

'cache_assets',

'cache_documents',

'cache_stream_chunks'

];

cache_stream_chunks — это узкоспецифичная штука: так в Telegram Web называется кэш для прогрессивной подгрузки чанков медиа. Случайно такое имя в чужой проект не попадает.

3.2. Тот же MessageChannel‑протокол между страницей и SW

В оригинальном tweb страница общается с service worker через postMessage со строго определёнными типами: requestFilePart, pushClick, pushPing, notificationsClear и тому подобное. В бандле на dobro‑vesna.com.tr — ровно тот же протокол, только имена внутренних функций заминифицированы:

self.addEventListener(“message”, e => {

const o = e.data;

switch (o.type) {

case “requestFilePart”:

Qi(o.id, o.dcId, o.location, o.offset, o.limit);

break;

case “pushClick”:

cr(o);

break;

case “pushPing”:

mr(o);

break;

case “notificationsClear”:

gr();

break;

}

});

Сравните с тем, как это устроено у настоящего клиента (упрощённо):

self.addEventListener('message', event => {

const { type, payload, id } = event.data;

if (type === 'requestFilePart') {

requestFilePart(id, payload.dcId, payload.location,

payload.offset, payload.limit);

} else if (type === 'pushClick') {

onPushClick(payload);

}

});

Сигнатура requestFilePart(id, dcId, location, offset, limit) — это буквально публичный «контракт» между страницей и SW в tweb. Совпадение по позициям и семантике аргументов — это не «вдохновлено», это тот же код.

3.3. Прогрессивный стриминг через /progressive/{dcId}/...

В оригинальном клиенте fetch‑обработчик SW узнаёт «свои» URL по префиксу /progressive/, парсит из них dcId и location, идёт за чанками. В бандле атакующих — тот же приём:

self.addEventListener(“fetch”, e => {

const u = new URL(e.request.url);

if (u.pathname.startsWith(“/progressive/”)) {

e.respondWith(vr(e));

return;

}

//... остальные ветки...

});

async function vr(e) {

const [,, dcId, fileId,...rest] = new URL(e.request.url).pathname.split(“/”);

// далее — обращение к Qi() / br() с теми же dcId/location/offset/limit

}

Это уже прямая копия архитектуры стриминга медиа из Telegram Web.

3.4. Те же WebAssembly‑зависимости

В бандле инициализируются модули с сигнатурами opus‑декодера и обработчика голосовых вейвформ — ровно то, что использует tweb (opusDecoder, rlottie, libwebp). Случайному фишинг‑сайту такие модули не нужны вообще; они нужны клиенту, который реально умеет проигрывать голосовые и стикеры.

3.5. Что это даёт атакующему

Главный смысл всей этой возни — не «нарисовать красивую форму», а проксировать настоящий MTProto‑флоу:

  • интерфейс реально работает: вы получаете настоящий код от Telegram (потому что атакующий запросил его настоящим клиентом, в качестве которого выступает он сам);

  • вы вводите код и 2FA‑пароль — атакующий получает валидную сессию, а не строку «+7…»;

  • после успешного логина браузер ведёт себя «как обычно», жертва ничего подозрительного не видит — а атакующий уже сидит в её аккаунте на своём устройстве;

  • первое, что он делает с угнанного аккаунта в 5 утра по локальному времени контакта, — рассылает то самое сообщение про детский конкурс по списку контактов.

Круг замкнулся.

4. Где живёт инфраструктура

Дальше — обычная whois‑археология. У нас два разных хостинга, потому что у бейта и у боевого домена разные IP.

4.1. Бейт‑домен risk.fun‑fix.shop

$ dig +short A risk.fun‑fix.shop

94.26.35.126

Здесь же стоит тот PHP‑клоакер из раздела 1. По whois IP‑блок выглядит так:

inetnum: 94.26.35.0/24 (SUB‑ALLOCATED PA, country CH)

route: 94.26.35.0/24 origin AS51852

created: 2026–01-19 (суб‑аллокация выдана 4 месяца назад)

org: SINO WORLDWIDE TRADING LIMITED (HK, шелл‑компания)

mnt‑by: lir‑bg‑telco-1-MNT

mnt‑ref: MNT‑NETERRA, bg‑sofcompany-1-mnt, mnt‑bg‑eurocrypt-1

abuse‑c: ACRO62035-RIPE

Иными словами: формально швейцарский диапазон, оформленный на гонконгскую шелл‑компанию, обслуживаемый болгарскими LIR«ами и Neterra‑связанными maintainer»ами. Всё это сделано в конце 2025 — начале 2026 года, явно под текущую кампанию. Это типичный профиль bulletproof‑style арендованной подсети, где «хостер» меняется как перчатки.

Реальный abuse‑email достаём отдельным запросом:

whois ‑h whois.ripe.net ACRO62035-RIPE

— и используем его как первичный адрес жалобы по бейт‑IP.

4.2. Боевой домен dobro‑vesna.com.tr

$ dig +short A dobro‑vesna.com.tr

178.16.54.9

Whois по домену (.tr, реестр TRABIS):

Domain Name: dobro‑vesna.com.tr

Status: Active

Registrar: ATAK DOMAİN BİLGİ TEKNOLOJİLERİ A.Ş. (TR)

Nameservers: julio.ns.cloudflare.com

kayleigh.ns.cloudflare.com

Created: 2025–11-16

Expires: 2026–11-15

Registrant: Hidden upon user request

Whois по IP:

inetnum: 178.16.54.0 — 178.16.54.255

netname: OMEGATECH

country: NL

org: Omegatech LTD (Seychelles)

abuse‑c: abuse@omegatech.sc

route: 178.16.54.0/24 AS202412

Самая интересная деталь — отсутствие cloudflare‑прокси перед origin. NS у домена принадлежат Cloudflare (julio.ns.cloudflare.comkayleigh.ns.cloudflare.com), но A‑запись отдаёт прямой IP Omegatech — 178.16.54.9. Если бы трафик шёл через CF‑прокси, вернулся бы адрес из диапазонов Cloudflare (типа 104.16/12 или 172.64/13), а не клиентский. То есть Cloudflare здесь только DNS‑хостинг, без оранжевого облачка, и реальный origin не спрятан.

Для нас это удобно: можно жаловаться напрямую хостеру, не упираясь в стандартное «мы только CDN, обращайтесь к origin».

4.3. Итоговая карта инфраструктуры

Сводно по адресатам жалоб:

  • бейт‑домен: risk.fun‑fix.shop, IP 94.26.35.126, AS51852, шелл‑компания SINO WORLDWIDE TRADING (HK), обслуга — болгарский LIR / Neterra,

  • боевой домен: dobro‑vesna.com.tr — реестр.tr (TRABIS), регистратор ATAK Domain, NS Cloudflare,

  • origin боевого: 178.16.54.9, Omegatech LTD (Seychelles), netname OMEGATECH, AS202412.

5. Как такие вещи разбирать у себя

Минимальный набор для self‑debug любой подобной «голосовалки»:

  • Сначала curl, не браузер. Если получили 403 + cookie — не закрывайте, разберите cookie. Очень часто в формате php_serialize / JSON / base64 валяется готовая структура «что проверил клоакер»; уже из этого видно, что вообще происходит.

  • Отдельный профиль браузера или ВМ. Никаких сохранённых сессий Telegram, банков и почты. Внутрь — мобильный UA и Accept‑Language: ru‑RU.

  • DevTools → Application → Service Workers. Если на странице зарегистрирован SW — записываете его URL целиком, это уже один артефакт инфраструктуры.

  • Application → Cache Storage. Имена вроде cache_assets, cache_documents, cache_stream_chunks — почти стопроцентный признак форка Telegram Web. Внутри — реальные URL ассетов и API.

  • Network → Fetch/XHR + WS, включить «Show requests from Service Worker». Вводите фейковый номер, смотрите, куда улетает первый запрос. WS‑канал к чему‑то вроде wss://<их‑домен>/apiws — это и есть прокси под MTProto.

  • dig + whois по обоим доменам и IP. Если A отдаёт не Cloudflare‑диапазон — origin открыт, идите сразу к хостеру. Если IP‑блок суб‑аллоцирован недавно и сидит на смеси HK‑шелла + BG/LV‑maintainer«ов — это уже самостоятельный red‑flag.»

Пара минут — и у вас полный профиль атакующего: бейт‑инфра, боевая инфра, IP, хостеры, регистратор, реестр, провайдер NS.

6. Куда я отправил жалобы

Чтобы это всё не осталось «ну посмотрел и закрыл», полезно методично вынести сор из избы во все инстанции, у которых есть рычаг. Приоритет — кто реально может выключить инфраструктуру:

  • Хостер origin (Omegatech) — abuse@omegatech.sc. В этом кейсе он же — главный адресат, потому что origin открыт.

  • Хостер бейт‑IP 94.26.35.126 — abuse‑mailbox от хэндла ACRO62035-RIPE (получаем whois ‑h whois.ripe.net ACRO62035-RIPE), плюс параллельно болгарские maintainer«ы как непрямые адресаты:»

    • MNT‑NETERRA (Neterra Communications, BG) — abuse@neterra.net / форма https://www.neterra.net/abuse,

    • lir‑bg‑telco-1-MNT — abuse‑mailbox того LIR (по handle«у),»

    • upstream AS51852 — поднять abuse через peeringdb.com/asn/51852.

В письме делаем явный упор на серверный клоакер: цитируем Set‑Cookie с PHP‑serialize и факт 403/200 в зависимости от UA — это прямое доказательство, что abuse‑направленность настроена на стороне сервера, а не «у нас взломали страничку».

  • Cloudflare — форма https://abuse.cloudflare.com/phishing и abuse@cloudflare.com. Они тут не CDN, а только DNS‑хостинг, но всё равно могут перестать обслуживать домен.

  • Регистратор dobro‑vesna.com.tr — ATAK Domain, abuse@atakdomain.com (+ info@, destek@). Прошу clientHold по обязательствам ICANN/TRABIS.

  • Реестр.tr — TRABIS / BTK: trabis@btk.gov.tr, плюс контакты из IANA (onur.gencer@btk.gov.trgokhan.usta@btk.gov.tr).

  • Регистратор fun‑fix.shop (whois по домену) — отдельным письмом по той же логике.

  • CERT Турции (USOM) — bildirim@usom.gov.tr и форма usom.gov.tr/ihbar.

  • Telegram — @notoscam в самом мессенджере и abuse@telegram.org.

  • Антифишинговые листы (чтобы Chrome/Firefox/Safari начали показывать «Deceptive site»):

    • Google Safe Browsing — safebrowsing.google.com/safebrowsing/report_phish/

    • PhishTank — phishtank.org/add_web_phish.php

    • Netcraft — report.netcraft.com/report

    • APWG — reportphishing@apwg.org

Шаблон письма, которым удобно бомбить всех сразу (кратко):

Subject: Phishing report: dobro‑vesna.com.tr (Telegram credential theft) — IPs 178.16.54.9 / 94.26.35.126

Bait domain: http://risk.fun‑fix.shop/deti/lot (IP 94.26.35.126, AS51852)

Phishing domain: https://dobro‑vesna.com.tr/help‑vision/20

https://dobro‑vesna.com.tr/help‑vision/D5oRKcN

Phishing origin: 178.16.54.9 (NOT behind Cloudflare proxy)

Hosting / IP holder: Omegatech LTD (RIPE: OMEGATECH, AS202412)

Bait IP holder: SINO WORLDWIDE TRADING LIMITED (HK shell),

sub‑allocated 2026–01-19, BG LIR + MNT‑NETERRA

Nameservers: julio.ns.cloudflare.com, kayleigh.ns.cloudflare.com

Registrar: ATAK Domain (TR)

Registry:.tr / TRABIS (BTK)

The bait host operates a PHP‑based cloaking/TDS that selectively

redirects mobile RU‑locale visitors arriving from Telegram to the

phishing page on dobro‑vesna.com.tr; non‑targeted requests are answered

with HTTP 403 to evade automated detection. The phishing page

impersonates Telegram Web and steals phone numbers, login codes and

2FA passwords by running a modified Telegram Web service worker that

proxies the MTProto auth flow through attacker‑controlled infrastructure.

Please suspend / null‑route the host, suspend the domain, and preserve

logs (HTTP access, auth, billing, registration, payment method) for any

future law‑enforcement request.

Полная версия письма с обоснованием и evidence — отдельно по каждому адресату.

7. Что делать, если уже ввели данные

Если на каком‑то шаге всё‑таки прошёл код или 2FA‑пароль:

  • Telegram → Settings → Devices → Terminate all other sessions. Сразу.

  • Поменять облачный пароль (2FA) в Privacy and Security.

  • Проверить Active Sessions ещё раз через 5 минут — атакующий может попытаться зайти заново.

  • Просмотреть Saved Messages, секретные чаты, привязанные боты, права в админских группах — особенно интересны те, где вы админ.

  • Предупредить контакты: с вашего имени уже могла уйти ровно такая же «голосовалка».

8. Краткие выводы

  • Современный фишинг на Telegram — это не «введите пароль», а полноценный форк клиента с MTProto‑проксированием и Service Worker. Это объясняет, почему всё так убедительно выглядит и реально присылает вам код.

  • Перед боевой страницей часто стоит отдельный TDS / клоакер на стороннем хостинге, который фильтрует трафик и прячет фишинг от сканеров. Сам факт его наличия — самостоятельное доказательство злого умысла, и в abuse‑письма это нужно включать.

  • Под такие кампании сейчас арендуются свежие /24-блоки у bulletproof‑LIR«ов (HK‑шелл, BG‑обслуга), оформленные за 1–3 месяца до запуска. Если в whois IP‑блок моложе 6 месяцев и сидит на болгарском/латвийском/гонконгском миксе maintainer»ов — это уже самостоятельный red‑flag, ещё до анализа контента.

  • Точка входа — доверенный контакт, а не подозрительная рассылка. Поэтому единственная надёжная эвристика — смотреть на домен и на сам сценарий («войди в Telegram, чтобы проголосовать»), а не на отправителя.

  • Любой сайт, который просит ввести номер Telegram или код из Telegram «чтобы за кого‑то проголосовать / получить подарок / подтвердить участие», — это фишинг. Других интерпретаций не бывает.

  • Технически такие кейсы разбираются за 10 минут curl + DevTools + dig + whois, и из этого получается набор адресатов, которые могут реально снести инфраструктуру.

Если получили такое сообщение — не молчите. Попробуйте достучаться до отправителя по другому каналу («ты только что прислал ссылку, у тебя угнали аккаунт»), сообщите в @notoscam, и пройдитесь по списку выше. Чем больше параллельных жалоб, тем быстрее у атакующих сгорает домен и хостинг — и тем меньше следующих жертв.

Берегите свои сессии. И передайте знакомым 💓 — но не ссылку, а вот эту статью.