路人甲 · 2015/05/13 10:10php
原文:Learning Pentesting for Android Deviceslinux
本文主要帶你們瞭解ARM處理器的基礎知識和ARM世界中不一樣種類的漏洞.咱們會進一步分析這些漏洞來搞清楚它的具體利用場景.此外,咱們還會研究不一樣的安卓rooting利用腳本用於挖掘潛在的漏洞.考慮大世面上大多數android智能手機都是基於ARM架構處理器,所以瞭解ARM以及ARM中存在的安全隱患是很是有價值的.android
ARM架構基於精簡指令集(Reduced Instruction Set Computing RISC),這意味着它具備比基於複雜指令集(Complex Instruction Set ComputingCISC)少得多的指令架構.使用ARM處理器的設備幾乎無處不在,好比智能手機,電視,電子書,嵌入式設備等等.shell
ARM共有16個通用寄存器從R0到R15.(R0-R7,8個通用寄存器)其中5個有特å殊意義:編程
下圖顯示了ARM架構:緩存
這五個寄存器中咱們應重點關注以下三個:sass
棧指針 Stack Pointer (SP-R13):存儲棧頂指針安全
連接寄存器 Link Register (LR-R14):存儲被調用函數返回地址架構
程序計數器 Program Counter (PC-R15):存儲着下一條執行指令的地址.每條執行被執行後,該計數器會進行自增.app
ARM有兩種執行模式:
執行模式取決於程序狀態寄存器(CPSR)的狀態.其實存在第三種模式: Thumb-2模式,就是將arm模式和Thumb模式混合.咱們不會去分析這兩種模式的區別,由於這樣就超出本文的範圍了.即便是Android SDK中的模擬器也是arm平臺的,其餘大多數的智能手機也是基於arm.可是咱們仍是選擇從開源硬件模擬器QEMU開始進行ARM exploitation的訓練.
在咱們開始基於ARM平臺設備的exploiting前建議先安裝好對應的環境.儘管Android SDK的模擬器也能基於arm運行,並且大多數的智能手機也是基於arm.咱們仍是選擇用QEMU(開源硬件虛擬機和模擬器)開始ARM exploitation.
爲了在android設備上執行接下來的操做,咱們須要下載和配置Android NDK環境.若是你正使用Mac,那麼安裝QEMU是很是簡單的,只須要輸入:brew install qemu
若是系統是Ubuntu須要執行以下操做:
1.第一步下載安裝QEMU依賴包
sudo apt-get build-dep qemu
wget http://wiki.qemu-project.org/download/qemu-
1.7.0.tar.bz2
複製代碼
2.下一步配置QEMU,指定目標爲ARM最後make.只須要進入解壓後的目錄輸入以下命令.
./configure --target-list=arm-softmmu
make && make install
複製代碼
3.一但QEMU安裝成功,咱們就能夠下載ARM平臺的Debian鏡像運行exploitation習題.下載列表:
people.debian.org/~aurel32/qe…
4.這裏咱們下載格式爲qcow2的鏡像,debian_squeeze_armel_ standard是基於QUME的系統鏡像.qcow2 for our OS.內核文件是 vmlinuz-2.6.32- 5-versatile ,RAM磁盤文件是initrd.img-2.6.32-5- versatile.下載完必須文件後就能夠經過如下指令啓動QEMU實例.
qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.32-5-versatile -initrd initrd.img-2.6.32-5-versatile -hda debian_squeeze_armel_standard.qcow2 -append "root=/dev/sda1" --redir tcp:2222::22
複製代碼
5.上述全部操做成功就能夠經過如下命令ssh登陸QEMU:
ssh root@[ip address of Qemu] -p 2222
複製代碼
6.默認賬號密碼是root:root.
到此咱們已經成功配置好環境,是時候開始exploiting存在漏洞的應用
簡單來說,緩存(buffer)是用於存儲任意數據的地方.當緩存的數據超過了緩存區的大小就會發生溢出(overflow).攻擊者能夠利用溢出攻擊來控制程序執行惡意代碼.
下面就用一個簡單的程序來演示如何利用溢出攻擊.下圖中顯示程序有三個函數:vulnerable, ShouldNotBeCalled以及 main.
執行程序的時候函數 ShouldNotBeCalled
一直沒有被調用.
函數vulnerable
只有一個操做就是將成員變量拷貝到只有10bytes大小的緩存buff中.
寫完此程序後經過gcc編譯(arm虛擬機中編譯).此外咱們還將禁用空間格局隨機化Address Space Layout Randomization (ASLR)讓利用場景變得更簡單些.ASLR是一種針對緩衝區溢出的安全保護技術,經過對堆、棧、共享庫映射等線性區佈局的隨機化,經過增長攻擊者預測目的地址的難度,防止攻擊者直接定位攻擊代碼位置,達到阻止溢出攻擊的目的.據研究代表ASLR能夠有效的下降緩衝區溢出攻擊的成功率,現在Linux、FreeBSD、Windows等主流操做系統都已採用了該技術.Android 4.0以後也實現了該方案.www.duosecurity.com/blog/exploi…
echo 0 > /proc/sys/kernel/randomize_va_space //禁用ASLR
gcc -g buffer_overflow.c -o buffer_overflow //編譯example
複製代碼
下一步,用gdb調試二進制文件.
gdb -q buffer_overflow
複製代碼
使用disass
命令反編譯一部分函數,下圖爲反編譯ShouldNotBeCalled
正如截圖中說看到的,函數ShouldNotBeCalled
從內存地址0x00008408開始.若是咱們查看反編譯的main
函數,將會發現vulnerable
函數是從0x000084a4開始調用,在0x000084a8返回.當程序進入存在漏洞的函數,使用有漏洞的指令strcpy,函數並不會檢查拷貝字符串的大小.若是程序進入存在漏洞的子程序,咱們就可以經過控制LR控制整個程序流程.
這裏目標是估算LR什麼時候被重寫以後插入ShouldNotBeCalled
地址來調用函數ShouldNotBeCalled
.用一個較長的參數運行程序,好比下面的命令,觀察發生了啥.在此以前先在調用strcpy
地址處設置斷點.
b vulnerable
b *<address of the strcpy call>
複製代碼
經過設置斷點,咱們能夠將參數改爲AAAABBBBCCCC運行程序觀察他如何被覆蓋.觀察發如今vulnerable和strcpy函數被調用時觸發斷點.一但斷點觸發,咱們就能夠經過x
命令指定sp操做堆棧.以下圖
如圖所示,堆棧已經被咱們輸入(ASCII: 41 for A, 42 for B, and so on)的buffer重寫.分析截圖,發現0x000084a8這種狀況咱們須要多於4個字節去覆蓋返回地址.
最終輸入的字符串爲16字節的垃圾數據和函數ShouldNotBeCalled
的地址
r `printf "AAAABBBBCCCCDDDD\x38\x84"`
複製代碼
如圖所示,咱們將IShouldNeverBeCalled
起始地址插入參數中
請注意,由於框架緣由這裏字節順序是相反的.這樣就能看到程序調用函數ShouldNotBeCalled了.以下圖
大多數狀況下,咱們並不須要調用程序自身的其餘函數.相反,咱們須要在攻擊向量中插入shellcode,這樣就能夠經過shellcode達到任意目的.可是,再大多數基於arm平臺的設備中內存區域是不可執行的,這樣就阻止了咱們插入和執行shellcode.
因此,攻擊者必須依賴一項技術返回導向編程 return-oriented programming ROP.所謂ROP,簡單的說就是把原來內存已經存在的代碼塊拼接起來,拼接的方式是經過一個預先準備好的特殊的返回棧,裏面包含了各條指令結束後下一條指令的地址.最終執行個人shellcode.在通常程序裏面,都包含着大量的返回指令(ret),他們基本位於函數的尾部,或是函數中部須要返回的地方.而從函數開始的地方到ret指令之間的這一段序列稱爲二進制指令代碼塊(gadgets).咱們須要在整個內存空間中搜索咱們須要的gadgets
舉個例子,若是咱們在調試程序的時候反編譯seed48()
,獲得以下輸出:
分析反編譯代碼,代碼包含一個ADD指令接着是POP和BX指令,這就是完美的 ROP gadget.這裏攻擊者能夠想到爲了利用 ROP gadget 首先跳到POP指令控制R4(which will be six less than the address of /bin/sh)以後在LR中輸入ADD指令的值.最後咱們獲得 /bin/sh 的地址,當咱們跳會ADD (R0 = R4 + 6 ),以後咱們能夠在R4中指定任意垃圾數據以及LR中指定 system() 的地址.
這意味着咱們最終講跳到 system() 而且參數爲 /bin/sh , 這樣就能夠執行shell命令了.用一樣的方式,咱們能夠建立任意ROP gadget 來達到執行任意命令的效果.由於ROP是個很是複雜的話題,強烈建議本身動手嘗試分析反編譯代碼,而後構造exploit.
在早期android版本中,各類android版本的各類設備都遇到Android root exploits .Android rooting就是獲取設備的最高權限而不是手機制造廠商給用戶的默認權限.這些root exploits利用了各類Android系統漏洞.下面是一些漏洞列表和漏洞原理簡介:
Exploid: CVE-2009-1185 影響android2.1及以前版本,此exploit基於udev
漏洞CVE-2009-1185,udev是一個android組件負責USB鏈接,進程應該只處理kernel發送的device的NETLINK的socket消息,但實際上並未檢測NETLINK的socket消息的來源,這樣能夠廣播add device的socket信息,觸發硬件處理事件,將惡意代碼傳入kernel,由其寫入設備文件.這樣,攻擊者只需發送一條構造好的udev消息就能夠提權了.
Gingerbreak:CVE-2011-1823,此exploit利用vold的漏洞,原理相似上一個.(android並無實現linux的udev,其功能由vold進程實現,其包含VolumeManager,NetlinkManager,CommandListener等modules).Android 2.3.4以前版本的 volume 守護進程(vold)因爲信任從 PF_NETLINK socket 接收到的消息,所以容許以 root 權限執行任意代碼,利用方法是經過一個負數索引繞過指針對最大值的有符號整數檢查.
RageAgainstTheCage:此exploit基於RLIMIT_NPROC
,RLIMIT_NPROC用於指定用戶調用setuid()函數的時候能建立的最大進程數.adb 後臺是root權限,以後會調用 setuid() 自行降權.android 2.2 以及以前版本若是進程數達到RLIMIT_NPROC的閾值,程序就不會調用setuid()降權,這樣adb就會以root權限運行了.
Zimperlich:與RageAgainstTheCage
原理相似,不同的是此處依賴的zygote進程的降權.全部的android應用是由Zygote進程fork分支後啓動的.Zygote是由root權限運行的.在fork以後新的進程將使用setuid調用降權至目標應用的uid.Android2.2以及以前版本的Zygote沒有對降權時setuid調用的返回值進行檢查.一樣,在耗盡目標程序uid的最大進程數以後,Zygote就沒法下降它的權限,而後就以root權限啓動應用了.
KillingInTheNameOf: CVE-2011-1149 此expolit利用了ashmem
(the shared memory manager) 接口漏洞,用於修改ro.secure
的值,ro.secure決定了設備的root狀態.Android 的共享內存(Ashmem)子系統是一個共享內存分配器.共享內存能夠經過 mmap 或者文件 I/O 進行訪問.在android 2.3以前,ashmem 容許任何用戶從新映射屬於 init 進程的共享內存,將包括系統屬性地地址空間的內存進行共享,KillingInTheNameOf 利用程序將系統屬性空間從新映射爲可寫,並將 ro.secure 屬性設置爲0.在重啓 adbd 後,ro.secure 屬性的修改會容許 adb shell 取得 root 權限訪問.
這些都是比較出名的用戶root安卓設備的exploits.
數據處理指令-指令編碼
操做碼功能表
分支指令B/BL-指令編碼
分支指令BX-指令編碼
分支指令功能表
arm架構完整版