История стандартная для малого и среднего бизнеса: оптовая компания, 15 сотрудников, у менеджера по снабжению — рабочий телефон с привязанным к нему расчётным счётом. Ночью с этого счёта уходят два перевода на 380 000 рублей суммарно, банк присылает подтверждение, менеджер спит. Формально операция подтверждена с устройства владельца счёта — значит, для банка это не мошенничество, а «клиент сам перевёл». Разбираться пришлось не с банком, а с телефоном.
Куда делись деньги
За неделю до списания менеджеру в мессенджер пришла ссылка: «обновите приложение банка, иначе доступ будет заблокирован». Ссылка вела не в Google Play, а на сторонний сайт с файлом APK. Установка прошла в обход официального магазина — при первом запуске приложение запросило права на службу специальных возможностей (Accessibility Service) и на отображение поверх других окон. Пользователь эти права выдал, посчитав их частью «настройки безопасности банка».
С этого момента устройство фактически перестало принадлежать владельцу. Троян умеет три вещи одновременно: читать содержимое экрана и уведомлений через Accessibility API, рисовать поддельный интерфейс поверх настоящего приложения (overlay-атака) и перехватывать входящие SMS раньше, чем их увидит пользователь. Когда менеджер открывал настоящее банковское приложение, троян детектировал имя пакета на переднем плане и за доли секунды подменял экран собственной копией — визуально неотличимой. Введённые логин, пароль и код из СМС уходили не в банк, а на сервер злоумышленников, а настоящий банк в это время получал легитимный, только что перехваченный код подтверждения.
Почему это не «вирус для одного банка»
Современные семейства таких троянов (в духе публично описанных TeaBot/Anatsa, Cerberus/Octo, Hook, Vultur) не пишутся под конкретный банк. Overlay и парсинг экрана строятся так, что вредонос сравнивает foreground-пакет (com.android.systemui → активный app) со списком из сотен банковских и криптокошельковых приложений и подгружает нужный шаблон фишингового окна с сервера управления (C2) уже после заражения. Это ровно тот случай, который описан в новости о 349 атакуемых приложениях: список целей не зашит статично в APK, а обновляется удалённо, поэтому антивирусные сигнатуры отстают.
Как это эксплуатируется — по шагам
Ниже — типичный путь такой атаки с точки зрения человека, который её расследует или тестирует защищённость корпоративных устройств. Все команды — для легального анализа собственного APK/устройства, не для атаки на чужую инфраструктуру.
1. Доставка
Фишинговое сообщение в мессенджере или SMS со ссылкой на сторонний хостинг APK. Проверка такого домена стандартным инструментарием разведки:
curl -I https://fake-bank-update.ru/app.apk
HTTP/1.1 200 OK
Server: nginx
Content-Type: application/vnd.android.package-archive
Content-Disposition: attachment; filename="Bank_Update.apk"
Домен зарегистрирован несколько дней назад, сертификат Let's Encrypt, никакого редиректа на официальный сайт банка — классические признаки одноразовой фишинговой инфраструктуры.
2. Установка в обход Google Play
Ключевое условие атаки — разрешённая установка «из неизвестных источников». Проверить состояние настройки на устройстве:
adb shell settings get global install_non_market_apps
1
Единица означает, что установка сторонних APK разрешена — именно так троян и попал на телефон менеджера.
3. Статический анализ вредоносного APK
При разборе инцидента я разворачиваю образец в изолированной песочнице (эмулятор без сети или отдельный физический тестовый телефон) и смотрю манифест и код:
apktool d Bank_Update.apk -o bank_update_decoded
grep -E "uses-permission|service" bank_update_decoded/AndroidManifest.xml
Типичный набор разрешений в таких образцах:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<service android:name=".AccessService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
</service>
Комбинация SYSTEM_ALERT_WINDOW + BIND_ACCESSIBILITY_SERVICE + доступ к SMS — практически всегда сигнатура overlay-трояна, независимо от названия семейства. Для более глубокого разбора логики подмены окон удобен jadx:
jadx-gui Bank_Update.apk
В декомпилированном коде обычно находится список пакетов-целей (ru.sberbankmobile, ru.vtb24.mobilebanking, com.idamob.tinkoff.android и т.д.) и метод, который слушает onAccessibilityEvent для отслеживания смены переднего окна.
4. Динамический анализ и подтверждение поведения
Для проверки, что именно происходит в момент открытия «банка», используется Frida — трассировка runtime-вызовов без исходников:
frida -U -f com.fake.bankupdate -l trace_overlay.js --no-pause
[*] onAccessibilityEvent: package=ru.sberbankmobile.online
[*] launching overlay activity: FakeLoginActivity
[*] SMS intercepted: code=482913, forwarded to C2
Более быстрый вариант для массовой проверки корпоративного парка APK — автоматизированный статический+динамический анализ через MobSF в докере:
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf
# затем загрузка APK через веб-интерфейс localhost:8000
MobSF сразу подсвечивает опасные комбинации разрешений и обфусцированный код, характерный для банковских троянов.
5. Логи на стороне устройства
Если заражение уже произошло и нужно подтвердить факт для отчёта клиенту или страховой, полезно поднять logcat и поискать привязку службы специальных возможностей:
adb logcat | grep -i accessibility
AccessibilityManagerService: Accessibility Service com.fake.bankupdate/.AccessService connected
Появление незнакомого пакета в списке подключённых Accessibility-сервисов — прямое доказательство компрометации.
Что и почему сработало бы дальше
380 000 рублей — это только то, что успели увидеть. Получив Accessibility-доступ, троян обычно не останавливается на одном банке:
- Перехватывает коды из push- и SMS-уведомлений любых других приложений — почты, мессенджеров, крипто-кошельков, второго банка, если он тоже установлен на этом телефоне
- Через Accessibility API имитирует нажатия — то есть может сам, без участия жертвы, кликать по кнопкам подтверждения перевода, если пользователь не успел заблокировать телефон
- В более развитых семействах есть модуль удалённого управления экраном (по типу VNC поверх MediaProjection), позволяющий оператору дистанционно управлять устройством в реальном времени
- Список контактов и переписка в мессенджерах используются для рассылки той же фишинговой ссылки — так атака масштабируется на других сотрудников и партнёров компании
Именно поэтому расследование одного инцидента на 380 000 ₽ всегда должно сопровождаться полной проверкой остальных корпоративных телефонов, а не только пострадавшего устройства.
Во что это обошлось компании
Прямые потери — 380 000 рублей, банк деньги не вернул: с юридической точки зрения операция подтверждена корректным кодом с устройства держателя счёта, и доказать факт компрометации телефона постфактум сложно. Косвенные потери оказались не меньше: неделя работы собственника ушла на переписку с банком и заявление в полицию вместо переговоров с поставщиками, а к менеджеру, который формально «сам всё подтвердил», временно перестали допускать переводы — хотя причиной была дыра в настройках телефона, а не человеческая ошибка в моменте платежа.
Как закрыли
Работы заняло два дня на весь парк рабочих телефонов, без внедрения дорогих систем.
-
Запрет установки из сторонних источников на уровне управления устройствами (Android Enterprise / MDM), а не только через системную настройку, которую пользователь может включить обратно:
adb shell settings put global install_non_market_apps 0 adb shell dpm set-device-owner com.company.mdm/.AdminReceiverЧерез управляемый Google Play (Android Enterprise) применяется корпоративная политика с белым списком приложений:
{ "applications": [ { "packageName": "ru.sberbankmobile.online", "installType": "REQUIRED" }, { "packageName": "com.company.internalapp", "installType": "REQUIRED" } ], "playStoreMode": "WHITELIST", "unknownSourcesAllowed": false, "adjustVolumeDisabled": true }При такой политике установка APK вне разрешённого списка физически недоступна пользователю без прав администратора MDM.
-
Переход с SMS-кодов на приложение-аутентификатор (TOTP: Google Authenticator, Яндекс Ключ или банковский аутентификатор с привязкой к устройству). Такие коды не проходят через SMS-канал и не читаются напрямую через
READ_SMS, что заметно повышает сложность перехвата — overl
