漏洞概要 关注数(24) 关注此漏洞
缺陷编号:wooyun-2015-0149563
漏洞标题:友盟SDK通用app升级过程存在缺陷可被中间人攻击利用植入木马
相关厂商:友盟
漏洞作者: 路人甲
提交时间:2015-10-26 23:15
修复时间:2015-12-17 14:48
公开时间:2015-12-17 14:48
漏洞类型:非授权访问/认证绕过
危害等级:高
自评Rank:20
漏洞状态:厂商已经确认
漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]
Tags标签: 无
漏洞详情
披露状态:
2015-10-26: 细节已通知厂商并且等待厂商处理中
2015-10-29: 厂商已经确认,细节仅向厂商公开
2015-11-01: 细节向第三方安全合作伙伴开放(绿盟科技、唐朝安全巡航)
2015-12-23: 细节向核心白帽子及相关领域专家公开
2016-01-02: 细节向普通白帽子公开
2016-01-12: 细节向实习白帽子公开
2015-12-17: 细节向公众公开
简要描述:
友盟SDK中自动更新(Android)版本,返回数据可以被中间人劫持,校验过程不严格,伪造升级包让app自动下载,进而植入木马。
根据测试,有的app使用友盟host进行更新,有的app使用自己的host进行更新,但是绝大部分app使用友盟sdk的app升级时,服务器返回数据为明文,且包含更新app包的url地址,可以直接劫持进行修改。
而根据友盟官网,友盟服务超过64万款APP。
详细说明:
友盟SDK中自动更新(Android)版本,返回数据可以被中间人劫持,校验过程不严格,伪造升级包让app自动下载,进而植入木马。
根据测试,有的app使用友盟host进行更新,有的app使用自己的host进行更新,但是绝大部分app使用友盟sdk的app升级时,服务器返回数据为明文,且包含更新app包的url地址,可以直接劫持进行修改。
而根据友盟官网,友盟服务超过64万款APP。
随手对友盟官网的app进行测试
1 当贝市场
升级更新发包
拦截后,修改其中url地址,返回数据包
效果如下
2 穷游
使用fiddler拦截,修改返回url
效果图
3 豆瓣
使用fiddler拦截,修改返回url
效果图
4 中华万年历
使用fiddler拦截,修改返回url
效果图
不管app是使用友盟的host,还是自己的host,都可以对其进行url拦截,修改。
漏洞证明:
友盟SDK中自动更新(Android)版本,返回数据可以被中间人劫持,校验过程不严格,伪造升级包让app自动下载,进而植入木马。
根据测试,有的app使用友盟host进行更新,有的app使用自己的host进行更新,但是绝大部分app使用友盟sdk的app升级时,服务器返回数据为明文,且包含更新app包的url地址,可以直接劫持进行修改。
而根据友盟官网,友盟服务超过64万款APP。
随手对友盟官网的app进行测试
1 当贝市场
升级更新发包
拦截后,修改其中url地址,返回数据包
效果如下
2 穷游
使用fiddler拦截,修改返回url
效果图
3 豆瓣
使用fiddler拦截,修改返回url
效果图
4 中华万年历
使用fiddler拦截,修改返回url
效果图
不管app是使用友盟的host,还是自己的host,都可以对其进行url拦截,修改。
反汇编友盟sdk代码
可以看到更新流程如下,只关心服务器返回json到下载url的实现,水平有限可能过程有遗漏。首先
(1)在package com.umeng.update.UpdateDialogActivity中,点击确定后使用UpdateResponse类保存服务器的json信息
UpdateResponse b;
this.b = ((UpdateResponse)getIntent().getExtras().getSerializable("response"));
(2)在package com.umeng.update. UpdateResponse中
在构造函数中,调用a(paramJSONObject);进行对象初始化
public UpdateResponse(JSONObject paramJSONObject)
{
super(paramJSONObject);
a(paramJSONObject);
}
(3)在a中,只判断服务器返回的json中的update是否为Yes,如果是保存,path(对应json中的url), new_md5(对应json中的md5值),target_size,version等参数
private void a(JSONObject paramJSONObject)
{
try
{
this.hasUpdate = "Yes".equalsIgnoreCase(paramJSONObject.optString("update"));
if (this.hasUpdate)
{
this.updateLog = paramJSONObject.getString("update_log");
this.version = paramJSONObject.getString("version");
this.path = paramJSONObject.getString("path");
this.target_size = paramJSONObject.optString("target_size");
this.new_md5 = paramJSONObject.optString("new_md5");
this.delta = paramJSONObject.optBoolean("delta");
if (this.delta)
{
this.patch_md5 = paramJSONObject.optString("patch_md5");
this.size = paramJSONObject.optString("size");
this.origin = paramJSONObject.optString("origin");
}
}
return;
}
catch (Exception paramJSONObject)
{
paramJSONObject.printStackTrace();
}
}
(4)然后到com.umeng.update. UmengUpdateAgent中a函数调用startDownload进行下载并调用startInstall进行安装。
private static void a(Context paramContext, UpdateResponse paramUpdateResponse, File paramFile)
{
if (paramFile == null)
{
startDownload(paramContext, paramUpdateResponse);
return;
}
startInstall(paramContext, paramFile);
}
startDownload函数如下
public static void startDownload(Context paramContext, UpdateResponse paramUpdateResponse)
{
if ((paramUpdateResponse.delta) && (UpdateConfig.isDeltaUpdate()))
{
e.a(paramContext, paramUpdateResponse.origin, paramUpdateResponse.new_md5, paramUpdateResponse.path, paramUpdateResponse.patch_md5, c);
e.b();
return;
}
e.a(paramContext, paramUpdateResponse.path, paramUpdateResponse.new_md5, null, null, c);
e.c();
}
(5)水平有限没能继续跟入函数,但是从传递的参数,可以看到友盟sdk对服务器返回json数据并没有进行校验,对url也没有黑白名单机制,最有可能进行的就是返回的md5和apk进行校验,很容易对其进行中间人劫持攻击。
修复方案:
加个密吧
版权声明:转载请注明来源 路人甲@乌云
漏洞回应
厂商回应:
危害等级:中
漏洞Rank:8
确认时间:2015-10-29 16:45
厂商回复:
您好,漏洞已确认,正在修复中。感谢您对阿里巴巴安全的支持和关注!
最新状态:
暂无