[ pwn 学习 ] CTFshow-pwn4
2026-08-22 20:36:38

pwn4

打开附件 反编译

字符串比较口令校验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int __fastcall main(int argc, const char **argv, const char **envp)
{
char s1[11];
char s2[12];
unsigned __int64 v6;

v6 = __readfsqword(0x28u);
setvbuf(_bss_start, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
strcpy(s1, "CTFshowPWN");
logo();
puts("find the secret !");
__isoc99_scanf("%s", s2);
if ( !strcmp(s1, s2) )
execve_func();
return 0;
}

C语言的反编译版本。IDA把机器代码“猜回”C,所以名字看上去奇怪。本质上还是C语言

1
int __fastcall main(int argc, const char **argv, const char **envp)

main是程序固定入口

intmain最后会返回一个整数(0表示正常结束)

argc/argv/envp是命令行参数(这里可以不用管

_fastcall是编译器用的调用方式,对题目逻辑没影响

1
2
3
char s1[11];
char s2[12];
unsigned __int64 v6;
  • char s1[11];
    开一块能放11个字符的空间
  • char s2[12];
    开一块能放12个字符的空间
  • unsigned __int64 v6;
    一个 64 位无符号整数。
    这个是栈保护值,暂时理解为安全锁
1
v6 = __readfsqword(0x28u);

读取栈保护值。是编译器加的,防止栈溢出攻击。和题目逻辑无关

1
2
setvbuf(_bss_start, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);

让输入输出立刻显示,不等缓冲,这样交互更流畅

1
strcpy(s1, "CTFshowPWN");

strcpy是把右边字符串复制到左边的数组里

所以s1现在是CTFshowPWN

1
2
logo();
puts("find the secret !");

logo()是打印题目banner

puts()是打印一句话

1
__isoc99_scanf("%s", s2);

"%s"是“读入一个字符串”

你的输入会被存进s2

1
2
if ( !strcmp(s1, s2) )
execve_func();
  • strcmp(s1, s2)比较两个字符串。
    • 如果相同,返回0
    • 如果不同,返回非0
  • !strcmp(...) 的意思是“如果它们相同”
  • 如果相同,执行 execve_func()
1
return 0;

程序结束正常退出

因此这里要输入s1数值,你输入的内容就存入s2,与真实的s1比较,相同则执行execve_func()

反编译execve_func(),发现就是进入一个shell

1
2
CTFshowPWN
cat /ctfshow_flag


相关笔记

  • pwn0strcpy 函数详解与溢出原理
  • pwn3 — 函数选择:直接调用后门函数
  • pwn23strcpy 栈溢出 → SIGSEGV 信号劫持
  • pwn25 ret2libc 栈溢出利用 (NX 绕过) — 进阶:栈溢出 + ROP 链
上一页
2026-08-22 20:36:38
下一页