Off by one overflow
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Sadece 1B overflow erişimine sahip olmak, bir saldırganın bir sonraki chunk'ın size
alanını değiştirmesine olanak tanır. Bu, hangi chunk'ların gerçekten serbest bırakıldığını manipüle etmeyi sağlar ve potansiyel olarak başka bir geçerli chunk içeren bir chunk oluşturabilir. Sömürü, double free veya üst üste binen chunk'lar ile benzerdir.
İki tür off by one güvenlik açığı vardır:
Keyfi byte: Bu tür, o byte'ı herhangi bir değerle üzerine yazmaya olanak tanır.
Null byte (off-by-null): Bu tür, o byte'ı yalnızca 0x00 ile üzerine yazmaya olanak tanır.
Bu güvenlik açığının yaygın bir örneği, strlen
ve strcpy
davranışının tutarsız olduğu aşağıdaki kodda görülebilir; bu, bir sonraki chunk'ın başında 0x00 byte'ı ayarlamaya olanak tanır.
Bu, House of Einherjar ile sömürülebilir.
Tcache kullanılıyorsa, bu bir double free durumuna dönüştürülebilir.
Diğer kontrollerin yanı sıra, artık bir parça serbest bırakıldığında, önceki boyut, meta verilerin parçasında yapılandırılan boyut ile karşılaştırılmaktadır, bu da bu saldırıyı 2.28 sürümünden itibaren oldukça karmaşık hale getirmektedir.
Bu saldırı artık Tcaches kullanımı nedeniyle çalışmamaktadır.
Ayrıca, daha büyük parçaları kullanarak bunu kötüye kullanmaya çalışırsanız (bu durumda tcaches dahil değildir), malloc(): invalid next size (unsorted)
hatasını alırsınız.
Bir parçanın başka bir parçanın içinde yer almasını sağlamak, böylece o ikinci parçaya yazma erişimi, içeridekini üzerine yazmaya izin verir.
Boyut meta verisi bilgisini değiştirmek için off by one overflow.
Üç parça A
, B
ve C
(örneğin boyut 0x20) ayırın ve üst parçayla birleştirmeyi önlemek için başka bir parça ayırın.
C
parçasını serbest bırakın (0x20 Tcache serbest listesine eklenmiştir).
A
parçasını B
üzerinde taşmak için kullanın. Off-by-one'ı kötüye kullanarak B
'nin size
alanını 0x21'den 0x41'e değiştirin.
Artık B
, serbest parça C
'yi içermektedir.
B
'yi serbest bırakın ve 0x40 boyutunda bir parça ayırın (buraya tekrar yerleştirilecektir).
Hala serbest olan C
'nin fd
işaretçisini değiştirebiliriz (Tcache zehirlenmesi).
3 bellek parçası (a, b, c) ardışık olarak ayrılır. Ardından ortadaki parça serbest bırakılır. İlk parça bir off by one overflow açığı içerir ve saldırgan bunu 0x00 ile kötüye kullanır (önceki byte 0x10 olsaydı, ortadaki parça gerçekte olduğundan 0x10 daha küçük olduğunu gösterirdi).
Ardından, ortada serbest bırakılan parçaya (b) 2 tane daha küçük parça ayrılır, ancak b + b->size
asla c parçasını güncellemez çünkü işaret edilen adres olması gerekenin altındadır.
Ardından, b1 ve c serbest bırakılır. c - c->prev_size
hala b'ye (şimdi b1) işaret ettiğinden, her ikisi de tek bir parçada birleştirilir. Ancak, b2 hala b1 ve c arasında içtedir.
Son olarak, bu bellek alanını geri almak için yeni bir malloc gerçekleştirilir ve bu alan aslında b2'yi içerecektir, bu da yeni malloc'un sahibinin b2'nin içeriğini kontrol etmesine izin verir.
Bu resim saldırıyı mükemmel bir şekilde açıklamaktadır:
strlen
'in bir sonraki parçanın size
alanını dikkate alması nedeniyle off-by-one.
Tcache kullanılıyor, bu nedenle genel off-by-one saldırıları, Tcache zehirlenmesi ile keyfi yazma ilkesini elde etmek için çalışır.
Off by one'ı kötüye kullanarak heap'ten bir adres sızdırmak mümkündür çünkü bir dizeyi aşan 0x00 byte'ı, bir sonraki alan tarafından üzerine yazılmaktadır.
Keyfi yazma, işaretçiyi başka bir yere işaret edecek şekilde sahte işaretçilerle sahte bir yapı oluşturmak için off by one yazma açığını kötüye kullanarak elde edilir. Ardından, bu yapının işaretçisini takip ederek keyfi yazma elde etmek mümkündür.
libc adresi sızdırılır çünkü heap mmap kullanılarak genişletildiğinde, mmap tarafından tahsis edilen bellek libc'den sabit bir ofset ile ayrılmıştır.
Son olarak, keyfi yazma, __free\_hook
adresine bir gadget ile yazmak için kötüye kullanılır.
Kullanıcı girişi satırlarını okuyan getline
fonksiyonunda bir NULL off by one açığı vardır. Bu fonksiyon, içeriğin "anahtarını" okumak için kullanılır ve içeriği değil.
Yazımda 5 başlangıç parçası oluşturulur:
chunk1 (0x200)
chunk2 (0x50)
chunk5 (0x68)
chunk3 (0x1f8)
chunk4 (0xf0)
üst parça ile birleştirmeyi önlemek için chunk defense (0x400)
Ardından chunk 1, 5 ve 3 serbest bırakılır, böylece:
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]