简单完成了前两个lab,现在来看看第三个。
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);
}
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;
}
与level2类似,传入一个参数,但是传的是字符串首地址。所以rdi中存放的应该是个地址。touch3调用的是hexmatch函数,大体意思是rdi存放的地址的字符串内容要与cookie的8位asacill码一一对应才能成功。
其中cookie值为0x59b997fa
它的ascii值为35 39 62 39 39 37 66 61(根据百度16进制转ascii搜的)
当然这些ascii应该存在哪?因为s不确定,所以存在getbuf上的test的栈帧最好,即getbuf的返回地址的上一个地址。
即0x5561dca8这是test的栈帧部分,hexmatch调用sprintf,以及strncmp压栈可能会覆盖getbuf的数据,所以用到test的栈帧。
借用简书金际一线天 的图
这个图非常形象的描写了这个过程。
即编写汇编:
然后汇编
反汇编得到机器码
接着编写攻击脚本
(最后一行是cookie的ascii码)
最后借助hex2raw攻击
成功!