2016-10-21

appscan

 

0x1.引子

 

前段时间盘古的同学发现了QQ手机浏览器的“虫洞漏洞”,我们同步分析了下该漏洞,目前该漏洞已经修复,我们和大家分享一下这个漏洞的分析和挖掘全过程,供大家参考。

 

0x2.样本信息

 

下载链接:http://mb.qq.com/

文件名称:qqbrowser_6.9.2.2665_20820.apk

文件md5:64FE443F770BA9433E23D689C78DAF99

versionCode: ‘6922665’

versionName: 6.9.2.2665

云盘备份地址:https://yunpan.cn/cM8JVT39xQnhw  访问密码 d7d6

 

0x3.特征定位

 

查看手机所开端口发现一处可疑端口本地未校验。

 

所以需要对本地所有dex文件进行扫描,看看此部分功能到底是在哪里,在做什么。

通过搜索端口号以及判定是打开Sokcet,我们确定此处地址。

 

 

即确定文件所在包为:

assets/dex/com.tencent.mtt.sniffer.jar

 

0x4.代码深入

 

现在我们就可以继续往下进行分析了。

我们用jeb查看一下java代码。

 

 

 

既然g.b是获取的端口8786数字,那么g类很可能就是初始化socket的类,所以我们按照代码逻辑往下看一下这个g类,发现这里this.i的数值是new j(this.a),而这个j类则包含很多数据。

如下图所示:

 

第一个红框是方法名,处理申请的访问链接流程的。

第二个红框是请求的网址,根据不同的请求执行不同的功能。

第三个红框就是执行的功能,在代码下面有很多类似结构。

这里我们先看一下/getWifiInfo这个请求。

在j.a(this.a,arg13)方法我们往后跟一下。

 

 

这里有两处需要分析的地方,一处是数据处理,即请求访问协议的数据的加密与解密;一处是Message的发送,即不同的请求走不同的方法分支。我们先看第一处红框这个位置,是将数据进行处理,this.a(v2.toString)方法我们跟进去。

 

 

可以看到执行的是e.a和e.b方法,我们看到这个,一般是可以猜测到是加解密的方法。

 

 

这样,我们就明显的确定是通过的3des进行的加解密处理。

然后密钥的获取可以直接静态分析得到。

密钥的获取:

l.b = b.b + h.c;

 

b .b = “kM7hYp8lE69U” ;

h .c = e.b + d.f;

 

e.b = “jidhlPbD9”;

d .f = “8Pm” ;

 

密钥==”kM7hYp8lE69UjidhlPbD98Pm

在寻找密钥的过程中,我们发现访问请求的数据加密,和服务器返回的数据解密,都是通过3des加密解密,然后进行Base64编码解码处理的。

所以我们整理一下思路,先对刚才的getWifiInfo请求进行测试模拟。

 

 

流程也就是先在本地进行8786端口转发一下。

然后用python写一下网络请求即可,在上面截图中的url大家可以直接看到。

 

0x5.漏洞利用

 

上一条测试通过之后,我们继续往下看,有更多的协议需要分析。

 

 

我们这里可以看到,第一条getWifiInfo协议没有判断,直接会进行请求,而后面的请求,都是基于uuid来进行判定,如果uuid存在并且合法,那么才会进行后续请求,所以主要问题在于我们如何构造uuid并且使之合法化。

我们继续分析代码,也就是上图第二个红框标识的地方,如果uuid不是空,同时本地的一个hashmap中没有记录过它,那么将会往下走if的流程,所以看到这个/bind协议,我们就可以猜测,这条协议是否是绑定uuid的呢?

跟进去看一下this.a.a(arg12);

 

 

我们看到这个红框,可以发现上文中我们在跟getWifiInfo方法的时候,也跟进去了,所以我们分析一下这个是什么意思。

 

 

经过代码流程的跟踪,我们到了这个类,发现这里是处理Message流程的地方。

当前bind走的是case 0,也就是this.a.b(arg5.obj);

再跟一下。

 

 

这里的是我们请求的v0_1,即需要post数据的json字符串,可以看到保证code有数值,或者qq有数值即可。

然后走this.a(“ok”,v0_1);是正常绑定的流程,所以我们继续跟进去。

 

 

看到这两个红框标识的位置,我们保证刚才传过去的字符串包含ok,而json数据中包含上面提到的code数值,以及uuid数值即可,这就是bind的过程,即绑定uuid的过程。测试一下。

我们简单截图一下:

 

 

下面是请求访问成功的截图。

 

 

这里绑定好uuid之后,后面的请求我们按部就班地跟着分析就行,没有什么难度了。

 

比如getapplist协议,getappInfo协议。

 

 

 

获取手机安装的app列表信息不算太可怕。

我们往下分析。

 

 

 

根据名称,我们推测一条是下载安装app的,另外一条是在手机上显示对话框的。

访问构造参数根据代码分析一下就好,这里就不贴了。

直接发一下测试结果。

 

 

 

好了,这样就测试完毕了。因为这里下载,安装,没有走su的流程,也就是没有使用静默安装的,而是调用的系统安装页面,所以是上图所示。

 

0x6.安全建议

 

1).使用RSA加密操作,对所有的请求进行RSA加密,然后本地存储RSA公钥进行身份验证。

2).去除这部分命令执行功能,使用应用层的intent实现打开网页。

3).监听0.0.0.0的端口转为127.0.0.1,或给相关执行动作加入用户安全提示,需用户允许才能打开网页。

 

0x7.关于作者

 

ggz,360信息安全部-vulpecker team

 

360 vulpecker team隶属于信息安全部,专注于研究安卓安全,研究方向重点为安卓APP安全和安卓系统安全。开发并维护了免费的在线Android应用安全扫描服务 appscan.360.cn ,方便了众多移动应用开发者。

该团队发现了安卓通用型拒绝服务漏洞,影响市面上几乎所有的安卓产品,该通用型本地拒绝服务可以造成大面积的app拒绝服务。还发现了安卓APP新型通用安全漏洞“寄生兽”,安卓系统下包括支付宝、高德、微信等超过千万个APP都可能存在这一漏洞。在kcon等安全大会上发表演讲,公开了多款手机浏览器的远程溢出漏洞和众多流行手机应用的远程攻击漏洞研究成果。

2016-10-08

本月一共有71个安全漏洞,其中Critical 6个,High 47个,Moderate 17个,Low 1个,其中属于Aosp部分的有21个,驱动和kernel的有50个。

 

下面是与9月份的漏洞数量对比图:

 

 

漏洞分布情况对比图:

漏洞详细情况分析整理

 

  • Aosp高风险安全漏洞

Aosp的漏洞主要集中在mediaserver模块中,这也是最近安全研究漏洞挖掘的热点模块。下图是这个月aosp漏洞的整理。

A)以下高风险安全漏洞在mediaserver组件中,可以被任意app触发。

CVE-2016-3909、CVE-2016-3910、CVE-2016-3913、CVE-2016-3920是四个High级的mediaserver漏洞。分别影响libstagefright_soft_mpeg4dec.so、libstagefright_soft_mpeg4enc.so、libsoundtriggerservice.so、libmediaplayerservice.so、libstagefright.so五个文件。

Mediaserver的权限提升漏洞能够让本地的恶意程序来提升权限执行任意代码,所以被评为High。

CVE-2016-3909是在SoftMPEG4::onQueueFilled()中,输出缓冲区可能小于被写入的引用。补丁是在写入之前检查缓冲区与被写入的引用大小。

CVE-2016-3910是calloc(1, from_user.data_size + sizeof(struct sound_trigger_phrase_sound_model)) 会引起一个整型溢出并分配一个比实际需要小的内存块,当分配的内存块小于from_user.data_size时,会发生堆溢出,补丁是增加了溢出检查。

CVE-2016-3913是一个无效的static_cast会导致越界访问。

CVE-2016-3920是一拒绝服务漏洞。

 

B)以下高风险安全漏洞在Camera service中。

CVE-2016-3815是High级的提权漏洞,影响libcamera_metadata.so。在camera_metadata.c,由于validate_camera_metadata_structure方法没有对data_count 做边界检查会导致append_camera_metadata方法发生crash。给data_count设置一个很大的值会导致堆溢出。补丁是增加了溢出检查。

CVE-2016-3816是Camera service错误的检查了camera_metadata_buffer_entry结构体的变量数。补丁是在计算metadata的大小时增加了溢出检查。

 

C)其他High级别的提权漏洞

CVE-2016-3900是High级的提权漏洞,影响serviceManager。ServiceManager判断一个Binder事务是否有权限去注册一个service。它使用getPidcon()查询SELinux context。getPidcon()由于竞争条件会导致一个错误的SELinux context被用来做权限检查。

CVE-2016-3908是由于从Android 5.*升级到Android 6.*的设备,一个遗留的hash值任然存在于手机上,会在调用checkPassword()是删除掉手机的密码或者PIN码。

CVE-2016-3911是由于android.os.Process# zygoteSendArgsAndGetResult()方法在没有读取Zygote写入的值就抛出一个异常。因此所有从zygoteSendArgsAndGetResult返回的PIDs都将右移一个字节。因此一个本地的恶意应用可以产生一个新的进程去执行shell命令在一个高权限的上下文。

CVE-2016-3912是在被附加的进程中当一个pending broadcast被派遣时,BroadcastQueue.sendPendingBroadcastsLocked API会检查ProcessRecord 的PID属性。如果一个进程曾经接收这个广播并且检查了uid,当下一个进程使用相同的pid时就不在检查,虽然使用的不同uid。

CVE-2016-3914 MmsProvider.openFile验证current_data列在数据库,然后调用ContentProvider.openFileHelper。由于竞争条件可能会导致二次读写数据库。

CVE-2016-3917是一个三种条件竞争,指纹识别、切换用户、切换键盘。触发的过程可能是由于用户尝试使用指纹认证,同时连续的点击第二个用户的头像。补丁是在验证是绑定用户id,在验证结束时确认用户id。

CVE-2016-3918 在应用获得com.android.email.permission.READ_ATTACHMENT权限后,他可以访问邮件应用的任何文件。

 

D)其他风险级别较低的受影响文件

wifi-service.jar、services.jar、libstagefright.so、libsysutils.so、libril.so、framework.jar、debuggerd、libaudioflinger.so

 

  • kernel高风险安全漏洞

A). CVE-2016-0758和CVE-2016-7117是Critical级提权的漏洞

CVE-2016-0758 是内核ASN.1(Abstract Syntax Notation One)解码器中的整形溢出漏洞.从补丁来看,在函数asn1_find_indefinite_length当中,增加了一些额外的边界检查(check_length)来避免整数溢出漏洞.

CVE-2016-7117 是内核当中一个UAF漏洞,当调用recvmsg返回一些数据包并且命中失败的时候,将会让sock对象走向sock->sk->sk_err,这样就出现了一个潜在的UAF问题.

 

B). CVE-2015-8955, CVE-2015-8950是High级的提权漏洞

CVE-2015-8955 是内核中类型混乱的一个漏洞.由于PMU的类型没有被校验而放置到arm_pmu当中出现的问题.补丁中更新了arm64的PMU驱动并且拒绝了PMU的其他事件.

CVE-2015-8950 是内核中的一个信息泄漏漏洞.由于ION内存中初始化分配内存的时候没有把堆清零,导致了信息泄漏的问题.补丁中的代码将初始化的内存都用零填充初始来避免这个问题.

 

C). CVE-2016-6683 ,CVE-2016-6684 , CVE-2016-6685, CVE-2015-8956和CVE-2016-5696是Moderate级的漏洞

CVE-2016-6683 ,CVE-2016-6684 和 CVE-2016-6685 都是内核组件中的信息泄漏漏洞.如果系统没有设置kptr_restrict,那么格式化打印%p就会泄漏打印内核地址.补丁中的代码是将%p转换成%pK.

CVE-2015-8956 是内核中的信息泄漏漏洞.在rfcomm_sock_bind函数中,addr结构是由用户态拷贝未初始化的区域,所以可能导致信息泄漏问题.补丁中的代码将sockaddr_rc结构初始化清零来避免这个问题.

CVE-2016-5696 是内核网络中的一个拒绝服务漏洞.在linux内核4.7版本之前的tcp_input.c文件中.漏洞的根源在于RFC5961引入了challengeACK响应和TCP控制封包的速率限制.新的漏洞可让攻击者推断出互联网上任意两台主机之间是否使用了TCP连接进行通信,并且无需进行中间人攻击即可远程劫持会话.补丁增强了对ACK段的不可控性.

 

D). CVE-2016-6690是Low级的漏洞

CVE-2016-6690 是内核音频驱动中拒绝服务漏洞.codec结构的变量没有经过校验就传递到了snd_soc_read和snd_soc_write函数中,因此造成了拒绝服务的攻击.补丁中的代码对这些函数指针都进行了各种校验.

  • 高通和MTK的驱动漏洞

A).高通驱动漏洞


CVE-2015-8951 是高通音频驱动中的UAF漏洞.当q6lsm_open函数调用失败时,如果LSM客户端数据被释放后仍可以被访问就会导致UAF问题.增加的补丁是,只能在msm_lsm_close函数中释放客户端数据,一次来防止释放后被重用.CVE-2016-3934 是高通照相机驱动中的栈溢出漏洞.在msm_camera_cci_i2c_write_seq函数中,栈的大小没有经过校验,所以会导致溢出问题.补丁当中把数组改成了动态分配,以此来避免溢出.

CVE-2016-3901和CVE-2016-3935 都是高通加密引擎驱动中的整数溢出漏洞.ULONG_MAX不能被用于检测uinit32_t的大小,所以在补丁中使用U32_MAX类型来替换ULONG_MAX.

CVE-2016-5340 是高通内存共享驱动中由于没有正确校验ashmem区域对应的名称和路径而导致的漏洞,从补丁上来看,是验证file->f_op指针对应的存储记录,而不是仅仅比较名称和路径.

CVE-2016-3938 是高通视频驱动中的内存破坏漏洞.由用户态拷贝的z_order,没有经过校验就作为left_lm_zo_cnt和right_lm_zo_cnt的索引,会导致内存破坏问题的出现.补丁中加入了判断.

CVE-2016-3939 是高通视频驱动中的异常指针访问漏洞.在函数mdss_misr_get_map中,如果block_id是无效的,当调用ioctl的时候就会访问异常.补丁在mdss_mdp_misr_table中校验了block_id.

CVE-2016-3905 是高通wifi驱动中的内存破坏漏洞.在hdd_parse_sendactionframe_v2函数中的command变量没有被正确校验而导致的内存破坏问题.补丁中增加了边界的校验来避免这个问题.

CVE-2016-6675 是高通wifi驱动中的缓冲区溢出漏洞.在__iw_get_softap_linkspeed函数中,一个空终结符作为不正确的索引而导致了缓冲区溢出.补丁中空终结符设置到了MAC_ADDRESS_STR_LEN-1的位置来避免这个问题.

CVE-2016-6676 是高通wifi驱动中的缓冲区溢出漏洞.在处理GET_CFG的IOCTL过程中,如果接受一个全局变量没有经过校验作为数组的参数,就会导致缓冲区溢出问题.补丁的代码修改了边界的校验来修复这个问题.

CVE-2016-5342 是高通wifi驱动中的缓冲区溢出漏洞.当wcnss_wlan_write函数调用了超过初始分配的数据,就会造成缓冲区溢出.补丁当中加强了边界检查,如果发生了溢出就会返回失败.

CVE-2015-0572 是高通character驱动中的一个任意地址写漏洞.当程序在处理COMPAT_FASTRPC_IOCTL_INVOKE_FD的IOCTL时,从用户空间返回的指针会导致在用户可控的位置写零操作.补丁中的代码让用户空间的指针没有被直接调用,而是用get_user和put_user的宏来确保是否有效.

CVE-2016-3860 是高通音频驱动中的一个越界读取的漏洞.在IOCTL的AUDIO_GET_CALIBRATION控制码中,用于分配内部缓冲区的部分没有经过校验,导致在使用copy_to_user的时候读取越界.补丁的代码中增加了对头的校验和类型的校验.

CVE-2016-3940和CVE-2016-6672 是触摸屏驱动当中的栈溢出漏洞.在synaptics_rmi4_i2c_write函数中,栈的数组大小来源于用户空间,所以可能导致栈溢出.补丁当中用动态分配堆内存来替换了这种方法.

 

B).MTK驱动漏洞

CVE-2016-3928 是MTK视频驱动中的内存破坏漏洞.在mtkfb_ioctl函数中,没有校验displayid的值是否为负数而导致的内存崩溃.

CVE-2016-3936 是MTK视频驱动中的内存破坏漏洞.在函数mtkfb_auto_capture_framebuffer函数中,config->outputBuffer输入参数没有正确校验,所以会导致问题.补丁当中完全删掉了这些代码来避免内存破坏漏洞.

CVE-2016-3937 是MTK视频驱动中的内存破坏漏洞.在process_dbg_opt函数中,opt输入参数没有被正确校验而导致了内存破坏问题.补丁中完全删掉了这些代码来防止内存破坏问题.

 

C).英伟达驱动漏洞


CVE-2016-6673 是英伟达照相机驱动中的UAF漏洞.在camera_new_device函数中,如果一个设备已经存在,在camera_remove_device函数中被调用两次就会导致UAF问题.补丁中删掉了没有被使用的问题代码来避免UAF.

CVE-2016-6677 是英伟达GPU驱动中的信息泄漏漏洞.在gk20a_channel_ioctl函数中的缓冲区变量没有初始化清零就被拷贝到用户空间中就会造成信息泄漏的问题.补丁中增加了初始化清零的操作来避免这个问题.

 

D).其他驱动漏洞

CVE-2016-6678 是摩托罗拉USBNET驱动中的一个信息泄漏漏洞.在usb_ether_xmit函数中,分配的缓冲区没有被初始化清零,所以可能导致信息泄漏问题.补丁中增加了初始化内存清零的操作来避免这个问题.

 

4.高通组件漏洞

 

CVE-2016-3929 是高通QSEE中的TOCTOU漏洞.早期注册的共享缓冲区由于线程上下文的切换而未能重新验证,从而出现竞争问题.CVE-2016-2059 是高通网络组件中IPC Router绑定任意端口而造成的问题,从补丁中看,是需要在绑定端口之前要校验是否是客户端的端口.

CVE-2016-6679 是高通组件中的一个信息泄漏的漏洞.iw_softap_setwpsie函数中由于不正确的边界检查导致的信息泄漏问题.补丁中的代码全部删除了这些问题代码.

CVE-2016-3902 是高通组件中的一个信息泄漏的漏洞.当IOCTL调用到WAN_IOC_ADD_FLT_RULE_INDEX控制码时,由于内核堆的越界读取导致了信息泄漏.在补丁中增加了对最大值的判断检测,来避免读取越界造成的信息泄漏问题.

CVE-2016-6680 是高通组件中的一个信息泄漏的漏洞.当调用iw_set_priv的IOCTL时,由于内核堆的过度读写导致了信息泄漏.补丁中的代码删除了全部问题的代码来避免这个问题.

CVE-2016-6681和CVE-2016-6682 是高通组件中的信息泄漏漏洞.msm_audio_config32结构在初始化的时候没有进行清零操作而导致的信息泄漏,补丁中的代码增加了对他们的清零计算来避免这个问题.

CVE-2016-6686,CVE-2016-6687和CVE-2016-6688都是英伟达profiler中的信息泄漏漏洞.它们都是从用户态拷贝未初始化清零结构,从而导致的信息泄漏问题.补丁代码中将这些结构的代码都进行了初始清零操作来避免这个问题.

CVE-2016-6691,CVE-2016-6692,CVE-2016-6693,CVE-2016-6694,CVE-2016-6695,CVE-2016-6696,CVE-2016-5344和CVE-2016-6697都是高通组件中的漏洞.但是并不影响Nexus设备.这些漏洞需要通过受影响的厂商来解决,相关的问题细节需要厂商来提供.

  • 受影响进程列表

2016-09-07

appscan

本月一共有63个安全漏洞,其中Critical 8个,High 35个,Moderate 19个,未定义风险等级1个。其中属于Aosp部分的有33个,驱动和kernel的有30个。

 

下面是与8月份的漏洞数量对比图:

 

 

 

漏洞分布情况对比图:

 

 

漏洞详细情况分析整理

1.Aosp高风险安全漏洞

Aosp的漏洞主要集中在mediaserver模块中,这也是最近安全研究漏洞挖掘的热点模块。下图是这个月aosp漏洞的整理。

 

A)以下高风险安全漏洞在mediaserver组件中,可以被任意app触发。

 

CVE-2016-3862、CVE-2016-2429是两个Critical级的远程代码执行漏洞。分别影响framework.jar、libstagefright_soft_flacenc.so两个文件。

 

Mediaserver远程代码执行漏洞可能允许攻击者使用专门制作的媒体文件来攻击手机,在解析媒体文件时会发生内存崩溃。这个漏洞由于可能在Mediaserver进程中发生远程代码执行,所有被评为Critical。Mediaserver进程有权限访问音频和视频流,第三方应用程序不能。

 

CVE-2016-3862是在解析JPG文件时一个恶意构造的exif数据能够导致堆栈被破坏,并导致远程代码执行。

 

CVE-2016-2429是对2016.4月的安全补丁的一个更新,在解析一个畸形文件时会产生一个空指针引用。

 

CVE-2016-3863是一个High级别的远程代码执行漏洞影响libstagefright.so文件。

 

CVE-2016-3863是一个在MediaMuxer的远程代码执行漏洞,攻击者可以通过一个恶意构造的文件在一个低权限进程来达到远程代码执行。这个漏洞被评为High是因为必须通过一个已安装的apk来进行攻击。

 

CVE-2016-3870、CVE-2016-3871、CVE-2016-3872、CVE-2016-3823是四个High级别的提权漏洞。分别影响libstagefright_omx.so、libstagefright_soft_mp3dec.so、libOmxVenc.so、libstagefright_soft_vpxdec.so四个so文件。

 

权限提升漏洞可以被本地的恶意应用用来执行恶意代码进行提权,mediaserver的漏洞,可以被用来提权到system。

 

CVE-2016-3870是在解析从解码器取得的数据时会导致堆溢出。

 

CVE-2016-3871是在SoftMP3::onQueueFilled()方法里调用memset时会传入一个很大的值,导致堆溢出。补丁是加了一个边界检查。

 

CVE-2016-3872 是SoftVPX::outputBuffers()里调用了SoftVideoDecoderOMXComponent::copyYV12FrameToOutputBuffer()可以复制解码数据的范围超过输出缓冲区,这可能导致堆溢出。补丁加了检查,以防止堆溢出。

 

CVE-2016-3823是在libOmxVenc.so里方法omx_video::empty_this_buffer_proxy方法里会memcpy数据到0xdeadbeef,在64位设备上可以通过一个精心构造的binder触发。补丁是加了设置指针为null和在访问之前检查指针。

 

B)以下高风险安全漏洞在LibUtils组件中。

 

CVE-2016-3861是Critical级的远程代码执行漏洞,影响libmediaplayerservice.so、libutils.so。

 

CVE-2016-3861是在utf16_to_utf8和utf16_to_utf8_length的不一致导致堆溢出。补丁修改了正确的长度计算和边界检查。

 

C)以下高风险漏洞在libjhead组件中,可以被任意app触发。

 

CVE-2016-3822是High级的远程代码执行漏洞,影响libjhead.so。libjhead.so的远程代码执行漏洞可以被攻击者用一个特殊构造的文件在当前环境下执行任意代码。

 

CVE-2016-3822是由于offsetval传递给ProcessExifDir会导致一个越界写。补丁是增加了offsetval数溢出检查和边界写检查。

 

D)其他风险级别较低的受影响文件

 

libstagefright_soft_avcdec.so、libsonivox.so、libui.so、telephony-common.jar、service.jar、debuggerd、SystemUI.apk、SettingsProvider.apk、Settings.apk、telephony-common.jar、adbd、Email.apk、framework.jar、TeleService.apk

 

2.kernel高风险安全漏洞

 

A)Critical级别

 

 

CVE-2014-9529、CVE-2016-4470、CVE-2013-7446、CVE-2016-3134、CVE-2016-3951是内核中Critical级别的本地提权漏洞。

 

CVE-2014-9529是由于竞争条件引起的,在3.4、3.10、3.18这些版本的内核的安全子系统中,允许本地应用通过keyctl命令来在内核中执行代码,这个功能的代码中在调用key_gc_unused_keys函数回收一个key时内存释放顺序有问题,当其他进/线程同样对此key进行类似操作时就可能导致内存破环或者系统崩溃,合理布置内存可用来进行本地权限提升。

 

CVE-2016-4470是内核的安全子系统中的use-after-free漏洞。在内核安全子系统模块的security/keys/key.c中的key_reject_and_link函数中可能存在key查找时失败情况,这种情况下再尝试去释放之后还需要使用的内存,就会导致UAF漏洞。补丁代码中添加了额外的检查工作,来避免潜在的UAF风险。

 

CVE-2013-7446 是kernel的networking子系统中的use-after-free漏洞。这个漏洞能够导致,在linux内核4.4.3之前的本地用户刻意巧妙的通过调用epoll_ctl来绕过AF_UNIX socket权限限制来达到本地提权。补丁将unix_dgram_poll函数中的第二次调用sock_poll_wait移除来来避免潜在的UAF风险。

 

CVE-2016-3134 是网络防火墙子系统中的整型越界漏洞。在防火墙子系统的mark_source_chains函数中,因为对用户提供的ipt_entry结构体中的next_offset成员没有做全面的越界检查从而可能被本地用户可以通过IPT_SO_SET_REPLACE setsockopt系统调用来传入非法参数进行权限提升或者导致内存破坏使得拒绝服务。补丁当然是添加对用户空间传入的数据做全面的边界检查。

 

CVE-2016-3951 是USB驱动中的double free漏洞。因为USB是支持热插拔的,当我们插入一个USB设备后执行cdc_ncm_bind进行bind时会调用usbnet_link_change,usbnet_link_change中会进而调用shedule_work。但是在bind失败后我们应该避免后面的usbnet_link_change调用,否则的话就会导致在结束shedule work时导致double free漏洞。恶意攻击者可以通过插入无效拥有descriptor的USB device来触发bind失败情况,进而导致double free。补定将cdc_ncm_bind中的usbnet_link_change调用删除,进行延期调用来避免此漏洞。被定义为Critical是因为一旦漏洞被触发可能导致设备持久性crash,只有通过刷机才能恢复。

 

B)High级别

 

 

CVE-2016-2053、CVE-2016-3864、CVE-2016-3858、CVE-2014-4805、CVE-2016-1583是内核中High级的提权漏洞。

 

CVE-2016-2053 是内核ASN.1(Abstract Syntax Notation One) 解码器中的内存破坏漏洞。在asn1_ber_decoder函数中,攻击者可以通过一个缺少public key的ASN1 BER 文件来导致public_key_verify_signatureh函数运行出错,进而破坏内存。

 

CVE-2016-3864 是内核中的高通音频接口层的buffer溢出漏洞。补丁添加了字符串参数长度的检查。

 

CVE-2016-3858 是内核中高通子系统驱动中的数组越界漏洞。在firmware_name_store()函数中,如果buf变量中包含的字符串超过subsys->desc->fw_name的大小就会导致数组越界,本地恶意应用可以通过有一定权限的进程利用此漏洞来进一步提升权限。

 

CVE-2014-4805 是内核networking驱动中的use-after-free漏洞。在内核的networking驱动中,由于一些像ppp_async和ppp_synctty等类型的channels允许在另一个namespace中拥有他们的userspace controller,因此这些channels不能依靠namespace来排除被移除的netns。因此通过移除一个和ppp_async和ppp_synctty类型相关的network namespace时可能存在UAF风险,可被本地用户用来提权。

 

CVE-2016-1583 是内核eCryptfs(Enterprise Cryptographic Filesystem,企业加密文件系统)中的栈内存破坏漏洞。本地攻击者可以通过精心构造相关mmap调用向量来导致递归的缺页异常处理,从而使造成栈内存破坏或者系统拒绝服务。

 

3. 高通和MTK等其他第三方厂商漏洞

 

A)高通驱动中存在权限提升漏洞

 

 

CVE-2016-3866、CVE-2016-3867、CVE-2016-3868、CVE-2016-3869、CVE-2016-1583、CVE-2016-3874、CVE-2014-4655、CVE-2016-2471是高通组件驱动中High级别漏洞。

 

CVE-2016-3866是高通声卡驱动中的一个缓冲区溢出漏洞。当编解码器在对通过msm_compr_ioctl_shared函数接受到的参数进行解析时,没有对数据包长度进行检查导致存在缓冲区越界风险。补丁中添加了对数据包长度进行预置操作,来避免潜在的缓冲区溢出漏洞发生。

 

CVE-2016-3867 是IPA(IP Packet Accelerator)这个可编程硬件协处理器的驱动中的一个内存破坏漏洞。从补丁代码来看,添加了一些对用户空间传递进来的参数的检查来防止对特殊资源的竞争情况。在未修补的设备中,本地攻击者可以利用此漏洞提升权限。

 

CVE-2016-3868 是高通电源驱动中的一个栈溢出漏洞。因为split_ptable_arg函数中没有传进来的参数进行边界检查,从而存在潜在栈溢出漏洞风险。补丁中添加了额外的参数检查代码,来设定参数的最大值避免栈溢出风险。

 

CVE-2016-3869  是博通Wi-Fi驱动中的内存破坏漏洞,由于对wls_parse_batching_cmd函数中的batch_params.nchan参数没有做边界检查导致可能造成内存破坏风险。

 

CVE-2016-3874是高通Wi-Fi驱动中的内存破坏漏洞。由于__iw_set_var_ints_getnone函数中没有对参数apps_args[1]的边界做检查,当这个参数为负数的时候可能触发内核内存破坏漏洞。补丁增加了额外的边界检查操作。

 

CVE-2014-4655是内核声卡子系统(只影响高通设备)的ALSA(Advanced Linux Sound Architecture)中的漏洞。这个漏洞其实包含两处风险:一方面是由于代码未对ioctl的调用是否是通过用户触发的以及这和control是否是在一个将被移除的进程中触发的进行判断,从而存在use-after-free风险;另一方面是control被replace的时候未对user_ctl_count的值进行检查,因此在用户控件通过足够多次SNDRV_CTL_IOCTL_ELEM_REPLACE ioctl调用可以导致user_ctl_count溢出。补丁对这两处问题进行了合理的修补。

 

CVE-2016-2471是高通Wi-Fi驱动中的内存破坏漏洞。在对接受到的essid长度没有做完整长度检查的情况下就直接进行buffer拷贝,导致的内存破坏。有别本地攻击者利用提权的风险。补丁添加完整的长度检查。

 

B) MTK驱动中的漏洞

 

本月无MTK驱动中的漏洞。

 

C) 其他第三方厂商中的漏洞

 

 

CVE-2016-3859是高通摄像头驱动中的内核空间任意写漏洞。由于VIDIOC_MSM_VFE_REG_CFG的ioctl请求,进入 msm_isp_send_hw_cmd()函数处理没有对用户输入做很好的校验,导致内核空间任意写漏洞。具有一定权限的本地恶意应用可以利用此漏洞提升权限。

 

CVE-2016-2446 是NVIDIA video驱动中的数组越界漏洞。补丁对原始代码增加了更细致的边界检查。

 

CVE-2016-3873 是NVIDIA kernel中的内核堆空间任意写漏洞。由于debugfs文件入口没有对来自用户空间的输入做很好的校验导致内核空间任意写漏洞。具有一定权限的本地恶意应用可以利用此漏洞提升权限。

 

4. 受影响进程列表

 

 

 

 

 

 

2016-09-01

appscan

0x1 libupnp简介

libupnp 是一个便携、可移植的 UPnP 的 C 语言开发包,UPnP是一种网络协议,允许设备自动搜寻和设定。Libupnp最新版本是1.6.20,编译时间为2016年7月7日,上一个版本为1.6.19,编译时间为2013年11月15日,编译间隔很长,有漏洞的版本为1.6.17及以下版本,编译时间为2012年12月以前。

0x2 漏洞原理

在1.6.17以及以下版本中存在多个缓冲区溢出漏洞,漏洞函数出现在upnp/src/ssdp/ssdp_server.c的unique_service_name中:

对于输入参数cmd未做安全检测,导致strncpy时发生缓冲区溢出。

由于漏洞类型比较老,攻击难度不大,使用一个构造的UDP数据包就能触发漏洞。早在漏洞刚出现时,Rapid7就推出了扫描工具ScanNow,其构造的数据包为:

测试ssdp包
M-SEARCH * HTTP/1.1
HOST:239.255.255.250:1900
MAN:"ssdp:discover"
MX:3
ST:uuid:rootdevice

 

通过数据包返回的结果中查看是否是有漏洞的upnp库。下面是一段python发送udp的代码:

 

发送ssdp数据包
import socket
 
SSDP_ADDR = '172.21.192.2' 
#SSDP_ADDR = '10.18.25.50' 
SSDP_PORT = 1900 
 
MS = 'M-SEARCH * HTTP/1.1\r\nHost:239.255.255.250:1900\r\nST:upnp:rootdevice\r\nMan:\"ssdp:discover\"\r\nMX:3\r\n'
__s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
__s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
local_ip = socket.gethostbyname(socket.gethostname())
__s.bind((local_ip, 50000))
__s.sendto(MS, (SSDP_ADDR, SSDP_PORT))

 

0x3 漏洞修复

判断数据大小,防止数据越界,常规的缓冲区溢出修复方法。下图为

0x4 漏洞扫描方法

360显危镜现已支持libupnp漏洞的扫描,其扫描方式为判断libupnp的版本,一般来说,libupnp在编译的时候都会将版本号编译进去,通过扫描so文件的字符串拿到版本号,如果小于1.6.18则判断为有漏洞的版本,扫描代码如下:

 

扫描代码
def detect_so_upnp(apkinfo,native_dir,logger=logger):
    r_rets = {'scan_version':scan_version,'scan_tag':scan_tag}
    ret_ = []   
    rets = detect_so_strings(apkinfo,native_dir,logger)
    if len(rets['result']) > 0:
        for r in rets['result']:
            if 'data' not in r.keys():
                continue
            rr = r['data'].split('\n')
            for __r in rr:
                if 'Portable SDK for UPnP' in __r:
                    vers = __r.split("/")
                    ver = vers[3].split(".")
                    real_ver = int(ver[2])
                                               sub_ver = int(ver[1])
                    if sub_ver<=6 and real_ver < 18:
                        r_ = {'vul_file':r['vul_file']}
                        r_.update({'vul_id':vul_id})
                        r_.update({'md5':apkinfo['md5']})
                        if r_ not in ret_:
                            ret_.append(r_)
    if len(ret_) == 0:
        r_rets.update({'risk':0,'result':[{'vul_id':vul_id,'md5':apkinfo['md5']}]})
    else:
        r_rets.update({'risk':1,'result':ret_})      
	return r_rets  

 

0x5 市场状况

直到2015年12月,QQ音乐才修复了这个漏洞,替换了有漏洞的libupnp库,当时使用的库版本为1.6.17。

 

通过对appscan大数据中的13w款app的扫描,发现受此漏洞影响的产品数量为60款。

虽然说比重几乎可以忽略不计,但是仍然要提醒开发者,开发时关注第三方库的安全状况,及时使用官方最新的安全版本库。

 

0x6 参考

  1. https://community.rapid7.com/community/infosec/blog/2013/01/29/security-flaws-in-universal-plug-and-play-unplug-dont-play
  2. https://security.tencent.com/index.php/blog/msg/99