题目信息

解题步骤

使用DIE分析:

使用IDA分析

1
2
v8 = __readfsqword(0x28u);  // Canary,防栈溢出
pid = fork(); // 关键!创建子进程

fork() 的行为回顾

  • fork() 创建一个子进程复制父进程的内存空间
  • 子进程返回 0
  • 父进程返回子进程 PID
  • 之后两个进程独立运行

所以:

1
2
if (pid) { /* 父进程 */ } 
else { /* 子进程 */ }

flag 字符串到底被谁修改了?

看这段代码:

1
2
3
4
5
6
7
8
else
{
for ( i = 0; i <= strlen(flag); ++i )
{
if ( flag[i] == 105 || flag[i] == 114 )
flag[i] = 49;
}
}
  • 105'i'
  • 114'r'
  • 49'1'

所以:子进程把 flag 中的 'i''r' 都替换成了 '1'

我立刻打开 IDA,查找 flag 的定义。

.data 段发现:

flag 是一个位于 .data 段的全局字符串:

代码理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int __fastcall main(int argc, const char **argv, const char **envp)
{
int stat_loc;
int i;
__pid_t pid;
char s2[24];
unsigned __int64 v8;

v8 = __readfsqword(0x28u); // Stack Canary
pid = fork(); // 创建子进程

if ( pid )
{
waitpid(pid, &stat_loc, 0); // 父进程等待子进程结束
}
else
{
// 子进程执行
for ( i = 0; i <= strlen(flag); ++i )
{
if ( flag[i] == 105 || flag[i] == 114 ) // 'i' 或 'r'
flag[i] = 49; // 替换为 '1'
}
}

printf("input the flag:");
__isoc99_scanf("%20s", s2);

if ( !strcmp(flag, s2) )
return puts("this is the right flag!");
else
return puts("wrong flag!");
}

所以最终的flag是:{hack1ng_fo1_fun}

flag{hack1ng_fo1_fun}