Her C programcının bilmesi gereken güvenlik riskleri / güvenlik açıkları nelerdir? [kapalı]


13

Üst düzey programlama dillerinden iyi test edilmiş ve kanıtlanmış API'lerin kullanılmasıyla donanıma yakın temastan kaynaklanan birçok güvenlik riski vardır. C'de bir arabellek taşmasına neden olmak, Java gibi bir dilde olduğundan çok daha kolaydır.

Her C programcısının bilmesi gereken riskler veya güvenlik açıkları (örneğin, arabellek taşmaları) nelerdir (C programcılarıyla ilgili IE güvenlik açıkları)? Bunlar hangi sorunlara yol açabilir? Onlardan nasıl kaçınılır ve bunların programlarda ortaya çıkmasına neden olan yaygın hatalar nelerdir?


Peki ya bu liste: owasp.org/index.php/Category:OWASP_Top_Ten_Project Bundan başka ne gerekiyor?
S.Lott

2
@ S.Lott: Web geliştirmedeki güvenlik sorunları ile ilgili gibi görünüyor. Genelde istediğimden daha fazla kaynak var gibi görünüyor, öyle görünüyor.
Anto

@Anto: Lütfen , güvenlikle ilgili tüm kaynakları ve sorduğunuz güvenliği ayırt etmek için soruyu güncelleyin .
S.Lott

@ S.Lott: Ne demek istediğinden emin değilim. Çoğu C programcısı için önemli olan, yani arabellek taşmaları ve C'de mümkün olan diğer şeyler için güvenlik istiyorum.
Anto

@Anto: "Genel olarak bu [web güvenliği?] Üzerinde gerçekten istediğimden daha fazla kaynak var gibi görünüyor" Web güvenliği olmayan bir güvenlik sormak istediğinizi söylüyor. Doğru? Öyleyse, aradığınızı açıklamak için lütfen soruyu güncelleyin . Yanlış? Sonra edilir , bu durumda, neden söz belirtilen OWASP listesi değildir, web güvenliği hakkında soran?
S.Lott

Yanıtlar:


13

Arabellek taşmaları büyüktür. C'deki hiçbir şey varsayılan olarak aralık kontrolünden geçirilmez, bu nedenle bir tamponun üzerine yazmak çok kolaydır. gets()Arabellek taşmasını engelleyemeyen ve neredeyse hiç kullanılmaması gereken standart bir kütüphane işlevi vardır .

Yığın bloklarını karıştırmak gibi sömürüyü engellemek için uygulama düzeyinde bazı teknikler vardır, ancak bu, yerel bir arabellekteki arabellek taşmalarını durdurmaz, bu da genellikle bir işlevin geri döneceği adresi değiştirmek gibi ilginç şeyler yapabilir.

C'de iyi bir genel çözüm yoktur. Birçok kütüphane fonksiyonunun yazacakları miktarı sınırlandıracak versiyonları vardır. hesaplama olsa da bu beceriksiz olabilir. Uygun test çalıştırıldığı sürece testte yığın arabellek taşmalarını algılayabilen bir yazılım vardır ve yığın taşması genellikle testte bir kilitlenme olarak görünecektir. Bunun dışında, dikkatli kodlama ve kod incelemesi meselesi.

İlgili bir sorun, bir karakter tarafından çok küçük bir ara belleğe yazma sorunu olup, n karakter uzunluğunda bir C dizesinin, '\0'sonlandırıcı nedeniyle bellekte n + 1 karakter gerektirdiğini unutmasıdır . Saldırgan bir dizgiyi sonlandırıcı olmadan depolamayı başarabiliyorsa, dize bekleyen herhangi bir C işlevi sıfır baytına ulaşana kadar işlemeye devam eder ve bu da istenenden daha fazla bilgi kopyalanmasına veya çıkmasına neden olabilir (veya bir DOS saldırısı için korumalı belleğe çarpabilir) ). Çözüm yine farkındalık, bakım ve kod incelemeleridir.

Ailenin başka bir riski daha var printf(). Hiç yazdıysanız char * str; ... printf(str);, stryazdırıldığında '%' içeriyorsa, kendinizi sorunlara hazırlıyorsunuz. %nBiçim yönergesi verir printf()belleğe yazmak için. Çözüm printf("%s", str);veya puts(str);. (Ayrıca, snprintf()yerine C99 kullanın sprintf().)

İmzasız tamsayıların, özellikle döngü dizinleri olarak kullanılması sorunlara neden olabilir. İmzasız olana küçük bir negatif değer atarsanız, büyük bir pozitif değer elde edersiniz. Bu, yalnızca bir şeyin N örneğini işlemek veya gibi sınırlı işlevlerde işlemlere zarar verebilir strncpy(). Tüm imzalanmamış tam sayıları inceleyin. Bundan kaçınmak isteyebilirsiniz unsigned short, çünkü bunlardan birindeki büyük bir değer bir int.

Unutmayın, C cinsinden bir karakter sabiti aslında bir int. Gibi bir şey yazmak char c; while((c = getchar()) != EOF) ...kolayca başarısız olabilir, çünkü EOFa char.

Düşünebileceğim çok daha karakteristik C hataları var, ancak bunlar güvenlik sorunlarına neden olabilir.


Aynı işi printf("%s", str)yaparken çıplak bir ip için kullanmaya gerek yoktur puts(str).
Blrfl

@Blrfl ama putsyeni satır karakteri eklerken eklemiyor printf.
sağda

Bunu da yapabilirdi fputs(str, stdout), değil.
Blrfl

Tamsayı taşması konusunda: İmzalı girişleri kullanmak çözüm değildir, çünkü taşmaları UB'ye neden olacaktır. Tek (ağrılı) çözüm, ya asla taşmayacağınızı resmi olarak kanıtlamak ya da çalışma zamanında kontrol etmektir (ancak doğru kontrol edin, bu da kontrolde taşmadan zor).
sleske

@DavidThornley: C11 ve C ++ 14 standardı kaldırıldı, tehlikeli olması nedeniyle standart kütüphaneden gets () işlevi.
Yıkıcı

5

C'ye özgü risklerden bazıları şunlardır: arabellek taşmaları , biçimlendirme dizesi saldırıları ve tamsayı taşmaları .


1
Arabellek taşmaları hakkında C'ye özgü hiçbir şey yoktur - işaretçileri olan herhangi bir dil buna sahip olabilir. Tamsayı taşmaları hemen hemen her dil için geçerlidir ve yönetilen kodda da kolayca olabilir.
Steve

1
@Steve, bu soruna neden olan işaretçiler değil, dilin dizi sınırlarını nasıl zorlamadığı.
Doug T.

2
@Soru, soru sadece C'yi ilgilendiren şeyler değil, C programcılarının bilmesi gereken bir şey sormaktı.
AttackingHobo

1
@Steve: C, kısmen aralık denetimi için destek eksikliği ve sizin için arabellekleri mutlu bir şekilde dolduracak kütüphane işlevlerinin sayısı nedeniyle, arabellek taşmalarına olağandışı bir şekilde duyarlıdır.
David Thornley

Sorunun özellikle C hakkında sorduğunu anlıyorum, ancak cevabın bu risklerin daha genel olduğu bağlamdan okunması durumunda açıklığa kavuşturmaya değer olduğunu düşünüyorum. Özellikle yönetilen kod geliştiricileri (IMHO) güvenlik konusunda çok fazla şikayetçidir ve özellikle tamsayı taşmaları çoğu dili etkilemektedir.
Steve

4

İşte düzeltilmesi saatler sürecek sorunlara neden olabilecek bir riski kaçırmak kolaydır.

Sorunsuz derlenecek aşağıdaki kodu göz önünde bulundurun.

if(lpstr_current_state = CONST_EMERGENCY_STATE_HOLY_CRAP)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

Eğer görmek için kontrol zaman eğer lpstr_current_stateiçindedir CONST_EMERGENCY_STATE_HOLY_CRAPaslında atama ediyoruz. Sabit değişkeni her zaman sola koymak daha iyidir. Sabiti sola koyduğunuzda, bir değişkene değer atayamayacağınız için derleyici başarısız olur.

if(CONST_EMERGENCY_STATE_HOLY_CRAP = lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

O zaman kolayca okumak için kodu sabitlerken, kendinize, "kötü bok olabilir, bu kötü olabilir" diyebilirsiniz ...

if(CONST_EMERGENCY_STATE_HOLY_CRAP == lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

7
Bir derleyicinin diğer sorunlardan farklı olarak bir uyarı olarak yakalaması ve işaretlemesi kolaydır. Ne yazık ki, tüm derleyiciler bunu yapmayı kolaylaştırmaz.
David Thornley

2
Bu, C dışındaki dillerde =ve ve dillerini kullanan herhangi bir dilde olabilir ==.
FrustratedWithFormsDesigner

3
Bu aynı zamanda bir güvenlik açığı değildir, bu bir hatadır.
Chris Pitman

1
Bunlara Yoda koşulları denir.

2
@Kristofer Hoch: Eğer herhangi bir C hatasını bir risk olarak adlandıracak ve burada ele alacaksak, çok daha büyük bir foruma ihtiyacımız olacak.
David Thornley

0

Sadece bir güvenlik riski vardır: Yazılımınızdaki herhangi bir güvenlik açığını yakalamak ve kendi kazançları için bu açıktan yararlanmak için elinden gelenin en iyisini yapacak kişiler olması. Diğer her şey oradan gelir.

Yani "doğru akıllarında kimse ..." diye düşünmüyorsanız, o zaman hemen düşünmelisiniz "dışında başkalarının bilgisayarlarına hack etmek isteyen biri tam da bunu yapacaktır".

En büyük sonuç, dışarıdaki olaylara her tepki verdiğinizde (örneğin, dışarıdan gönderilen verileri işleyerek), bu verilerin en kötü düşmanınızın kontrolü altında olduğunu varsaymanız gerekir.


İkinci ve üçüncü paragrafları kabul ederken, tüm suçu saldırgana atmak gözlerimde biraz kalın. Başarılı bir saldırı için her zaman iki tane gerekir: Vidalayan bir programcı ve eylemde programcıyı yakalayan bir saldırgan. Ancak güvenlik açığı, saldırganın bundan yararlanabilmesi için önce vardır . Ve bunun için programcı suçlanacak.
cmaster - eski haline monica
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.