Як Android-траян Gustuff здымае сліўкі (фіят і крыпту) з вашых рахункаў

Як Android-траян Gustuff здымае сліўкі (фіят і крыпту) з вашых рахункаў

Літаральна на днях Group-IB паведамляла аб актыўнасці мабільнага Android-траяна Gustuff. Ён працуе выключна на міжнародных рынках, атакуючы кліентаў 100 найбуйнейшых замежных банкаў, карыстальнікаў мабільных 32 криптокошельков, а таксама буйных e-commerce рэсурсаў. А вось распрацоўшчык Gustuff - рускамоўны кіберзлачынца пад нікам Bestoffer. Яшчэ нядаўна ён нахвальваў свой траян як "сур'ёзны прадукт для людзей са ведамі і вопытам".

Спецыяліст па аналізе шкоднаснага кода Group-IB Іван Пісараў у сваім даследаванні падрабязна распавядае аб тым, як працуе Gustuff і ў чым яго небяспека.

За кім палюе Gustuff

Gustuff адносіцца да новага пакалення шкоднасных праграм з цалкам аўтаматызаванымі функцыямі. Па словах распрацоўніка, траян стаў новай палепшанай версіяй шкоднаснай праграмы AndyBot, якая з лістапада 2017 года атакуе тэлефоны з АС Android і крадзе грошы праз фішынгавыя вэб-формы, якія маскіруюцца пад мабільныя прыкладанні вядомых міжнародных банкаў і плацежных сістэм. Bestoffer паведамляў, што кошт арэнды "Gustuff Bot" складала $ 800 у месяц.

Аналіз сэмпла Gustuff паказаў, што патэнцыйна траян накіраваны на кліентаў, якія выкарыстоўваюць мабільныя прыкладанні найбуйнейшых банкаў, такіх як Bank of America, Bank of Scotland, JPMorgan, Wells Fargo, Capital One, TD Bank, PNC Bank, а таксама на криптокошельки Bitcoin Wallet, BitPay , Cryptopay, Coinbase і інш.

Першапачаткова створаны як класічны банкаўскі траян, у бягучай версіі Gustuff значна пашырыў спіс патэнцыйных аб'ектаў для нападу. Акрамя Android-прыкладанняў банкаў, фінтэх-кампаній і крыптасэрвісаў, Gustuff накіраваны на карыстальнікаў прыкладанняў маркетплэйсаў, анлайн-крам, плацежных сістэм і месэнджараў. У прыватнасці, PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut і іншых.

Кропка ўваходу: разлік на масавае заражэнне

Для Gustuff характэрны "класічны" вектар пранікнення на Android-смартфоны праз СМС-рассыланні са спасылкамі на APK. Пры заражэнні Android-прылады траянам па камандзе сервера можа адбыцца далейшае распаўсюджванне Gustuff'а па базе кантактаў інфікаванага тэлефона або па базе дадзеных сервера. Функцыянальныя магчымасці Gustuff разлічаны на масавае заражэнне і максімальную капіталізацыю бізнесу сваіх аператараў – у ім прысутнічае унікальная функцыя «аўтазаліва» у легітымныя мабільныя банкаўскія прыкладанні і криптокошельки, што дазваляе паскорыць і маштабаваць крадзеж грошай.

Даследаванне траяна паказала, што функцыя аўтазаліва рэалізаваная ў ім пры дапамозе Accessibility Service – сэрвісу для людзей з абмежаванымі магчымасцямі. Gustuff - не першы траян, які паспяхова абыходзіць абарону ад узаемадзеяння з элементамі вокнаў іншых прыкладанняў з дапамогай дадзенага сэрвісу Android. Аднак выкарыстанне Accessibility Service у спалучэнні з аўтазалівам застаецца да гэтага часу досыць рэдкай з'явай.

Пасля загрузкі на тэлефон ахвяры Gustuff, выкарыстоўваючы Accessibility Service, атрымлівае магчымасць узаемадзейнічаць з элементамі вокнаў іншых прыкладанняў (банкаўскіх, криптовалютных, а таксама прыкладанняў для анлайн-шопінгу, абмену паведамленнямі і інш.), выконваючы неабходныя для зламыснікаў дзеянні. Да прыкладу, па камандзе сервера траян можа націскаць на кнопкі і змяняць значэнні тэкставых палёў у банкаўскіх дадатках. Выкарыстанне механізму Accessibility Service дазваляе траяну абыходзіць механізмы абароны, выкарыстоўваныя слоікамі для процідзеяння мабільным траянам мінулага пакаленні, а таксама змены ў палітыцы бяспекі, укаранёныя Google у новыя версіі АС Android. Так, Gustuff "умее" адключаць абарону Google Protect: па запэўненнях аўтара, дадзеная функцыя спрацоўвае ў 70% выпадкаў.

Як Android-траян Gustuff здымае сліўкі (фіят і крыпту) з вашых рахункаў

Таксама Gustuff можа дэманстраваць фэйкавыя PUSH-паведамленні з абразкамі легітымных мабільных прыкладанняў. Карыстальнік клікае на PUSH-паведамленне і бачыць загружанае з сервера фішынгавае акно, куды сам уводзіць запытаныя дадзеныя банкаўскай карты або крыптакашалька. У іншым сцэнары працы Gustuff адбываецца адкрыццё прыкладання, ад імя якога дэманстравалася PUSH-апавяшчэнне. У гэтым выпадку шкоднасная праграма па камандзе сервера праз Accessibility Service можа запаўняць палі формы банкаўскага прыкладання для ашуканскай транзакцыі.

У функцыянальныя магчымасці Gustuff таксама ўваходзяць адпраўка на сервер інфармацыі аб заражанай прыладзе, магчымасць чытання/адпраўлення СМС-паведамленняў, адпраўленне USSD-запытаў, запуск SOCKS5 Proxy, пераход па спасылцы, адпраўленне файлаў (у тым ліку фотасканаў дакументаў, скрыншотаў, фатаграфій) на сервер , скід прылады да завадскіх налад.

Аналіз шкоднаснай праграмы

Перад усталёўкай шкоднаснага прыкладання АС Android дэманструе карыстачу акно, утрымоўвальнае ў сабе спіс запытаных Gustuff'ом мае рацыю:

Як Android-траян Gustuff здымае сліўкі (фіят і крыпту) з вашых рахункаў
Устаноўка прыкладання адбудзецца толькі пасля атрымання згоды карыстальніка. Пасля запуску прыкладання траян пакажа карыстачу акно:

Як Android-траян Gustuff здымае сліўкі (фіят і крыпту) з вашых рахункаў
Пасля чаго выдаліць свой абразок.

Gustuff спакаваны, па словах аўтара, пакавальнікам ад FTT. Пасля запуску прыкладанне перыядычна звяртаецца да CnC-сервера з мэтай атрымання каманд. У некалькіх даследаваных намі файлах у якасці кіраўніка сервера выкарыстоўваўся IP-адрас 88.99.171[.]105 (у далейшым будзем пазначаць як <%CnC%>).

Пасля запуску праграма пачынае адпраўку паведамленняў серверу http://<%CnC%>/api/v1/get.php.

У якасці адказу чакаецца JSON наступнага фармату:

{
    "results" : "OK",
    "command":{
        "id": "<%id%>",
        "command":"<%command%>",
        "timestamp":"<%Server Timestamp%>",
        "params":{
		<%Command parameters as JSON%>
        },
    },
}

Пры кожным звароце прыкладанне адпраўляе інфармацыю аб заражанай прыладзе. Фармат паведамлення прадстаўлены ніжэй. Варта адзначыць, што палі Поўны, дадаткова, прыкладання и дазвол - апцыянальныя і будуць адпраўленыя толькі ў выпадку каманды-запыту ад CnC.

{
    "info":
    {
        "info":
        {
            "cell":<%Sim operator name%>,
            "country":<%Country ISO%>,
            "imei":<%IMEI%>,
            "number":<%Phone number%>,
            "line1Number":<%Phone number%>,
            "advertisementId":<%ID%>
        },
        "state":
        {
            "admin":<%Has admin rights%>,
            "source":<%String%>,
            "needPermissions":<%Application needs permissions%>,
            "accesByName":<%Boolean%>,
            "accesByService":<%Boolean%>,
            "safetyNet":<%String%>,
            "defaultSmsApp":<%Default Sms Application%>,
            "isDefaultSmsApp":<%Current application is Default Sms Application%>,
            "dateTime":<%Current date time%>,
            "batteryLevel":<%Battery level%>
        },
        "socks":
        {
            "id":<%Proxy module ID%>,
            "enabled":<%Is enabled%>,
            "active":<%Is active%>
        },
        "version":
        {
            "versionName":<%Package Version Name%>,
            "versionCode":<%Package Version Code%>,
            "lastUpdateTime":<%Package Last Update Time%>,
            "tag":<%Tag, default value: "TAG"%>,
            "targetSdkVersion":<%Target Sdk Version%>,
            "buildConfigTimestamp":1541309066721
        },
    },
    "full":
    {
        "model":<%Device Model%>,
        "localeCountry":<%Country%>,
        "localeLang":<%Locale language%>,
        "accounts":<%JSON array, contains from "name" and "type" of accounts%>,
        "lockType":<%Type of lockscreen password%>
    },
    "extra":
    {
        "serial":<%Build serial number%>,
        "board":<%Build Board%>,
        "brand":<%Build Brand%>,
        "user":<%Build User%>,
        "device":<%Build Device%>,
        "display":<%Build Display%>,
        "id":<%Build ID%>,
        "manufacturer":<%Build manufacturer%>,
        "model":<%Build model%>,
        "product":<%Build product%>,
        "tags":<%Build tags%>,
        "type":<%Build type%>,
        "imei":<%imei%>,
        "imsi":<%imsi%>,
        "line1number":<%phonenumber%>,
        "iccid":<%Sim serial number%>,
        "mcc":<%Mobile country code of operator%>,
        "mnc":<%Mobile network codeof operator%>,
        "cellid":<%GSM-data%>,
        "lac":<%GSM-data%>,
        "androidid":<%Android Id%>,
        "ssid":<%Wi-Fi SSID%>
    },
    "apps":{<%List of installed applications%>},
    "permission":<%List of granted permissions%>
} 

Захоўванне канфігурацыйных дадзеных

Gustuff захоўвае важную для працы інфармацыю ў preference-файле. Імя файла, як і імёны параметраў у ім - вынік вылічэнні MD5-сумы ад радка 15413090667214.6.1<%name%>, Дзе <%name%> - зыходнае імя-значэнне. Python-інтэрпрэтацыя функцыі генерацыі імя:

 nameGenerator(input):
    output = md5("15413090667214.6.1" + input) 

У далейшым будзем пазначаць як nameGenerator(input).
Такім чынам, імя першага файла: nameGenerator("API_SERVER_LIST"), ён змяшчае значэння з наступнымі імёнамі:

Імя зменнай Значэнне
nameGenerator("API_SERVER_LIST") Змяшчае спіс CnC-адрасоў у выглядзе масіва.
nameGenerator("API_SERVER_URL") Змяшчае CnC-адрас.
nameGenerator("SMS_UPLOAD") Сцяг па змаўчанні ўсталяваны. Калі сцяг усталяваны - адпраўляе СМС-паведамленні на CnC.
nameGenerator("SMS_ROOT_NUMBER") Нумар тэлефона, на які будуць адпраўлены SMS-паведамленні прынятыя заражанай прыладай. Па змаўчанні null.
nameGenerator("SMS_ROOT_NUMBER_RESEND") Сцяг па змаўчанні скінуты. Калі ўсталяваны - пры атрыманні заражанай прыладай SMS яно будзе адпраўлена на root-нумар.
nameGenerator("DEFAULT_APP_SMS") Сцяг па змаўчанні скінуты. Калі дадзены сцяг усталяваны – дадатак будзе апрацоўваць уваходныя SMS-паведамленні.
nameGenerator("DEFAULT_ADMIN") Сцяг па змаўчанні скінуты. Калі сцяг усталяваны - прыкладанне мае правы адміністратара.
nameGenerator("DEFAULT_ACCESSIBILITY") Сцяг па змаўчанні скінуты. Калі сцяг усталяваны - запушчаны сэрвіс, які выкарыстоўвае Accessibility Service.
nameGenerator("APPS_CONFIG") JSON-аб'ект, утрымоўвае спіс дзеянняў, якія неабходна выканаць пры спрацоўванні Accessibility-падзеі, злучанага з вызначаным дадаткам.
nameGenerator("APPS_INSTALLED") Захоўвае спіс устаноўленых на прыладзе дадаткаў.
nameGenerator("IS_FIST_RUN") Флаг пры першым запуску скідаецца.
nameGenerator(«UNIQUE_ID») Змяшчае унікальны ідэнтыфікатар. Генеруецца пры першым запуску робата.

Модуль апрацоўкі каманд ад сервера

Дадатак захоўвае адрасы CnC-сервераў у выглядзе масіва закадаваных па База85 радкоў. Спіс CnC - сервераў можа быць зменены пры паступленні адпаведнай каманды, у такім выпадку адрасы будуць захоўваецца ў preference-файле.

У адказ на запыт сервер адпраўляе з дадаткам каманду. Варта адзначыць, што каманды і параметры прадстаўлены ў JSON-фармаце. Прыкладанне можа апрацоўваць наступныя каманды:

Каманда Апісанне
forwardStart Пачаць адпраўленне атрыманых заражанай прыладай SMS-паведамленняў на CnC-сервер.
forwardStop Спыніць адпраўленне SMS-паведамленняў на CnC-сервер, якія атрымліваюцца заражанай прыладай.
ussdRun Выканаць USSD-запыт. Нумар, на які неабходна здзейсніць USSD-запыт знаходзіцца ў JSON-поле "number".
sendSms Адправіць адно SMS-паведамленне (пры неабходнасці паведамленне "драбніцца" на часткі). У якасці параметру каманда прымае JSON-аб'ект, які змяшчае палі "to" - нумар прызначэння і "body" - цела паведамлення.
sendSmsAb Адправіць SMS-паведамленні (пры неабходнасці паведамленне «драбніцца» на часткі) усім са спісу кантактаў заражанай прылады. Інтэрвал паміж адпраўленнем паведамленняў - 10 секунд. Цела паведамлення знаходзіцца ў JSON-поле «body»
sendSmsMass Адправіць SMS-паведамленні (пры неабходнасці паведамленне «драбніцца» на часткі) кантактам, указаным у параметрах каманды. Інтэрвал паміж адпраўленнем паведамленняў - 10 секунд. У якасці параметру каманда прымае JSON-масіў (поле "sms"), элементы якога ўтрымоўваюць палі "to" - нумар прызначэння і "body" - цела паведамлення.
changeServer Дадзеная каманда ў якасці параметру можа прымаць значэнне з ключом "url" - тады бот зменіць значэнне nameGenerator("SERVER_URL"), або "array" - тады бот запіша масіў у nameGenerator ("API_SERVER_LIST") Такім чынам прыкладанне змяняе адрас CnC-сервераў.
adminNumber Каманда прызначана для працы з root-нумарам. Каманда прымае JSON-аб'ект з наступнымі параметрамі: "number" - змяніць nameGenerator("ROOT_NUMBER") на атрыманае значэнне, "resend" - змяніць nameGenerator("SMS_ROOT_NUMBER_RESEND"), "sendId" - адправіць на nameGenerator("RO
updateInfo Адправіць на сервер інфармацыю аб заражанай прыладзе.
wipeData Каманда прызначана для выдалення карыстацкіх дадзеных. У залежнасці ад якога імя было запушчана прыкладанне адбываецца альбо поўнае сціранне дадзеных з перазагрузкай прылады (primary user), альбо выдаленне толькі карыстацкіх дадзеных (secondary user).
socksStart Запусціць Proxy-модуль. Праца модуля апісана ў асобным раздзеле.
socksStop Спыніць працу Proxy-модуля.
openLink Перайсці па спасылцы. Спасылка знаходзіцца ў JSON-параметры па ключы "url". Для адкрыцця спасылкі выкарыстоўваецца "android.intent.action.VIEW".
uploadAllSms Адправіць на сервер усе прынятыя прыладай SMS-паведамленні.
uploadAllPhotos Адправіць на URL выявы з заражанага прылады. URL прыходзіць як параметр.
загрузіць файл Адправіць на URL файл з заражанай прылады. URL прыходзіць як параметр.
uploadPhoneNumbers Адправіць на сервер нумары тэлефонаў са спісу кантактаў. Калі ў якасці параметру прыходзіць JSON-аб'ект значэнне з ключом "ab", прыкладанне атрымлівае спіс кантактаў з тэлефоннай кнігі. Калі ў якасці параметру прыходзіць JSON-аб'ект з ключом "sms", прыкладанне чытае спіс кантактаў з адпраўнікаў SMS-паведамленняў.
changeArchive Прыкладанне загружае файл з адраса, які прыходзіць у якасці параметру па ключы "url". Загружаны файл захоўваецца з імем "archive.zip". Пасля гэтага прыкладанне разархівуе файл, пры неабходнасці выкарыстоўваючы пароль для архіва "b5jXh37gxgHBrZhQ4j3D". Разархіваваны файлы захоўвае ў дырэкторыю [external storage]/hgps. У дадзенай дырэкторыі прыкладанне захоўвае web-фейкі (апісана далей).
дзеянні Каманда прызначана для працы з Action Service, які апісаны ў асобнай частцы.
тэст Нічога не робіць.
спампаваць Каманда прызначана для загрузкі файла з выдаленага сервера і захаванні яго ў дырэкторыю "Downloads". URL і імя файла прыходзяць у якасці параметру, палі ў JSON-аб'екце параметры адпаведна: "url" і "fileName".
выдаленне Выдаляе файл з дырэкторыі "Downloads". Імя файла прыходзіць у JSON-параметры з ключом "fileName". Стандартнае імя файла - "tmp.apk".
апавяшчэнне Паказаць апавяшчэнне з тэкстамі апісання і загалоўка, якія вызначаюцца кіруючым серверам.

Фармат каманды апавяшчэнне:

{
    "results" : "OK",
    "command":{
    "id": <%id%>,
    "command":"notification",
    "timestamp":<%Server Timestamp%>,
    "params":{
        "openApp":<%Open original app or not%>,
        "array":[
                      {"title":<%Title text%>,
                      "desc":<%Description text%>,
                      "app":<%Application name%>}
                   ]
                   },
        },
}

Апавяшчэнне, якое ствараецца доследным файлам, выглядае ідэнтычна апавяшчэнням, ствараным дадаткам, паказаным у поле прыкладанне. Калі значэнне поля openApp - True, пры адкрыцці апавяшчэння запускаецца дадатак, паказанае ў поле прыкладанне. Калі значэнне поля openApp - False, то:

  • адкрываецца фішынгавае акно, змесціва якога загружаецца з дырэкторыі <%external storage%>/hgps/<%filename%>
  • адкрываецца фішынгавае акно, змесціва якога загружаецца з сервера <%url%>?id=<%Bot id%>&app=<%Application name%>
  • адкрываецца фішынгавае акно, замаскіраванае пад Google Play Card, з магчымасцю ўвесці дадзеныя карты.

Вынік выканання любой каманды дадатак адпраўляе на <%CnC%>set_state.php у выглядзе JSON-аб'екта наступнага фармату:

{
    "command":
    {
        "command":<%command%>,
        "id":<%command_id%>,
        "state":<%command_state%>
    }
    "id":<%bot_id%>
}

ActionsService
У спіс каманд, якія апрацоўвае дадатак, уваходзіць дзеянне. Пры атрыманні каманды модуль апрацоўкі каманд звяртаецца да дадзенага сэрвісу з мэтай выканання пашыранай каманды. У якасці параметру сэрвіс прымае JSON-аб'ект. Сэрвіс можа выконваць наступныя каманды:

1. PARAMS_ACTION - пры атрыманні такой каманды сэрвіс у першую чаргу атрымлівае з JSON-параметра значэнне па ключы Type, можа быць наступным:

  • serviceInfo - падкаманда атрымлівае з JSON-параметра значэнне па ключы includeNotImportant. Калі сцяг роўны True — дадатак устанаўлівае сцяг. FLAG_ISOLATED_PROCESS на сэрвіс, які выкарыстоўвае Accessibility Service. Такім чынам, сервіс будзе запушчаны ў асобным працэсе.
  • корань - атрымаць і адправіць на сервер інфармацыю аб акне, якое цяпер у фокусе. Прыкладанне атрымлівае інфармацыю пры дапамозе класа AccessibilityNodeInfo.
  • адмін - запытаць правы адміністратара.
  • затрымка — прыпыніць працу ActionsService на тую колькасць мілісекунд, якая пазначана ў параметры па ключы «data».
  • вокны - адправіць спіс бачных карыстачу вокнаў.
  • ўсталёўваць - Устанавіць дадатак на заражаную прыладу. Назва пакета - архіва знаходзіцца ў ключы "fileName". Сам архіў знаходзіцца ў дырэкторыі Downloads.
  • глабальнай – падкаманда прызначана для ажыццяўлення пераходу з бягучага акна:
    • на меню Quick Settings
    • назад
    • дадому
    • да апавяшчэнняў
    • да акна нядаўна адкрытых прыкладанняў

  • запуск - запусціць прыкладанне. Найменне прыкладання прыходзіць як параметр па ключы gegevens.
  • гукі - Змяніць рэжым гуку на silence.
  • адамкнуць - Уключае падсвятленне экрана і клавіятуры на поўную яркасць. Прыкладанне выконвае дадзенае дзеянне пры дапамозе WakeLock, у якасці тэга паказвае радок [Application lable]: INFO
  • permissionOverlay - функцыя не рэалізаваная (адказ на выкананне каманды - {«message»:«Not support»} або {«message»:«low sdk»})
  • жэст - функцыя не рэалізаваная (адказ на выкананне каманды - {«message»:«Not support»}або {«message»:«Low API»})
  • дазволаў - Дадзеная каманда неабходна для запыту правоў для прыкладання. Аднак функцыя запыту не рэалізаваная, такім чынам каманда ня мае сэнсу. Спіс запытаных правоў прыходзіць як JSON-масіў з ключом "permissions". Стандартны спіс:
    • android.permission.READ_PHONE_STATE
    • android.permission.READ_CONTACTS
    • android.permission.CALL_PHONE
    • android.permission.RECEIVE_SMS
    • android.permission.SEND_SMS
    • android.permission.READ_SMS
    • android.permission.READ_EXTERNAL_STORAGE
    • android.permission.WRITE_EXTERNAL_STORAGE

  • адкрыць - вывесці на экран фішынгавае акно. У залежнасці ад прыходнага ад сервера параметру прыкладанне можа дэманстраваць наступныя фішынгавыя вокны:
    • Паказаць фішынгавае акно, змесціва якога прапісана ў файле ў дырэкторыі <%external directory%>/hgps/<%param_filename%>. Вынік узаемадзеяння карыстальніка з акном будзе адпраўлены па адрасе <%CnC%>/records.php
    • Паказаць фішынгавае акно, змесціва якога папярэдне грузіцца з адрасу <%url_param%>?id=<%bot_id%>&app=<%packagename%>. Вынік узаемадзеяння карыстальніка з акном будзе адпраўлены па адрасе <%CnC%>/records.php
    • Паказаць фішынгавае акно, замаскіраванае пад Google Play Card.

  • інтэрактыўны - каманда прызначана для ўзаемадзеяння з элементамі вокнаў іншых прыкладанняў пры дапамозе AcessibilityService. Для ўзаемадзеяння ў праграме рэалізаваны спецыяльны сэрвіс. Доследнае прыкладанне можа ўзаемадзейнічаць з вокнамі:
    • Актыўным на дадзены момант. У такім выпадку параметр утрымоўвае id або text (назва) аб'екта, з якім неабходна ўзаемадзейнічаць.
    • Бачным карыстачу на момант выканання каманды. Прыкладанне выбірае вокны па id.

    Атрымаўшы аб'екты AccessibilityNodeInfo для якія цікавяць элементаў акна, прыкладанне ў залежнасці ад параметраў можа выконваць дзеянні:

    • focus - усталяваць фокус на аб'ект.
    • click - клікнуць на аб'ект.
    • actionId - выканаць дзеянне па ID.
    • setText - змяніць тэкст аб'екта. Змена тэксту магчыма двума спосабамі: выканаць дзеянне ACTION_SET_TEXT (калі версія Android заражанай прылады - маладзей або роўная LOLLIPOP), альбо змясціўшы ў буфер абмену радок і уставіўшы яго ў аб'ект (для версій старэй). Дадзеная каманда можа быць выкарыстана для змены даных у банкаўскім дадатку.

2. PARAMS_ACTIONS - тое ж, што і PARAMS_ACTION, толькі прыходзіць JSON-масіў каманд.

Здаецца, шмат каму будзе цікава, як выглядае функцыя ўзаемадзеяння з элементамі акна іншага прыкладання. Вось такім чынам рэалізавана дадзеная функцыянальная магчымасць у Gustuff'е:

boolean interactiveAction(List aiList, JSONObject action, JsonObject res) {
    int count = action.optInt("repeat", 1);
    Iterator aiListIterator = ((Iterable)aiList).iterator();
    int count = 0;
    while(aiListIterator.hasNext()) {
        Object ani = aiListIterator.next();
        if(1 <= count) {
            int index;
            for(index = 1; true; ++index) {
                if(action.has("focus")) {
                    if(((AccessibilityNodeInfo)ani).performAction(1)) {
                        ++count;
                    }
                }
                else if(action.has("click")) {
                    if(((AccessibilityNodeInfo)ani).performAction(16)) {
                        ++count;
                    }
                }
                else if(action.has("actionId")) {
                    if(((AccessibilityNodeInfo)ani).performAction(action.optInt("actionId"))) {
                        ++count;
                    }
                }
                else if(action.has("setText")) {
                    customHeader ch = CustomAccessibilityService.a;
                    Context context = this.getApplicationContext();
                    String text = action.optString("setText");
                    if(performSetTextAction(ch, context, ((AccessibilityNodeInfo)ani), text)) {
                        ++count;
                    }
                }
                if(index == count) {
                    break;
                }
            }
        }
        ((AccessibilityNodeInfo)ani).recycle();
    }
    res.addPropertyNumber("res", Integer.valueOf(count));
}

Функцыя замены тэксту:

boolean performSetTextAction(Context context, AccessibilityNodeInfo ani, String text) {
    boolean result;
    if(Build$VERSION.SDK_INT >= 21) {
        Bundle b = new Bundle();
        b.putCharSequence("ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE", ((CharSequence)text));
        result = ani.performAction(0x200000, b);  // ACTION_SET_TEXT
    }
    else {
        Object clipboard = context.getSystemService("clipboard");
        if(clipboard != null) {
        ((ClipboardManager)clipboard).setPrimaryClip(ClipData.newPlainText("autofill_pm", ((CharSequence)text)));
        result = ani.performAction(0x8000);  // ACTION_PASTE
        }
        else {
            result = false;
        }
    }
    return result;
}

Такім чынам, пры правільнай наладзе кіраўніка сервера Gustuff здольны запоўніць тэкставыя палі ў банкаўскім дадатку і націснуць на неабходныя для здзяйснення транзакцыі кнопкі. Траяну нават не трэба праходзіць аўтарызацыю ў дадатку - дастаткова адправіць каманду на дэманстрацыю PUSH-паведамлення з наступным адкрыццём раней устаноўленага банкаўскага прыкладання. Карыстальнік сам пройдзе аўтарызацыю, пасля чаго Gustuff зможа зрабіць аўтазаліў.

Модуль апрацоўкі СМС-паведамленняў

Дадатак устанаўлівае апрацоўшчык падзеі на прыняцце заражаным прыладай СМС-паведамленняў. Доследнае прыкладанне можа прымаць каманды ад аператара, якія прыходзяць у целе СМС- паведамленні. Каманды прыходзяць у фармаце:

7!5=<%Base64 encoded command%>

Дадатак шукае ва ўсіх надыходзячых СМС-паведамленнях радок 7!5=, пры выяўленні радка – дэкадуе з Base64 радок па зняцці 4 і выконвае каманду. Каманды аналагічныя камандам з CnC. Вынік выканання адпраўляецца на той самы нумар, з якога паступіла каманда. Фармат адказу:

7*5=<%Base64 кода "result_code command"%>

Апцыянальна прыкладанне можа адпраўляць усе прыманыя паведамленні на Root-нумар. Для гэтага ў preference-файле павінен быць паказаны Root-нумар і ўсталяваны сцяг рэдырэкту паведамленняў. СМС-паведамленне адпраўляецца на нумар зламысніка ў фармаце:

<%From number%> - <%Time, format: dd/MM/yyyy HH:mm:ss%> <%SMS body%>

Таксама апцыянальна прыкладанне можа адпраўляць паведамленні на CnC. СМС-паведамленне адпраўляецца на сервер у JSON-фармаце:

{
    "id":<%BotID%>,
    "sms":
    {
        "text":<%SMS body%>,
        "number":<%From number%>,
        "date":<%Timestamp%>
    }
}

Калі ўсталяваны сцяг nameGenerator("DEFAULT_APP_SMS") - Дадатак спыняе апрацоўку СМС-паведамленні і чысціць спіс уваходных паведамленняў.

Proxy-модуль

У доследным дадатку прысутнічае Backconnect Proxy модуль (далей Proxy-модуль), які мае асобны клас, які ўключае ў сябе статычныя палі з канфігурацыяй. Канфігурацыйныя дадзеныя захоўваюцца ў сэмпле ў адкрытым выглядзе:

Як Android-траян Gustuff здымае сліўкі (фіят і крыпту) з вашых рахункаў

Усе дзеянні, якія здзяйсняюцца Proxy-модулем, лагуюцца ў файлы. Для гэтага прыкладанне ў External Storage стварае дырэкторыю з назвай "logs" (поле ProxyConfigClass.logsDir у канфігурацыйным класе), у якой захоўваюцца лог-файлы. Лагіраванне адбываецца ў файлы з імёнамі:

  1. main.txt - у дадзены файл адбываецца лагіраванне працы класа з назвай CommandServer. У далейшым лагіраванне радка str у дадзены файл будзем пазначаць як mainLog(str).
  2. session-<%id%>.txt - У дадзены файл адбываецца захаванне лог-дадзеных, злучаных з вызначанай сесіяй праксіравання. У далейшым лагіраванне радка str у дадзены файл будзем пазначаць як sessionLog (str).
  3. server.txt – у дадзены файл адбываецца лагіраванне ўсіх дадзеных, якія запісваюцца ў вышэйапісаныя файлы.

Фармат лог-дадзеных:

<%Date%> [Thread[<%thread id%>], id[]]: log-string

Якія ўзнікаюць падчас прац Proxy-модуля выключэння таксама лагуюцца ў файл. Для гэтага прыкладанне фармуе JSON-аб'ект фармату:

{
    "uncaughtException":<%short description of throwable%>
    "thread":<%thread%>
    "message":<%detail message of throwable%>
    "trace":        //Stack trace info
        [
            {
                "ClassName":
                "FileName":
                "LineNumber":
                "MethodName":
            },
            {
                "ClassName":
                "FileName":
                "LineNumber":
                "MethodName":
            }
        ]
}

Пасля чаго канвертуе яго ў радковае паданне і лагуе.

Запуск Proxy-модуля ажыццяўляецца пасля паступлення які адпавядае пакоі. Пры паступленні каманды на запуск Proxy-модуля дадатак запускае сэрвіс з назвай MainService, які адказвае за кіраванне працай Proxy-модуля - яго запуск і прыпынак.

Этапы запуску сэрвісу:

1. Запускае таймер, які спрацоўвае раз у хвіліну і правярае актыўнасць Proxy-модуля. Калі модуль не актыўны - запускае яго.
Таксама пры спрацоўванні падзеі android.net.conn.CONNECTIVITY_CHANGE адбываецца запуск Proxy-модуля.

2. Прыкладанне стварае wake-lock з параметрам PARTIAL_WAKE_LOCK і захоплівае яго. Такім чынам не дазваляе перайсці CPU прылады ў спячы рэжым.

3. Запускае клас апрацоўкі каманд Proxy-модуля, папярэдне лагіруючы радок mainLog("start server") и

Server::start() host[<%proxy_cnc%>], commandPort[<%command_port%>], proxyPort[<%proxy_port%>]

дзе proxy_cnc, command_port і proxy_port – параметры, атрыманыя з канфігурацыі Proxy-сервера.

Клас апрацоўкі каманд мае назву CommandConnection. Адразу пасля запуску выконвае наступныя дзеянні:

4. Падключаецца да ProxyConfigClass.host: ProxyConfigClass.commandPort і адпраўляе туды дадзеныя аб заражанай прыладзе ў JSON-фармаце:

{
    "id":<%id%>,
    "imei":<%imei%>,
    "imsi":<%imsi%>,
    "model":<%model%>,
    "manufacturer":<%manufacturer%>,
    "androidVersion":<%androidVersion%>,
    "country":<%country%>,
    "partnerId":<%partnerId%>,
    "packageName":<%packageName%>,
    "networkType":<%networkType%>,
    "hasGsmSupport":<%hasGsmSupport%>,
    "simReady":<%simReady%>,
    "simCountry":<%simCountry%>,
    "networkOperator":<%networkOperator%>,
    "simOperator":<%simOperator%>,
    "version":<%version%>
}

Дзе:

  • id - ідэнтыфікатар, спрабуе атрымаць з Shared Preference файла з імем "x" значэнне з полем "id". Калі дадзенае значэнне атрымаць не ўдалося - генеруе новае. Такім чынам, Proxy-модуль мае свой ідэнтыфікатар, які генеруецца аналагічна Bot ID.
  • imei - IMEI прылады. Калі ў працэсе атрымання значэння адбылася памылка - замест гэтага поля будзе запісана тэкставае паведамленне аб памылцы.
  • imsi - International Mobile Subscriber Identity прылады. Калі ў працэсе атрымання значэння адбылася памылка - замест гэтага поля будзе запісана тэкставае паведамленне аб памылцы.
  • model - end-user-visible name for the end product.
  • Manufacturer – Manufacturer of Product/hardware (Build.MANUFACTURER).
  • androidVersion - радок у фармаце «<% release_version%> (<% os_version%>), <% sdk_version%>»
  • country - бягучае месцазнаходжанне прылады.
  • partnerId - пусты радок.
  • packageName - package name.
  • networkType - тып бягучага сеткавага злучэння (прыклад: "WIFI", "MOBILE"). У выпадку памылкі вяртае null.
  • hasGsmSupport - true - калі тэлефон падтрымлівае GSM, інакш false.
  • simReady - стан SIM-карты.
  • simCountry - ISO-код краіны (на падставе правайдэра сім-карты).
  • networkOperator - найменне аператара. Калі ў працэсе атрымання значэння адбылася памылка - замест гэтага поля будзе запісана тэкставае паведамленне аб памылцы.
  • simOperator – The Service Provider Name (SPN). Калі ў працэсе атрымання значэння адбылася памылка - замест гэтага поля будзе запісана тэкставае паведамленне аб памылцы.
  • version – гэта поле захоўваецца ў конфіг-класе, для доследных версій робата яно было роўна «1.6».

5. Пераходзіць у рэжым чакання каманд ад сервера. Каманды ад сервера паступаюць у фармаце:

  • 0 offset - command
  • 1 offset - sessionId
  • 2 offset - length
  • 4 offset - data

Пры паступленні каманды дадатак лагуе:
mainLog(«Header { sessionId<%id%>], type[<%command%>], length[<%length%>] }»)

Магчымыя наступныя каманды ад сервера:

Імя Каманда Дата Апісанне
connectionId 0 Ідэнтыфікатар злучэння Стварыць новае падлучэнне
сну 3 час Прыпыніць працу Proxy-модуля
PING_PONG 4 - Адправіць PONG-паведамленне

PONG-паведамленне складаецца з 4 байт і выглядае наступным чынам: 0x04000000.

Пры паступленні каманды connectionId (на стварэнне новага падлучэння) CommandConnection стварае экзэмпляр класа ProxyConnection.

  • У праксіраванні бяруць удзел два класы: ProxyConnection и канец. Пры стварэнні класа ProxyConnection адбываецца падлучэнне да адрасу ProxyConfigClass.host: ProxyConfigClass.proxyPort і перадача JSON-аб'екта:

 {
    "id":<%connectionId%>
}

У адказ сервер дасылае SOCKS5-паведамленне, якое ўтрымоўвае адрас выдаленага сервера, з якім неабходна ўсталяваць злучэнне. Узаемадзеянне з гэтым серверам адбываецца з дапамогай класа канец. Схематычна ўстаноўку злучэння можна ўявіць наступным чынам:

Як Android-траян Gustuff здымае сліўкі (фіят і крыпту) з вашых рахункаў

Сеткавыя ўзаемадзеянні

Для прадухілення аналізу трафіку сеткавымі сніферамі ўзаемадзеянне паміж CnC-серверам і дадаткам можа быць абаронена з дапамогай пратаколу SSL. Усе перадаваемыя дадзеныя як з сервера так і на сервер прадстаўлены ў JSON-фармаце. Прыкладанне падчас працы выконвае наступныя запыты:

  • http://<%CnC%>/api/v1/set_state.php - Вынік выканання каманды.
  • http://<%CnC%>/api/v1/get.php - атрыманне каманды.
  • http://<%CnC%>/api/v1/load_sms.php - выгрузка SMS-паведамленняў з заражанай прылады.
  • http://<%CnC%>/api/v1/load_ab.php - выгрузка спісу кантактаў з заражанай прылады.
  • http://<%CnC%>/api/v1/aevents.php – запыт робіцца пры абнаўленні параметраў, якія знаходзяцца ў preference-файле.
  • http://<%CnC%>/api/v1/set_card.php - выгрузка дадзеных, атрыманых пры дапамозе фішынг-акна, які маскіруецца пад Google Play Market.
  • http://<%CnC%>/api/v1/logs.php - выгрузка лог-дадзеных.
  • http://<%CnC%>/api/v1/records.php - выгрузка дадзеных, атрыманых пры дапамозе фішынгавых вокнаў.
  • http://<%CnC%>/api/v1/set_error.php – апавяшчэнне аб узніклай памылцы.

Рэкамендацыі

У мэтах абароны сваіх кліентаў ад пагрозы мабільных траянаў кампаніі павінны выкарыстоўваць комплексныя рашэнні, якія дазваляюць без усталёўкі дадатковага праграмнага забеспячэння на прылады карыстальнікаў, адсочваць і папярэджваць шкоднасную актыўнасць.

Для гэтага сігнатурныя метады выяўлення мабільных траянаў неабходна ўзмацняць тэхналогіямі аналізу паводзін як кліента, так і самога дадатку. Гэтак жа абарона павінна складацца з функцыю ідэнтыфікацыі прылад з выкарыстаннем тэхналогіі лічбавага адбітка, што дазволіць зразумець, калі ўліковы запіс выкарыстоўваецца з нетыповай прылады і ўжо патрапіла ў рукі ашуканца.

Прынцыпова важны момант - наяўнасць магчымасці крос-канальнага аналізу, што дае магчымасць кампаніям кантраляваць рызыкі, якія ўзнікаюць на баку не толькі інтэрнэт-, але і мабільнага канала, напрыклад, у дадатках для мабільнага банкінгу, для аперацый з криптовалютами і любых іншых, дзе можа ажыццяўляцца фінансавая транзакцыя.

Правілы бяспекі для карыстальнікаў:

  • не ўсталёўваць прыкладанні для мабільнай прылады з АС Android з якія-небудзь крыніц, акрамя Google Play, звяртаць адмысловую ўвагу на запытаныя дадаткам правы;
  • рэгулярна ўсталёўваць абнаўленні АС Android;
  • зважаць на пашырэнні загружаных файлаў;
  • не наведваць падазроныя рэсурсы;
  • не пераходзіць па спасылках, атрыманых у SMS-паведамленнях.

Пры ўдзеле Сямёна Рагачова, малодшага спецыяліста па даследаванні шкоднаснага кода Лабараторыі камп'ютарнай крыміналістыкі Group-IB.

Крыніца: habr.com

Дадаць каментар