Всех приветствую. Под прошлой статьёй про малварь под русских мне написали хороший комментарий: "Хотелось бы побольше обзоров ещё и на разные форумные софты. Своего рода контроль качества". И вот это, честно, отличная формулировка. Потому что на форумах и в закрытых чатах такие штуки продают как готовые продукты: красивые скрины панели, списки фич, "стабильные 25 fps", "обход Secure screen", "PPass", "инжекты под банки и крипту". А что там реально внутри, покупатель чаще всего узнаёт уже после оплаты.
Так что сегодня будет ровно такой контроль качества. Я видел этот Android-софт в продаже на форуме, взял живой APK (не самый актуальный, но уже вышедший из бета-тестов) и проверил, соответствует ли реклама коду. Пока крупные ресёрч-команды пишут про новые Android-MaaS семейства вроде Albiriox, рынок таких "мобильных панелек" живёт своей жизнью: продавцы обещают VNC, AcVNC, обход чёрного экрана через Accessibility Node, live keylogger, PPass, сортировку жертв по ценности, инжекты под банки и крипту, и всё это в красивой веб-панели для оператора. На бумаге звучит как рекламный буклет для очередного скам-сервиса. Особенно когда за всё это просят не символические деньги, а что-то в районе 1420 долларов в месяц. Вопрос только один: это реально продукт такого уровня или очередной ИИ-комбайн, где часть фич работает, а часть просто красиво выглядит в треде?
Начнём снаружи. Уже по манифесту видно, что это не "просто приложение с видосиками". У него нет SMS-прав, то есть это не тот класс банкерa, который делает себя SMS-приложением по умолчанию. Тут другая философия: не перехват SMS, а полный удалённый контроль через Accessibility.
Разрешения говорят сами за себя:
- INTERNET, ACCESS_NETWORK_STATE, CHANGE_NETWORK_STATE - связь с C2
- QUERY_ALL_PACKAGES - посмотреть, какие приложения установлены
- SYSTEM_ALERT_WINDOW - рисовать окна поверх других приложений
- DISABLE_KEYGUARD - лезть в экран блокировки
- WAKE_LOCK - не давать телефону нормально засыпать
- RECEIVE_BOOT_COMPLETED - старт после перезагрузки
- REQUEST_IGNORE_BATTERY_OPTIMIZATIONS - просить исключение из энергосбережения
- SCHEDULE_EXACT_ALARM / USE_EXACT_ALARM - будильники и перезапуск
- REQUEST_DELETE_PACKAGES - запрашивать удаление приложений
- FOREGROUND_SERVICE и несколько foreground-service флагов - держаться в фоне
И самое главное, в services зарегистрирован:
com.nmz.nmz.AccessService
Это AccessibilityService. То есть весь смысл атаки в том, чтобы убедить жертву включить "спецвозможности" для приложения. А дальше Android сам отдаёт малвари дерево экрана, тексты, клики, фокусы, события ввода, возможность выполнять жесты и глобальные действия. Видеоплееру для взрослого тиктока это, конечно же, жизненно необходимо. Ну вы поняли.
Спойлер: сумрак
assets/ۦtolebafgliۖ۫hfqzgxa/ۦussjoۖ۫nz/ۦnsbۖ۫eninckks/qmosbulalۦۖ۫mtqyo/ۦuwctaqyۖ۫akarcx/wqiempxyۦۖpwyhngxqme۫/wlyۦۖdptaahgwit۫/sjۦۖ۫jzskgy/cijbrxakjۦۖrctfds۫/gjutsisoxۦۖ۫wmwbhj/wlapnumspۦۖ۫rc/ۦfpqjizdkeۖ۫gjb/hbۦۖqz۫/otqbhfpiۦۖdxlbl۫/tnlcaezۦۖkdthceuo۫/ۦxpsxtlpscۖ۫prk/ۦaqhۖ۫ibitwwj/kpcۦۖ۫rrkaqw/cuchtseoۦۖ۫fgxq/tberhlۦۖ۫yklpwpoqiwp/olykpngjaeۦۖ۫youwx/lqimnۦۖ۫wbckygyo/ekdgrjqaۦۖnxiezckrq۫/ۦcqۖ۫mdseo/ۦybyhhsyxebۖ۫ydbx/fbpngpfeۦۖ۫mopj/obbnkdmoyۦۖ۫xnyolp/kcaqۦۖ۫pgapzy/jjbfcatnmezۦۖ۫zzmb/ihocztgtuydۦۖazkmcbdi۫/dufdbhۦۖ۫pyriqzqtkau/gfaomuwxfmۦۖnbm۫/qmmۦۖqdmdaszeo۫/ۦzxyqekjcwۖ۫wdrlrkbfj/lrqsyxۦۖcxwejrcbo۫/ۦgcxkhgcۖ۫xylhskebpqs/crccpcpzgۦۖtmzqwoag۫/njewjcdfcxeۦۖlxibr۫/hugzdfrytqeۦۖ۫xho/ۦftwoxnycxouۖ۫ycpeu/rwۦۖ۫xmfecag/bqdkfniۦۖpafoy۫/luaۦۖrptcytld۫/pwqsxijdwgۦۖ۫ooez/ybhsjdۦۖfrmllcclbyl۫/ۦyqhzxwsrkujۖ۫xpjrsbwrog/ۦkkylczzۖ۫cgxw/ۦsdgfjwdfmۖ۫kjmn/upqucۦۖ۫wyyrjwxapll/hultۦۖ۫ca/ۦezyjrrxdgqgۖ۫nz/efۦۖ۫zmzpnpe/ۦpuodssrۖ۫cznncaecndn/apusmszۦۖ۫fdzyottzmm/okۦۖ۫jfmb/ۦsmwsnۖ۫bxyjmfnii/owtcpqgnۦۖ۫hm/uhlupslohwۦۖgufbyo۫/ۦfoitpkbiiۖ۫wrmqxyj/ۦwdxۖ۫linw/hywalsrhۦۖnoes۫/djkbtjۦۖygoczeqgx۫/uqdtaۦۖ۫qk/ۦhgpjnbjmtmaۖ۫scxejeuwkon/ۦltpdedxۖ۫yqxzdn/jcmbsiruoۦۖzzreukq۫/ۦhigۖ۫wkwphu/ounkifkۦۖ۫kzretcagyq/jhۦۖekodtoqtdad۫/kipssۦۖ۫acpxn/ۦcdۖ۫skf/rskۦۖ۫dlwbim/qowcuۦۖ۫zmyf/ۦymxoupdۖ۫ko/ۦuatkgyۖ۫rzyw/ۦheqcmwzqۖ۫eqyprctskg/ۦpylpicxdoۖ۫ouzo/ybzۦۖatisdlcakos۫/qymzjtkfuyۦۖxbla۫/tbۦۖ۫cxxqtlxqrr/beaffaizhisۦۖ۫xaljt/ۦslmamۖ۫rjew/ۦuhzwۖ۫zrkfjjmz/ۦloۖ۫xfbeei/immwۦۖcl۫/quxxnۦۖgesnlx۫/tnsyagoۦۖ۫cqhkiwbgib/ۦurqufbmyruwۖ۫cmzknmlp/ۦwcshynjۖ۫bsf/hlpwzxsgeqiۦۖ۫bkpseslzp/izdhۦۖpof۫/ql.json
com.diet.renew.Tkangaroostaff
И вот этот класс уже интересен. В нём есть методы, которые читают ql.json, расшифровывают его, распаковывают ZIP и подгружают реальные DEX. То есть манифест показывает нам вредоносные классы, но на диске в открытом виде их нет, пока стаб сам не распакует payload. Разбираем стаб. Он обфусцирован мусорными инструкциями, но логика простая. Есть строка-ключ - mbqMXi. И метод расшифровки, который выглядит как чистый RC4: KSA, swap массива S, потом PRGA и XOR байт payload. Функция g() делает swap, функция a() прогоняет байты через RC4. Никакой магии, просто коммерческий упаковщик с лёгким шифрованием.
Расшифровываем ql.json ключом mbqMXi. На выходе получаем зипку. Внутри которой уже самое заветное - classes.dex, и classes2.dex. Вот это уже настоящий код малвари. После распаковки jadx наконец видит com.nmz.nmz, AccessService, LoginActivity, Apps_Packages, AppInfos, AntiRemove, BlankOverlay и прочее добро.
BUILD_ID = "Crazy"
SERVER_IP = "185.208.156.239"
SERVER_PORT = 5555
FRAME_INTERVAL_MS = 40
PING_INTERVAL_MS = 15000
MAX_MISSED_PONGS = 7
ENABLE_LOGIN_OVERLAY = true
ENABLE_INJECTIONS = false
То есть билд называется Crazy, C2 сидит на 185.208.156.239:5555, кадр отправляется раз в 40 миллисекунд. 1000 / 40 = 25 fps. Это потом совпадёт с рекламой продавца про "стабильные 25 fps". Связь не HTTP и не WebSocket. Это сырой TCP через java.net.Socket. Протокол простой: 4 байта длины в big-endian, потом JSON. В JSON есть поле type. Входящие type=control идут в handleControlMessage, исходящие события тоже JSON'ом: handshake, app_list, crypto_apps, crypto_warning, live_key_event, device_password, phone_password, captured_credentials и так далее.
Что он делает при старте сервиса.
- создаёт WindowManager и PowerManager
- получает KeyguardManager
- генерирует/читает постоянный HWID
- пишет в лог модель устройства и C2
- поднимает wake locks
- просит игнорировать battery optimization
- ставит WorkManager-задачу ServiceKeeper
- ставит doze-resistant alarm
- стартует connection manager
- поднимает foreground service
- регистрирует receiver для учёток/оверлеев
В handshake на сервер уходит.
- type = handshake
- build_id = Crazy
- version = 2.1
- deviceModel = MANUFACTURER + MODEL
- hwid
- androidId
- manufacturer
- androidVersion
- apiLevel
- brand
- device
- fps = 25
captureScreenshot()
sendScreenshotBitmap()
startScreenshotCaptureThread()
Картинка сжимается в JPEG/WEBP, кладётся в Base64 и отправляется на C2 с полями screenWidth, screenHeight, imageData, frameNumber, queueSize. Для новых Android используется путь через SurfaceControl/HardwareBuffer (jadx часть этого куска декомпилировал криво, но Bitmap создаётся явно). Если кадр слишком большой, качество режется, есть fallback на JPEG 30%.
Второй режим - frame capture через Accessibility. Метод captureAndSendFrame() собирает информацию по текущему UI и тоже шлёт кадрами. Поток называется FrameCaptureThread, интервал 40 мс, в статистике логируется:
Mode: SCREENSHOT / ACCESSIBILITY
FPS
Frames
Skipped
Так что пункт "VNC, отрисовка происходящего на экране" правда.
Плюс глобальные действия Android:
performGlobalAction(1) - назад
performGlobalAction(2) - домой
performGlobalAction(3) - recent/multitask
performGlobalAction(6) - power/dialog/lock-related action
performGlobalAction(8) - ещё одно системное действие, используется при пробуждении/экране
Есть adjustVolume(true/false), то есть Vol+ и Vol- тоже есть. Есть wakeUpDevice(), wakeWithWakeLock(), wakeWithAccessibilityAction(). Если сравнивать с тем что написано в треде о аренда софта, то мы пока идем очень даже отлично, до несостыковок недокопаться!)
Keylogger и Live Keylogger. Тут NMZ сделал не просто "сохранять текст из EditText". Они слушают AccessibilityEvent и собирают практически всё. За что отдельный респект.
- TYPE_VIEW_TEXT_CHANGED
- клики по кнопкам
- className
- viewIdResourceName
- координаты элемента
- text
- password flag
- изменения masked input
То есть обычный keylogger и live keylogger на Accessibility Node есть. Причём live-режим может быть очень шумным, потому что Accessibility генерирует много событий, но в рекламе продавец сам пишет, что его использование должно быть обусловлено.
type = device_password
password
password_type
confidence
locked_state
attempt_count
input_sequence
Спойлер: все приложения
public static final Set<String> CRYPTO_PACKAGES = new HashSet<String>() { // from class: com.nmz.nmz.AppInfos.1
{
add("com.wallet.crypto.trustapp");
add("io.metamask");
add("io.metamask.mobile");
add("com.coinbase.android");
add("piuk.blockchain.android");
add("com.bitcoin.mwallet");
add("com.bitpay.wallet");
add("com.breadwallet");
add("com.mycelium.wallet");
add("com.electrum.electrum");
add("com.coinomi.wallet");
add("io.atomicwallet");
add("com.exodus.exodus");
add("com.safepal.wallet");
add("org.toshi");
add("com.ledger.live");
add("com.tangem.wallet");
add("io.zerion.android");
add("com.rainbow.me");
add("com.argent.app");
add("com.alphawallet.app");
add("com.wallet.mobile");
add("im.token.app");
add("com.viabtc.wallet");
add("com.guarda.wallet");
add("com.freewallet.monero");
add("com.trezor.suite");
add("com.unstoppable.money");
add("com.enjin.mobile.wallet");
add("com.mathwallet.android");
add("com.tokenpocket.android");
add("com.phantom.app");
add("app.solflare.mobile");
add("com.sollet.app");
add("com.slope.wallet");
add("com.glow.wallet");
add("com.terrastation.mobile");
add("wannabit.io.cosmostaion");
add("com.keplr.wallet");
add("com.xdefi.wallet");
add("com.frontier.wallet");
add("com.pillar.wallet");
add("com.gnosis.safe");
add("com.portis.wallet");
add("com.fortmatic.wallet");
add("com.walletconnect.wallet");
add("com.opera.crypto");
add("com.brave.browser");
add("com.status.ethereum");
add("com.jaxx.liberty");
add("com.edge.app");
add("com.zelcore.wallet");
add("com.infinitowallet");
add("com.klever.wallet");
add("com.onto.wallet");
add("com.cybavo.wallet");
add("com.cobo.wallet");
add("com.coolbitx.cwallet");
add("com.d4wallet.app");
add("com.ballet.wallet");
add("com.keyst.app");
add("com.zengo.wallet");
add("com.blue.wallet");
add("com.greenaddress.greenbits_android_wallet");
add("com.muunwallet");
add("com.nunchuk.android");
add("com.sparrowwallet.sparrow");
add("com.wasabiwallet.mobile");
add("com.samourai.wallet");
add("com.blockstream.green");
add("com.casa.wallet");
add("com.phoenix.wallet");
add("com.lightning.wallet");
add("com.breez.client");
add("com.getumbrel.app");
add("com.zap.wallet");
add("fr.acinq.eclair.wallet");
add("com.binance.dev");
add("com.binancemini");
add("co.mona.android");
add("com.kraken.trade");
add("com.kraken.pro");
add("com.bitfinex.mobileapp");
add("com.bybit.app");
add("com.okex.gp");
add("com.okx.calculator");
add("com.gateio.gateio");
add("com.kucoin.kumex");
add("com.huobi.gp");
add("com.huobi.pro");
add("com.htx.app");
add("com.crypto.exchange");
add("com.ftx.mobile");
add("com.gemini.android.app");
add("com.bittrex.trade");
add("com.poloniex.app");
add("com.bitstamp.app");
add("com.cex.app.prod");
add("com.luno.android");
add("com.bitso.wallet");
add("com.mexc.mexcpro");
add("com.bitmex.app");
add("com.phemex.android");
add("com.etoro.wallet");
add("com.etoro.openbook");
add("com.libertex.mobile");
add("com.exness.investor");
add("com.bitget.app");
add("com.bingx.app");
add("com.pionex.app");
add("com.ascendex.app");
add("com.probit.app");
add("com.liquid.app");
add("com.bitmart.app");
add("com.whitebit.app");
add("com.latoken.app");
add("com.coinsbit.app");
add("com.bitbns.app");
add("com.wazirx.app");
add("com.zebpay.app");
add("com.paxful.wallet");
add("com.localbitcoins.app");
add("com.changelly.app");
add("com.changeangel.app");
add("com.shapeshift.droid_shapeshift");
add("com.simpleswap.app");
add("com.swapzone.app");
add("com.stormgain.mobile");
add("com.primexbt.app");
add("com.bitmexgo.app");
add("com.deribit.app");
add("com.cryptofacilities.app");
add("com.delta.exchange");
add("com.btse.app");
add("com.aax.app");
add("com.bitflyer.app");
add("com.zaif.android");
add("com.coincheck.android");
add("com.bithumb.app");
add("com.upbit.exchange");
add("com.korbit.app");
add("com.coinone.android");
add("com.gopax.app");
add("com.indodax.app");
add("com.tokocrypto.app");
add("com.bitcoin.id");
add("com.coinhako.app");
add("com.coins.ph");
add("com.mercadobitcoin.app");
add("com.bitcointrade.app");
add("com.foxbit.app");
add("com.bitkub.app");
add("com.satang.pro");
add("com.btcturk.app");
add("com.paribu.app");
add("com.rain.app");
add("com.bitpanda.app");
add("com.bitvavo.app");
add("com.bitcoin.de");
add("com.litebit.app");
add("com.btcdirect.app");
add("com.coinmama.app");
add("com.coinjar.app");
add("com.coinspot.app");
add("com.btcmarkets.app");
add("com.independentreserve.app");
add("com.swyftx.app");
add("com.uniswap.mobile");
add("com.sushi.mobile");
add("org.pancakeswap.web");
add("com.dydx.mobile");
add("com.aave.mobile");
add("com.compound.mobile");
add("com.defi.wallet");
add("com.celsius.network");
add("com.nexo.wallet");
add("com.blockfi.mobile");
add("com.1inch.wallet");
add("com.curve.mobile");
add("com.balancer.mobile");
add("com.yearn.finance");
add("com.makerdao.mobile");
add("com.synthetix.mobile");
add("com.bancor.wallet");
add("com.kyberswap.android");
add("com.loopring.wallet");
add("com.thorchain.mobile");
add("com.osmosis.mobile");
add("com.raydium.mobile");
add("com.serum.dex");
add("com.orca.mobile");
add("com.quickswap.mobile");
add("com.spookyswap.mobile");
add("com.spiritswap.mobile");
add("com.traderjoe.mobile");
add("com.benqi.mobile");
add("com.venus.protocol");
add("com.alpaca.finance");
add("com.beefy.finance");
add("com.autofarm.network");
add("com.harvest.finance");
add("com.idle.finance");
add("com.cream.finance");
add("com.instadapp.mobile");
add("com.defisaver.app");
add("com.furucombo.app");
add("com.opensea.mobile");
add("com.rarible.mobile");
add("com.niftygateway.mobile");
add("com.superrare.mobile");
add("com.foundation.app");
add("com.makersplace.mobile");
add("com.knownorigin.mobile");
add("com.asyncart.mobile");
add("com.mintable.app");
add("com.zora.mobile");
add("com.magiceden.mobile");
add("com.solanart.app");
add("com.blur.mobile");
add("com.looksrare.mobile");
add("com.x2y2.mobile");
add("com.axieinfinitygame");
add("com.decentraland.mobile");
add("com.sandbox.mobile");
add("com.illuvium.mobile");
add("com.godsunchained.mobile");
add("com.sorare.app");
add("com.cryptokitties.mobile");
add("com.alienworlds.mobile");
add("com.splinterlands.mobile");
add("com.nicehash.mobile");
add("com.minergate.mobile");
add("com.cryptotab.android");
add("com.stormgain.miner");
add("com.honeyminer.mobile");
add("com.kryptex.app");
add("com.stakewise.app");
add("com.lido.mobile");
add("com.rocketpool.mobile");
add("com.blockfolio.blockfolio");
add("com.coinstats.app");
add("com.cointracker.android");
add("com.delta.app");
add("com.coinmarketcap.android");
add("com.coingecko.app");
add("com.cryptocompare.mobile");
add("com.coincodex.app");
add("com.livecoinwatch.app");
add("com.cryptopanic.mobile");
add("com.cryptowat.ch");
add("com.tradingview.tradingviewapp");
add("com.paypal.android");
add("com.cashapp");
add("com.venmo");
add("com.revolut.revolut");
add("com.robinhood.android");
add("com.webull.android");
add("com.sofi.app");
add("com.wirexapp.wirex");
add("com.crypto.visa");
add("com.binance.card");
add("com.bitpay.card");
add("com.coinbase.card");
add("com.nexo.card");
add("com.blockcard.app");
add("com.fold.app");
add("com.spedn.app");
add("com.moon.pay");
add("com.ramp.network");
add("com.transak.app");
add("com.wyre.app");
add("com.banxa.app");
add("com.simplex.app");
add("com.mercuryo.app");
add("com.wellsfargo.ceomobile");
add("com.wf.wellsfargomobile");
add("com.infonow.bofa");
add("com.chase.sig.android");
add("com.schwab.mobile");
add("com.fidelity.investments");
add("com.pnc.ecommerce.mobile");
add("com.konylabs.capitalone");
add("com.chime.prod");
add("com.bmo.mobile");
add("com.citizensbank.androidapp");
add("com.truist.mobile");
add("com.etrade.mobilepro.activity");
add("com.tastytrade.tastytrade");
add("com.vanguard.personalinvestors");
add("com.citi.citimobile");
add("com.usbank.mobilebanking");
add("com.tdbank");
add("com.ally.MobileBanking");
add("com.regions.mobbanking");
add("com.fifththird.mobile");
add("com.key.android");
add("com.huntington.m");
add("com.mtb.mbanking.sc.retail");
add("com.suntrust.mobilebanking");
add("com.bb_t.android");
add("com.zionsbank.zions");
add("com.americanexpress.android.acctsvcs");
add("com.discover.dfs.mobile");
add("com.marcus");
add("com.goldmansachs.gsuam");
add("com.morganstanley.clientserv.mobile");
add("com.jpmorgan.mobile.react");
add("com.bankofthewest.mobile");
add("com.navyfederal.android");
add("com.usaa.mobile.android.usaa");
add("com.pentagon.pfcu");
add("com.td");
add("com.rbc.mobile.android");
add("com.bmo.mobile.banking");
add("com.scotiabank.mobile");
add("ca.tangerine.clients.banking.app");
add("com.cibc.android.mobi");
add("ca.bnc.android");
add("com.desjardins.mobile");
add("com.hsbc.hsbccanada");
add("com.koho");
add("ca.paymi.paymi");
add("com.barclays.android.barclaysmobilebanking");
add("com.lloydsbank.businessmobile");
add("com.grppl.android.shell.halifax");
add("uk.co.santander.santanderUK");
add("uk.co.hsbc.hsbcukmobilebanking");
add("com.natwest.mobile.android.rbs");
add("com.rbs.mobile.android.rbs");
add("uk.co.metrobankonline.mobile");
add("uk.co.tsb.newmobilebank");
add("com.firstdirect.bankingonthego");
add("com.revolut.revolut");
add("com.monzo.android");
add("com.starlingbank.android");
add("de.dkb.portalapp");
add("de.commerzbank.kontostand");
add("com.db.mm.deutschebank");
add("com.ing.mobile");
add("nl.abnamro.nl.mobile.payments");
add("nl.rabomobiel");
add("com.bnpparibas.mescomptes");
add("mobi.societegenerale.mobile.lappli");
add("com.creditagricole.androidapp");
add("com.caisseepargne.android.mobilebanking");
add("es.lacaixa.mobile.android.newwapicon");
add("com.bbva.bbvacontigo");
add("es.santander.money");
add("com.unicredit");
add("com.intesasanpaolo.mobile");
add("ch.ubs.mobileBanking");
add("com.cs.android.creditsuisse");
add("com.n26.n26");
add("com.wirecard.boon.pt");
add("com.transferwise.android");
add("com.bunq.android");
add("com.dbs.sg.dbsmbanking");
add("com.ocbc.mobile");
add("com.uob.mighty");
add("com.StandardCharteredMobileBanking.ng");
add("com.axis.mobile");
add("com.sbi.SBIFreedomPlus");
add("com.icicibank.imobile");
add("com.hdfcbank.hdfcbankmobilebanking");
add("com.kotak.mobile");
add("com.paytm");
add("com.phonepe.app");
add("in.amazon.mShop.android.shopping");
add("com.mobikwik");
add("net.one97.paytm");
add("jp.co.smbc.direct");
add("jp.co.mizuhobank.mizuhodirect");
add("jp.mufg.bk.applisp.app");
add("jp.co.japannetbank.smtapp");
add("jp.co.rakuten_bank.rakutenbank");
add("com.kasikornbank.retail.kplusmbd");
add("com.scb.easy");
add("com.bbl.mobilebanking");
add("com.krungsri.kma");
add("com.tmb.mbanking");
add("au.com.cba.mobile.android");
add("au.com.westpac.mobile");
add("au.com.anz.mobile");
add("au.com.nab.mobile");
add("au.com.bankwest.mobile");
add("au.com.ingdirect.mobile");
add("au.com.suncorp.SuncorpBank");
add("com.macquarie.banking");
add("com.itau");
add("com.bb.mobile");
add("com.bradesco");
add("com.santander.app");
add("com.nu.production");
add("com.picpay");
add("com.mercadopago");
add("com.bancointer");
add("com.c6bank.app");
add("com.bancolombia.app");
add("com.davivienda.app");
add("com.banorte.app");
add("com.banamex.app");
add("com.bbva.mx");
add("com.hsbc.mx");
add("com.robinhood.android");
add("com.webull.android");
add("com.tdameritrade.mobile");
add("com.interactivebrokers.mobile");
add("com.thinkorswim");
add("com.merrilledge.app");
add("com.sofi.app");
add("com.stash.stashapp");
add("com.acorns.android");
add("com.betterment.app");
add("com.wealthfront.app");
add("com.personalcapital.android");
add("com.bloomberg.android.anywhere");
add("com.reuters.mobile");
add("com.moomoo.app");
add("com.public.app");
add("com.m1finance.android");
add("com.dough.app");
add("com.firstrade.firstrade");
add("com.tradestation.mobile");
add("com.lightspeed.mobile");
add("com.ig.android.markets");
add("com.plus500.app");
add("com.cmcmarkets.android.cfd");
add("com.avatrade.mobile");
add("com.forex.forexcom");
add("com.oanda.fxtrade");
add("com.varo.bank");
add("com.current.app");
add("com.dave.banking");
add("com.albert");
add("com.moneylion");
add("com.earnin.app");
add("com.brigit.app");
add("com.empower.app");
add("com.aspiration.app");
add("com.oxygen.app");
add("com.lili.app");
add("com.novo.app");
add("com.bluevine.app");
add("com.mercury.app");
add("com.brex.app");
}
};
}
И вот тут после первого прохода я, честно, сам слишком мягко отнёсся к этому списку. Огромный target-list выглядит солидно: крипта, банки, DeFi, NFT, трейдинг, финтех, всё подряд. Но когда дальше по коду начинаешь видеть ИИ-запах, хочется вернуться и пройтись по этому списку внимательнее. И тут внезапно выясняется, что "огромный список таргетов" не равен "качественная база реальных Android-приложений". Берём простой пример - OpenSea. В списке RAT лежит.
com.opensea.mobile
А у реального приложения в Google Play package id другой:
io.opensea
Для Android это не "почти то же самое", а две разные строки. PackageManager не будет угадывать, что автор имел в виду. Клиент ищет установленный пакет com.opensea.mobile, а если у жертвы стоит настоящий io.opensea, то по этой строке он его просто не найдёт. Ладно, допустим, человеческая ошибка. Бывает. Проверяем дальше.
Sparrow Wallet. В списке видим:
com.sparrowwallet.sparrow
Пробуем найти мобильное приложение, а в Google Play по такому id пусто. Чуть-чуть гуглим и вспоминаем, что Sparrow Wallet - это вообще десктопный кошелёк. То есть тут уже не просто опечатка в namespace, а типичная генерация в стиле "взять название известного криптокошелька и придумать ему Android package name".
Бог любит троицу, берём Trezor. В списке:
com.trezor.suite
А реальный Google Play пакет Trezor Suite:
io.trezor.suite
И снова то же самое: бренд угадан, package id нет. Для человека это выглядит как мелочь, но для кода это критично. com.trezor.suite и io.trezor.suite - разные приложения. RAT с таким списком будет искать не то, что реально установлено. Дальше уже можно не играть в "ну может совпадение". Я прогнал список по Google Play: из 441 уникального package id сейчас нормально находятся только 123, а 318 отдают 404. Сам по себе 404 ещё не смертный приговор: приложение могло быть удалено, быть недоступным в регионе или распространяться не через Play Store. Но когда рядом лежат desktop-only кошельки, выдуманные package names, мёртвые биржи и дубли, картина становится весёлой. В списке есть com.ftx.mobile, com.aax.app, com.blockfi.mobile, com.celsius.network, com.localbitcoins.app, com.bittrex.trade - сервисы, которые уже закрывались, банкротились или уходили с рынка. Есть целые пачки DeFi/NFT-проектов в формате com.aave.mobile, com.compound.mobile, com.yearn.finance, com.opensea.mobile, com.foundation.app, com.blur.mobile, будто кто-то попросил: "накидай Android package names для популярных крипто/DeFi/NFT брендов". И ещё банальные дубли: com.revolut.revolut, com.robinhood.android, com.webull.android, com.sofi.app. Вот тут уже начинается тот самый контроль качества. Target detect как механизм в клиенте есть: он реально собирает список установленных приложений и отправляет его на C2. Но качество базы таргетов местами такое, будто её не руками проверяли, а сгенерировали широкой сетью, потом даже не почистили. И за продукт за 1420 долларов в месяц это, мягко говоря, странный уровень. Одно дело использовать ИИ как помощника, другое - продавать клиентам "премиальный MaaS", где часть target-list ищет приложения, которых под такими package id просто нет. И раз уж пошёл ревизит, давайте честно отделим реальные признаки от шума. Во-первых, логи. По коду раскиданы галочки, замочки, предупреждения и статусы в стиле учебного pet-project: "✓ Successfully launched app", "✓ LOGIN DATA CAPTURED!", ":lock: SHOWING LOGIN FORM", ":lock: BLOCKING APP ACCESS", ":warning: LoginActivity stuck - force resetting flag", ":warning: AUTO-RESET: LoginActivity flag stuck after 10 seconds", ":rotating_light: CRYPTO WARNING SENT!". . Во-вторых, качество debug-логики. В LoginActivity прямо есть "PIN CAPTURED!", "PASSWORD CAPTURED!", а рядом даже "PIN: " + значение. Понятно, что это клиентская часть малвари, а не банковское приложение, но всё равно смешно: продукт за такие деньги сам палит в логах чувствительные события и местами чувствительные значения. Плюс куча костылей вокруг зависшего LoginActivity: active - skipping, stuck - force resetting flag, AUTO-RESET через 10 секунд. Это похоже не на вылизанный фреймворк, а на проект, который быстро дописывали, ловили гонки и затыкали таймерами. В-третьих, AntiRemove. Там не просто проверка удаления, а огромный словарь uninstall/remove на десятках языков, включая русский, украинский и белорусский: "удалить", "деинсталлировать", "видалити", "деінсталювати", "выдаліць", "дэінсталяваць". При этом явного гео-фильтра по Locale/SIM/country/timezone в клиенте я не увидел, а российских банков в финансовом target-list тоже нет. Поэтому вывод аккуратный: это не доказывает работу по СНГ, но странно бьётся с форумной риторикой "по своим не работаем". Скорее всего, список слов просто нагенерили "для всех языков сразу" и вставили без тонкой политики регионов.
ENABLE_INJECTIONS = false
ENABLE_LOGIN_OVERLAY = true
LoginActivity запускается поверх целевого приложения, получает targetPackageName и app_type, подставляет имя приложения, рисует PIN/password экран, а потом запускает оригинальное приложение обратно. В коде есть showLoginOverlay(), launchLoginActivity(), captured_credentials, EXTRA_PACKAGE_NAME, EXTRA_APP_TYPE.
То есть правильная формулировка: в этом билде есть overlay/phishing injects, в том числе под Trust Wallet; классических банковских инжектов я не увидел, но это не повод поднимать шумиху и так далее, билд у меня не очень свежий.
Отдельно по Trust Wallet подключён кастомный layout input.xml.
LIMB