返回
互联网金融APP反编译攻防
Android
2023-09-26 15:38:44
众所周知,H5+JS接口+Webview这种混合开发模式十分普遍,市场上面绝大部分应用或多或少都是用了。
本文实例讲解的是当前市场上用户量较大的一款互联网金融APP,注册用户数几百万,流水达几十亿。在本文之前已经将漏洞告知对方,这里为了保密不提及应用名称,包名。
虽然讲述了需多攻击技术,但本文重点还是放在攻防结合上面,在漏洞披露之前修复掉了。
漏洞发现
1. 环境搭建
反编译工具
Apktool 2.5.0
jd-gui
JEB
AndroidKiller
2.反编译
1)使用apktool反编译
java -jar apktool_2.5.0.jar d -f 80090041.apk
2)解压classes.dex文件
java -jar dex2jar-2.0.jar classes.dex
3)使用jd-gui打开jar文件
jd-gui classes-dex2jar.jar
3. 调试
正常情况下APP和Webview是通过JSInterface来调用的,在目标项目代码里搜寻关键词:
addJavascriptInterface
找到相关代码:
this.webview.addJavascriptInterface(new JSBridge(this), "JSBridge");
一般情况下,JS代码都可以直接通过WebviewClient的shouldOverrideUrlLoading回调函数拦截到,但是在APP里却没有这个回调,换句话说,这些JS代码都是在WebView内部执行的。
没办法只能用传统方法,断点调试,查看JSBridge具体做了什么。
1)加载需要用到的工具
AndroidKiller 2.0.2
2)用AndroidKiller定位到WebView控件
AKViewFinder finder = new AKViewFinder(this);
WebView view = (WebView) finder.findViewById("com.package.name", "id/webview");
3)找到并打开对应的smali文件
0002:invoke-virtual/range {v1 .. v1}, Landroid/webkit/WebView;->getSettings:()Landroid/webkit/WebSettings;
0003:const/4 v2, 0x1
0004:invoke-virtual/range {v1 .. v2}, Landroid/webkit/WebSettings;->setJavaScriptEnabled:(Z)V
0005:const/4 v2, 0x1
0006:invoke-virtual/range {v1 .. v2}, Landroid/webkit/WebSettings;->setJavaScriptCanOpenWindowsAutomatically:(Z)V
0007:invoke-virtual/range {v1 .. v1}, Landroid/webkit/WebView;->addJavascriptInterface:()Landroid/webkit/WebChromeClient;
WebView相关代码比较简单,主要核心在JSBridge这个类,具体代码如下:
public class JSBridge {
private Context context;
public JSBridge(Context context) {
this.context = context;
}
@JavascriptInterface
public void getUerInfo(String callback) {
UserInfo userInfo = new UserInfo();
userInfo.setUserName("XX");
userInfo.setNickName("XX");
userInfo.setSex("XX");
userInfo.setPhone("XX");
String json = JSON.toJSONString(userInfo);
callback(json);
}
@JavascriptInterface
public void callback(String json) {
Log.e("JSBridge", json);
}
}
这个JSBridge类一共有两个方法,分别是getUerInfo
和callback
。
4.利用
1)JS注入
在需要调用接口的页面使用DomInspector注入JS代码:
var getUerInfo = document.createElement('script');
getUerInfo.type = 'text/javascript';
getUerInfo.textContent = "(function(){JSBridge.getUerInfo('callback');})()";
document.body.appendChild(getUerInfo);
注入完代码后,当页面加载完成就会自动调用getUerInfo
方法,然后在callback
方法打印出来的就是用户的信息,这些信息也就可以上传到服务器。
2)钓鱼网站
和普通的钓鱼网站差不多,使用一个和APP一样的登录页面,然后注入JS代码去调用接口,用户在访问钓鱼网站时,先输入账号密码登录,登录后触发JS脚本,获取到用户信息后,传给钓鱼网站,钓鱼网站就可以通过这些信息来登录APP,进而操作用户账户。
漏洞修复
1.代码审计
- 审计JSBridge类中的代码,发现
getUerInfo
方法没有做任何参数验证,直接把用户信息传给了JS,这就存在注入的风险。 - 审计WebView相关代码,发现并没有对JS代码进行任何拦截或限制,这就导致JS代码可以在WebView内部任意执行。
2.代码修复
- 修改
getUerInfo
方法,对参数进行验证,只允许传入白名单中的参数。 - 在WebView中添加JS代码拦截和限制,只允许执行白名单中的JS代码。
3.修复效果验证
- 重新编译、打包、安装APP。
- 运行APP,访问需要调用接口的页面,发现注入的JS代码无法执行了。
- 使用DomInspector工具,发现JSBridge类中的
getUerInfo
方法的参数已经受限了,只能传入白名单中的参数。