从android设备中提取内核
背景
CVE-2013-2597 是高通 msm_acdb 设备驱动的一个 copy_from_user 栈溢出,利用要用到ROP。f101的漏洞利用介绍中,用到几处Gadgets,显然要根据acdb_ioctl的栈布局进行构造。
一个.ko模块加载到内核后,如何在内核中找到其对应汇编代码,一直比较迷惑,此文解决这个问题。
参考
- http://blog.csdn.net/py_panyu/article/details/45114545 少仲博客
- http://blog.csdn.net/hu3167343/article/details/45507999 如果找不到boot的分区,参考莫灰灰博客(后来发现,这其实在《Android安全攻防权威指南》里的。)
操作
以下在Nexus 5设备操作。
1)查看boot所有分区
root@hammerhead:/ # ls -l /dev/block/platform/msm_sdcc.1/by-name |grep boot
lrwxrwxrwx root root 1970-02-12 17:31 aboot -> /dev/block/mmcblk0p6
lrwxrwxrwx root root 1970-02-12 17:31 abootb -> /dev/block/mmcblk0p11
lrwxrwxrwx root root 1970-02-12 17:31 boot -> /dev/block/mmcblk0p19
root@hammerhead:/ #
2)dump出boot.img
root@hammerhead:/ # dd if=/dev/block/mmcblk0p19 of=/data/local/tmp/boot.img
45056+0 records in
45056+0 records out
23068672 bytes transferred in 0.827 secs (27894403 bytes/sec)
root@hammerhead:/ #
简单验证一下dump出的boot.img文件:
root@hammerhead:/ # busybox hexdump -C -n 200 /data/local/tmp/boot.img
busybox hexdump -C -n 200 /data/local/tmp/boot.img
00000000 41 4e 44 52 4f 49 44 21 20 41 80 00 00 80 00 00 |ANDROID! A......|
00000010 30 9d 07 00 00 00 90 02 00 00 00 00 00 00 f0 00 |0...............|
00000020 00 00 70 02 00 08 00 00 00 00 00 00 00 00 00 00 |..p.............|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 63 6f 6e 73 6f 6c 65 3d 74 74 79 48 53 4c 30 2c |console=ttyHSL0,|
00000050 31 31 35 32 30 30 2c 6e 38 20 61 6e 64 72 6f 69 |115200,n8 androi|
00000060 64 62 6f 6f 74 2e 68 61 72 64 77 61 72 65 3d 68 |dboot.hardware=h|
00000070 61 6d 6d 65 72 68 65 61 64 20 75 73 65 72 5f 64 |ammerhead user_d|
00000080 65 62 75 67 3d 33 31 20 6d 61 78 63 70 75 73 3d |ebug=31 maxcpus=|
00000090 32 20 6d 73 6d 5f 77 61 74 63 68 64 6f 67 5f 76 |2 msm_watchdog_v|
000000a0 32 2e 65 6e 61 62 6c 65 3d 31 00 00 00 00 00 00 |2.enable=1......|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000c0
由 #define BOOT_MAGIC “ANDROID!” ,就是它了。
3)分离 boot.img-kernel 与 boot.img-ramdisk.gz
将boot.img下载到本地,使用split_bootimg.pl这个perl脚本拆分。
split_bootimg.pl 地址:https://gist.github.com/MAGE001/07591653c9f9378d8ffb36b10814bc9f
zzhiyuan@ubuntu:~/zImage$ ./split_bootimg.pl boot.img
Page size: 2048 (0x00000800)
Kernel size: 8405280 (0x00804120)
Ramdisk size: 498992 (0x00079d30)
Second size: 0 (0x00000000)
Board name:
Command line: console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead
user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1
Writing boot.img-kernel ... complete.
Writing boot.img-ramdisk.gz ... complete.
zzhiyuan@ubuntu:~/zImage$
完成后,Android 内核就包含在 boot.img-kernel 中,但现在还不能用IDA分析,因为这是个gzip的自解压文件(注意不是标准gzip文件,还不能使用gunzip解压),需先将里面的gzip文件提取出来。
还有一点,手机厂商可能使用自已的压缩算法,这里不一定都是gzip,需要根据特征码或者文档,选择合适算法解压。如果下面介绍的解压方法中,没有找到gzip头(00088b1f),多半是这个原因。
4)解压 zImage
首先找到其中的标准gzip偏移位置:
zzhiyuan@ubuntu:~$ arm-linux-androideabi-objdump -EL -b binary -D -m armv5t boot.img-kernel |grep 00088b1f
48b4: 00088b1f andeq r8, r8, pc, lsl fp
将其dump出来,注意skip=18612是上面0x48b4的十进制:
zzhiyuan@ubuntu:~$ dd if=boot.img-kernel of=zImage.gz bs=1 skip=18612
8386668+0 records in
8386668+0 records out
8386668 bytes (8.4 MB) copied, 9.1257 s, 919 kB/s
zzhiyuan@ubuntu:~$
将其解压:
zzhiyuan@ubuntu:~/zImage$ gunzip zImage.gz
gzip: zImage.gz: decompression OK, trailing garbage ignored
zzhiyuan@ubuntu:~/zImage$ ls
zImage
用IDA打开,看到已经可以分析。但由于缺少符号表,还是较难阅读。
另外,加载基址选择0xC0008000,就可以与 /proc/kallsyms 中看到的符号地址对应了。
5) IDA导入内核符号表(/proc/kallsyms )
下面的链接,讲了内核没用ELF标准符号表的原因:缩减体积。因此需要我们自己在IDA中导入。少仲文章介绍了如何搜索内核,定位符号位置。我的Nexus 5已经root就不费事了。直接 # echo 0 /proc/sys/kernel/kptr_restrict :-p http://stackoverflow.com/questions/14800515/unknown-arm-linux-kernel-image-format/14811668#14811668
首先通过 # cat /proc/kallsyms >> kernel_synbols.txt 导出内核符号表,其格式如下:
...
c0103168 t vfp_single_fmsc
c0103194 t vfp_single_fmac
c01031c0 t vfp_single_fadd
c0103304 t vfp_single_fsub
编写Python脚本(import_symbols.py):
import idaapi
import idautils
import idc
def do_rename(l):
splitted = l.split()
straddr = splitted[0]
strname = splitted[2].replace("\r", "").replace("\n", "")
eaaddr = int(straddr, 16)
idc.MakeCode(eaaddr)
idc.MakeFunction(eaaddr)
idc.MakeNameEx(int(straddr, 16), strname, idc.SN_NOWARN)
if __name__ == "__main__":
Message("Hello IDC")
f = open( "D:\\TOP1_201601\\android\\exploits\\kernel_symbols.txt", "r")
for l in f:
do_rename(l)
f.close()
依次通过菜单栏的 File->Script file… 导入运行即可,运行后效果如下:
Have Fun!
从android设备中提取内核的更多相关文章
- 从Android设备中提取内核和逆向分析
本文博客链接:http://blog.csdn.net/qq1084283172/article/details/57074695 一.手机设备环境 Model number: Nexus 5 OS ...
- bat如何创建多级文件夹(在android设备中)
在android设备中要创建多个或者多级文件夹时,手动去创建费时费力(有点傻),一个bat文件就能很好的实现这个功能. 1.首先创建同级多个文件夹且在该文件夹下生成一个文件 @echo off ech ...
- XamarinSQLite教程在Xamarin.Android项目中提取数据库文件
XamarinSQLite教程在Xamarin.Android项目中提取数据库文件 由于不能直接打开该文件,开发者需要先将数据库文件从Android系统中提取出来.操作步骤如下. (5)选择MyDoc ...
- 通过ADB命令行卸载或删除你的Android设备中的应用(转载)
转自:http://mytiankong.com/?p=11755 如果你对你的Android设备在与命令行的交互间有一定的兴趣,那你可能想学习一些使用ADB卸载设备中已安装应用的技巧.为了使这种方法 ...
- 在桌面chrome中调试android设备中的web页面
准备工作 1, 桌面版chrome 2, Android设备(安装有chrome浏览器) 3, Android-sdk Android-sdk安装及设置 SKD安装 从http://developer ...
- Android设备中实现Orientation Sensor(图)兼谈陀螺仪
设备中的三自由度Orientation Sensor就是一个可以识别设备相对于地面,绕x.y.z轴转动角度的感应器(自己的理解,不够严谨).智能手机,平板电脑有了它,可以实现很多好玩的应用,比如说指南 ...
- 浅析Android设备中grep命令处理流程
2017-04-18 概述 在TV开发板中,可以在串口中直接使用grep命令.这是因为在/system/bin/下有一个'grep'链接.这个链接指向'/system/bin/toolbo ...
- 通过adb命令在Android设备中执行Java命令, 并调用so文件。
一.难点一:无法复制so文件到/system/lib或者/vendor/lib下,提示只读 解决方法: 2.使用android device monitor放库进入到 /system/lib出现只读权 ...
- android设备中USB转串口demo 下载
http://files.cnblogs.com/guobaPlayer/testUSB2Serial.apk USB转串口demo程序, 无需驱动,只要手机USB是OTG类型,插上我们的模块即可使用 ...
随机推荐
- [洛谷 P2709] 小B的询问
P2709 小B的询问 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数 ...
- Segments
Segments Given n segments in the two dimensional space, write a program, which determines if there e ...
- C++ string::size_type
从逻辑上讲,size()成员函数应该似乎返回整型数值,但事实上,size操作返回是string::size_type类型的值.string类类型和其他许多库类型都定义了一些配套类型(companion ...
- Python3组播通信编程实现教程(发送者+接收者)
一.说明 1.1 标准组播解释 通信分为单播.多播(即组播).广播三种方式 单播指发送者发送之后,IP数据包被路由器发往目的IP指定的唯一一台设备的通信形式,比如你现在与web服务器通信就是单播形式 ...
- python3练习-装饰器
在廖雪峰的官方网站学习装饰器章节时,初步理解类似与面向切面编程.记录一下自己的课后习题解法. 问题: 请编写一个decorator,能在函数调用的前后打印出'begin call'和'end call ...
- LY.JAVA面向对象编程.final、多态、抽象类、接口
2018-07-08 13:47:26 final关键字 多态 从右向前念 多态的成员访问特点及转型的理解 多态的问题理解: class 孔子爹 { public int age = 40; p ...
- day05 数据类型
一.整形int 基本使用: 1,用途:记录年龄\等级\各种号码 2定义方式: age=18 age =int(18) x =int(‘123’)#只能将纯数字的字符串转换成整形 print(t ...
- 自定义xadmin后台首页
登陆xadmin后台,首页默认是空白,可以自己添加小组件,xadmin一切都是那么美好,但是添加小组件遇到了个大坑,快整了2个礼拜,最终实现想要的界面.初始的页面如图: 本机后台显示这个页面正常,do ...
- JAVA的环境变量配置(方式二)
1.想要成功配置Java的环境变量,那肯定就要安装JDK(JDK安装包在方式一中),才能开始配置的. 2.安装JDK 向导进行相关参数设置.如图: 3.正在安装程序的相关功能,如图: 4.选择安装的路 ...
- bzoj1692
题解: 二分最近的不相同 然后hash判断是否相同 然后贪心 代码: #include<bits/stdc++.h> using namespace std; #define ull un ...