PWN – Ghost Diary

Ghost Diary - 500pt

Challenge

Try writing in this ghost diary.

Hints

None

Solution

WARNING: INSTRUMENT THE EXECUTABLE WITH GLIBC 2.27 OTHERWISE THIS WILL NOT WORK

To instrument the executable, you can employ a program called change-glibc https://github.com/Ayrx/reutils/tree/master/bin

You can use the libc.so.6 and ld-linux-x86-64.so.2 files contained in this folder.
In the exploit, we refer to the instrumented file as to ghost2.27.

The vulnerability of this program is in the function called by the command talk to ghost, which allows writing
data of a certain size, depending on the page that was created first. In particular, this executable is PIE compiled.
When decompiling the related function (starting at offset A5A), we get:

unsigned __int64 __fastcall sub_A5A(__int64 a1, int a2)
{
  unsigned int v2; // eax
  char buf; // [rsp+13h] [rbp-Dh]
  unsigned int v5; // [rsp+14h] [rbp-Ch]
  unsigned __int64 v6; // [rsp+18h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  v5 = 0;
  if ( a2 )
  {
    while ( v5 != a2 )
    {
      if ( read(0, &buf, 1uLL) != 1 )
      {
        puts("read error");
        exit(-1);
      }
      if ( buf == 10 )
        break;
      v2 = v5++;
      *(a1 + v2) = buf;
    }
    *(v5 + a1) = 0;
  }
  return __readfsqword(0x28u) ^ v6;

It is possible to observe that the function writes an additional null byte at the end of the byte stream. This triggers a null-byte
overflow vulnerability.

The general technique to exploit this vulnerability correctly is well-described here: https://devel0pment.de/?p=688

In general, the strategy is divided into three steps:

  • Leaking the libc stack to obtain the base address
  • Controlling a pointer to an arbitrary location in memory
  • Executing proper shellcode

For a detailed description of how the exploit works, we recommend reading the tutorial mentioned above. Our advice is using gdb gef and breaking the program executing after every step, visualizing the heap, and progressively understanding how the whole program works. In the following, we provide some notes that can be useful for exploiting this challenge.

Libc Leak

The libc leak is the most complex step to complete. We essentially need to allocate 4 chunks, one after the other in memory, with specific properties:

  • One chunk of large size, whose overall size in memory should be 0x100 (it could be, for example, 0xf0, the maximum size possible if the executable creates one page. In this case, the overall chunk size in memory is 0xf0+0x10 = 0x100 - this differs from the tutorial where the provided size was 0xf8, which is not possible here due to chunk size limitations imposed by the program).
  • Another smaller chunk of size 0x68 (in this case, the size of the chunk in memory is 0x68+8 = 0x70).
  • A third chunk of the same size as the previous one. Being the overall size 0x100, it is possible to exploit the null byte overflow.
  • A fourth small chunk to avoid consolidation with other areas of memory.

The goal is making the allocator combine the first and the third chunk by compromising the size parameters of the third chunk.
The idea is that, if the size of the first chunk becomes larger, it is possible to overflow the second chunk and perform
arbitrary read/write in memory.

Differently to the tutorial, we observe that the pages are written first to the TCACHE, but we need the target chunks to be in the unsorted bins. To do so, whenever repeating the steps of the tutorial, we always have to allocate and delete 7 pages to fill the TCACHE, for every chunk we want to put in the bins.

Once chunk consolidation is complete, you should be able to leak the stack by using the listen to ghost option from the program.

Controlling the pointer

This part is essentially the same as the tutorial (with the exception of the TCACHE), but it can be simplified. Once you obtained the malloc hook address (use gdb and the base address to get the right offset), you do not need to perform multiple cleanings of the chunks. The critical point is restoring the size of the second chunk to 0x70. You can then reallocate the first chunk with a larger size, in order to write the malloc hook addresses on the second chunk.

Executing the exploit

There are three possible one-gadgets here, and the third is the correct one. However, when writing the gadget on the malloc-hook area, you do not need extra bytes before the address, but you can directly write the target address.
"""

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *