2016-04-05 20 views
-2

64 bit Linux'ta C'deki Biçim Dizisi Güvenlik Açığı'nın basit bir örneğini uygulamaya çalışıyorum. Aşağıdaki dizeBiçim Dizesi Exploit, beklenmeyen sonuç

AAAABBBB-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x 

programlamak için

void not_called() { 
    printf("Exploited\n"); 
} 

int main(int argc, char **argv) { 

    // Buffer overflow vulnerability 
    char buffer[256]; 
    gets(buffer); 

    // User may input the format string 
    printf(buffer); 
} 

ben girişi Ve sonuç ben 41414141 olarak AAAA nokta olabilir ama BBBB takip etmiyor

AAAABBBB-8608002c-f458fe00-fbad2288-78252d78-252d7825-5e5c51a8-0-41414141-2d78252d-78252d78-252d7825-2d78252d 

geçerli: İşte benim kaynak kodu beklediğim gibi, tampondaki aynı girdi dizesinin ayrılmaz bir parçası.

Bu bir çeşit koruma mekanizması mı yoksa bir şeyi yanlış yorumlu muyum? Amacım, iade adresinin üzerine yazmam ve 64 bitlik makinede çalışırken 8 bayt (AAAABBBB) okumam gerekiyor. dizeyi istismar için

Sözde kod

RETRNPTR%[decimal address of not_called - 8]u%[offset of RETRNPTR]$n 

RETRNPTR benzer görünümde olacaktır şimdiki yığın çerçevede dönüş adresini saklamak belleğin adresidir.

En büyük endişem şu ki, 8 baytlık RETRNPTR beklendiği gibi sürekli bellekte görünmüyor. İkinci endişe,% n, int-pointer, yani sadece 4 bayt yazılır. Ayrıca, AAAA'dan önceki değerlerin nereden geldiği konusunda kafam karıştı.

+0

Sen tanımsız davranış çağırıyoruz aldık. Tam olarak ne olduğunu anlamak için sökmeye bakın. –

+0

C dilinde 'gets' denen bir işlev yoktur. C bilginizi güncellemeniz gerekiyor, 'gets' 17 yıl önce eskimiş olarak işaretlendi. – Lundin

+0

Ve ne düşünüyorsunuz printf ("AAAABBBB-% x-% x-% x-% x-% x-% x-% x-% x-% x-% x-% x-% x") ' Hiçbir değişken listesi ile belirtilen yok mu? – Lundin

cevap

2

Her şeyden önce, tanımlanmamış davranışı olan bir kod hakkında soru soruyorsunuz; Kodun davranışı, sıradan bir C programcısı tarafından tanımlanmayan bölümün çoğu için olmalıdır.

Şimdi, neden görmediğinize göre BBBB. Sanırım, bu programı x86-64 sisteminde çalıştırıyorsunuz. Orada çağrı kuralı yığında devam eden değerler için 64-bit itme yapmaktır; Ancak %x, 32 bit int yazdıran; En az 32 bitlik 64 bitlik yığın değeri. 64-bit long değerlerini yazdırmak için %lx kullanın.

(Aynı zamanda, x86-64 için Sistem V API 6 birinci tamsayı/işaretçi argümanlar tüm yığın gitmez, onlar RDI, RSI, RDX, RCX, R8 ve R9 yazmaçlarda konum).

Örneğin girdiğim:

AAAABBBB %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx 

ve çıkış

AAAABBBB 7f7c0a88f030 7f7c0a66b980 7f7c0a669980 7f7c0a88f031 786c2520786c2520 7ffc1456b6f8 
100000000 4242424241414141 786c2520786c2520 786c2520786c2520 
+0

Ayrıca, ilk n bağımsız değişkenler yığında değil, kayıtlarda olabilir. –

+0

@MichaelWalz, eklendi. –

+0

Yani, biçim dizeleriyle ilgili durum tutucu değişkenleri her zaman varsayılan sözcük boyutuyla (x86-64'te 8 bayt) ve biçim türünün kendisi ile hizalanmaz mı? % x, bir kelimeden düşük 4 bayt okur ve% x'i izleyen, aşağıdaki sözcükten 4 baytlık okuyacaktır? –

İlgili konular