Android 11中执行Bash脚本启动Metasploit Stage时遭遇SecurityException权限拒绝错误的排查与解决
Android 11下执行Metasploit持久化脚本触发SecurityException的原因与解决方法
错误原因分析
你遇到的SecurityException核心是这句:
Permission Denial: package=com.android.shell does not belong to uid=10463
这是Android 11(API 30)权限管控升级导致的:
- UID与包名绑定校验:Android 11在
ActivityTaskManagerService的assertPackageMatchesCallingUid方法中新增了严格校验——调用am start的进程,其包名对应的UID必须和当前调用进程的UID完全匹配。你用adb shell执行命令时,默认身份是com.android.shell(UID为2000),而你的Metasploit payload应用com.metasploit.stage的UID是10463,两者不匹配,直接被系统拦截。 - 另外,Android 11对后台启动Activity也有严格限制,就算权限问题解决了,后台进程随意启动Activity也可能被系统阻止,但你当前的核心问题还是UID/包名不匹配的权限问题。
解决方法
针对这个问题,有几个可行的解决方向:
1. 切换到payload应用的UID环境执行命令
使用run-as命令切换到目标应用的身份下执行am start,这样调用者的UID就和应用一致了,能绕过校验。修改后的脚本如下:
#!/bin/bash while true; do run-as com.metasploit.stage am start -a android.intent.action.MAIN -n com.metasploit.stage/.MainActivity sleep 20 done
注意:run-as仅支持debug签名的应用,如果你的payload是release签名,这个方法无法使用,此时需要依赖root权限。
2. 利用root权限执行命令
如果设备已经root,直接切换到root用户执行命令,root拥有最高权限,不受UID校验限制。修改脚本:
#!/bin/bash while true; do su -c "am start --user 0 -a android.intent.action.MAIN -n com.metasploit.stage/.MainActivity" sleep 20 done
3. 换更合规的持久化方案(推荐)
循环启动Activity的方式不仅容易被系统拦截,还很容易被用户察觉。针对Metasploit持久化,你可以采用更符合Android规则的方式:
- 注册系统启动广播接收器:监听
android.intent.action.BOOT_COMPLETED广播,在设备开机后自动启动meterpreter会话。 - 使用前台服务:让payload以前台服务的形式运行,既不会被系统轻易杀死,也能避免后台启动Activity的限制。
- 利用JobScheduler:定期调度任务唤醒payload进程,保持会话存活。
额外注意事项
即使解决了UID问题,Android 11及以上系统中,后台进程直接启动Activity还需要满足"应用处于前台可见状态"的条件。如果你的payload在后台,直接启动Activity可能会被系统拦截,此时可以通过发送通知,让用户点击通知来启动Activity,或者先将应用切换到前台再执行启动操作。
内容的提问来源于stack exchange,提问作者Cobra 444




