Your task is to get CTARGET to execute the code for touch1 when getbuf executes its return statement, rather than returning to test. 你的任务是运行CTARGET使得当getbuf运行结束后,运行touch1,这些行为要在test返回之前完成。
voidtouch2(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); }
Dump of assembler code for function test: 0x0000000000401968 <+0>: sub $0x8,%rsp 0x000000000040196c <+4>: mov $0x0,%eax 0x0000000000401971 <+9>: callq 0x4017a8 <getbuf> 0x0000000000401976 <+14>: mov %eax,%edx #<getbuf>的返回地址 0x0000000000401978 <+16>: mov $0x403188,%esi 0x000000000040197d <+21>: mov $0x1,%edi 0x0000000000401982 <+26>: mov $0x0,%eax 0x0000000000401987 <+31>: callq 0x400df0 <__printf_chk@plt> 0x000000000040198c <+36>: add $0x8,%rsp 0x0000000000401990 <+40>: retq Dump of assembler code for function getbuf: 0x00000000004017a8 <+0>: sub $0x28,%rsp #此时的%rsp还不是开辟空间的栈顶 0x00000000004017ac <+4>: mov %rsp,%rdi #此时的%rsp是已经开辟空间的栈顶 0x00000000004017af <+7>: callq 0x401a40 <Gets> 0x00000000004017b4 <+12>: mov $0x1,%eax 0x00000000004017b9 <+17>: add $0x28,%rsp 0x00000000004017bd <+21>: retq (gdb) disas touch2 Dump of assembler code for function touch2: 0x00000000004017ec <+0>: sub $0x8,%rsp #<touch2>的函数地址 ----not need watch----
Your task is to get CTARGET to execute the code for touch2 rather than returning to test. In this case, however, you must make it appear to touch2 as if you have passed your cookie as its argument.
Recall that the first argument to a function is passed in register %rdi. %rdi中存储touch2函数着第一个参数。
Your injected code should set the register to your cookie, and then use a ret instruction to transfer control to the first instruction in touch2. 你注入的代码应该把寄存器%rdi设置为cookie,然后中使用ret指令转移控制权到touch2中的第一条指令(即touch2的函数地址0x4017ec)。
(gdb) b *0x4017ac Breakpoint 1 at 0x4017ac: file buf.c, line 14. (gdb) run -q Starting program: /home/duile/Desktop/csapp_lab/attack-handout/ctarget -q Cookie: 0x59b997fa
Dump of assembler code for function hexmatch: 0x000000000040184c <+0>: push %r12 0x000000000040184e <+2>: push %rbp 0x000000000040184f <+3>: push %rbx 0x0000000000401850 <+4>: add $0xffffffffffffff80,%rsp #79_line: 此时%rsp是在原先旧帧(test、getbuf)上再开辟的110bytes空间的栈顶 ...... 0x00000000004018cf <+131>: callq 0x400ca0 <strncmp@plt> ----not need watch----
先看看任务:
Your task is to get CTARGET to execute the code for touch3 rather than returning to test. You must make it appear to touch3 as if you have passed a string representation of your cookie as its argument. 你的任务是让CTARGET执行touch3的代码,而不是返回test。你必须让touch3在test之上(执行)看起来就像你(通过test)传递了一个cookie的字符串表示作为touch3的参数。
再康康建议:
advice:
You will need to include a string representation of your cookie in your exploit string. The string should consist of the eight hexadecimal digits (ordered from most to least significant) without a leading “0x.” 你将会用到cookie的字符表示。这个字符表示是连续的十六进制数字且没有前缀0x。
Recall that a string is represented in C as a sequence of bytes followed by a byte with value 0. Type “man ascii” on any Linux machine to see the byte representations of the characters you need. 在c语言中,字符串表示的结尾是1byte的0(也就是'\0')。你可以在任何Linux机器中,使用man ascii指令查看字符对应的ascii码。
Your injected code should set register %rdi to the address of this string. 你注入的代码应该把%rdi设置为字符串地址。
When functions hexmatch and strncmp are called, they push data onto the stack, overwriting portions of memory that held the buffer used by getbuf. As a result, you will need to be careful where you place the string representation of your cookie. 当函数hexmatch和strncmp被调用时,它们会push数据到栈上,覆盖部分调用getbuf时存储的内容。因此,你应该仔细确定在哪里放入你的cookie。
Tables For convenience, below are more compact tables in hex(Left)anddecimal(Right). 2 3 4 5 6 7 30 40 50 60 70 80 90 100 110 120 ------------- --------------------------------- 0: 0 @ P ` p 0: ( 2 < F P Z d n x 1: ! 1 A Q a q 1: ) 3 = G Q [ e o y 2: " 2 B R b r 2: * 4 > H R \ f p z 3: # 3 C S c s 3: ! + 5 ? I S ] g q { 4: $ 4 D T d t 4: " , 6 @ J T ^ h r | 5: % 5 E U e u 5: # - 7 A K U _ i s } 6: & 6 F V f v 6: $ . 8 B L V ` j t ~ 7: ' 7 G W g w 7: % / 9 C M W a k u DEL 8: ( 8 H X h x 8: & 0 : D N X b l v 9: ) 9 I Y i y 9: '1 ; E O Y c m w A: * : J Z j z B: + ; K [ k { C: , < L \ l | D: - = M ] m } E: . > N ^ n ~ F: / ? O _ o DEL
从左边的16进制表示可以得到cookie的ASCII表示:
1 2
0x59b997fa 3539623939376661
接下来查找test的栈顶地址:
1 2 3 4 5 6 7 8 9 10
(gdb) b *0x40196c Breakpoint 1 at 0x40196c: file visible.c, line 92. (gdb) run -q Starting program: /home/duile/Desktop/csapp_lab/attack-handout/ctarget -q Cookie: 0x59b997fa
Breakpoint 1, test () at visible.c:92 92 visible.c: 没有那个文件或目录. (gdb) p $rsp $1 = (void *) 0x5561dca8
duile@ubuntu:~/Desktop/csapp_lab/attack-handout$ gdb rtarget ...... (gdb) disas addval_273 Dump of assembler code for function addval_273: 0x00000000004019a0 <+0>: lea -0x3c3876b8(%rdi),%eax <movq> 0x00000000004019a6 <+6>: retq End of assembler dump. (gdb) disas addval_219 Dump of assembler code for function addval_219: 0x00000000004019a7 <+0>: lea -0x6fa78caf(%rdi),%eax <popq> 0x00000000004019ad <+6>: retq End of assembler dump.
Before you take on the Phase 5, pause to consider what you have accomplished so far. In Phases 2 and 3, you caused a program to execute machine code of your own design. If CTARGET had been a network server, you could have injected your own code into a distant machine. In Phase 4, you circumvented two of the main devices modern systems use to thwart buffer overflow attacks. Although you did not inject your own code, you were able inject a type of program that operates by stitching together sequences of existing code. You have also gotten 95/100 points for the lab. That’s a good score. If you have other pressing obligations consider stopping right now.