Yarış durumu güvenlik açıkları, HackerOne platformundaki raporların %0,3’ünden azını oluşturuyor. Ancak araştırmacılar, James Kettle’ın 2023’te BlackHat’ta sunduğu “Devlet Makinesi” araştırmasının bir sonucu olarak, son zamanlarda ırk durumu zayıflıkları üzerinde deneyler yapmaya özellikle ilgi duyuyorlar.
Bu blog, bu araştırmayı World ID Yazılım Geliştirme Kitine (SDK) nasıl uyguladığımın ve bir saldırganın bulut tabanlı bir uygulamada önceden belirlenmiş doğrulama sınırını atlamasına olanak tanıyan bir yarış durumunu nasıl belirlediğimin öyküsünü anlatıyor. Bu güvenlik açığından yararlanılması, bir kullanıcının gerçekleştirebileceği eylem sayısını kısıtlamak için World ID’ye dayanan bir projeyi etkileyebilir (örneğin, bir proje, kullanıcının yalnızca bir oy kullanabilmesini sağlamak için SDK kullanıyorsa, saldırgan 20 oy vermek için güvenlik açığından yararlanabilir).
Yarış Durumu Nedir?
Yazılımın davranışı kontrol edilemeyen olayların sırasına veya zamanlamasına bağlı olduğunda bir yarış durumu ortaya çıkar. Bu kusur, birden çok işlemin veya iş parçacığının paylaşılan kaynaklara uygun senkronizasyon olmadan eşzamanlı olarak eriştiği ve değiştirdiği ortamlarda ortaya çıkar ve öngörülemeyen sonuçlara yol açar.
Yarış koşullarının getirilmesi genellikle eşzamanlılığa ilişkin yetersiz tasarım değerlendirmesine (örneğin, istekleri eşzamanlı olarak işlerken yeterli önlemlerin alınmaması) ve paylaşılan verilere erişim kontrollerinin hatalı uygulanmasına atfedilir. Yaygın bir senaryo, işlemlerin atomik olmasını sağlamadan paylaşılan bir değişkeni hem okuyan hem de ona yazan iki iş parçacığını içerir. Uygun kilitleme mekanizmaları veya atomik işlemler olmadan, paylaşılan kaynağın son durumu yürütme sırasına bağlı hale gelir, bu da tutarsızlıklara yol açar ve potansiyel olarak sistemin bütünlüğünü ve güvenliğini tehlikeye atar.
Bu güvenlik açıkları, yetkisiz eylemlere, veri bozulmasına ve hatta sistem çökmelerine neden olacak şekilde kullanılabilir. En kötü senaryoda, saldırganlar güvenlik mekanizmalarını atlatmak, hassas verilere yetkisiz erişim sağlamak veya rastgele kod çalıştırmak için yarış koşullarından yararlanarak kurumsal güvenlik ve veri bütünlüğü açısından önemli riskler oluşturabilir. Yarış koşullarını ele almak, tasarım ve test etme konusunda titiz bir yaklaşım gerektirir; eşzamanlılık kontrolünün vurgulanması ve paylaşılan kaynaklar üzerindeki kritik işlemlerin atomik olarak gerçekleştirilmesinin sağlanması.
Worldcoin’in Arka Planı
2019’da Blockchain sahnesine çıktığından beri Worldcoin’e ilgi duyuyorum. Worldcoin, a) benzersiz insanları biyometrik olarak doğrulamak ve b) Evrensel Temel Gelir (UBI) için bir dağıtım mekanizması için bir temel oluşturmayı amaçlayan bir kripto para birimi projesidir. Çoğu kişi muhtemelen bunu, içine bakarsanız size kripto para birimi verecek bir küre inşa eden şirket olarak biliyor.
İnsanların gözbebeklerini taraması ve biyometrik verileri merkezi bir varlığa vermesi fikri kesinlikle tartışmalıdır, ancak Worldcoin’in yaklaşımı, internetin bugün karşı karşıya olduğu en zor sorunlardan biri olan Sybil direncini sağlar (Sybil saldırısı, bir saldırganın birden fazla veri oluşturduğu bir güvenlik tehdididir). Bir ağ üzerinde orantısız derecede büyük bir etki elde etmek için sahte kimlikler kullanmak.) Herkesin yapay zeka destekli yüzlerce bot yaratabildiği bir dünyaya yaklaştıkça, Sybil direnci çözülmesi gereken kritik bir sorun haline gelecektir (Sam’in Altman, Worldcoin’in kurucularından biridir ve Worldcoin bu konu üzerinde anlamlı bir şekilde çalışan tek projeden biridir.
Worldcoin’i incelemeye başlamadan önce bunun tamamen bir kripto para birimi dağıtım mekanizması olduğunu varsaymıştım ancak daha derine indikçe biyometrik kimlik doğrulama etrafında bir Yazılım Geliştirme Kiti (SDK) oluşturduklarını gördüm. Bu, diğer uygulamaların bir kullanıcının = bir insan olduğunu doğrulamak için Worldcoin SDK’yı kullanabileceği anlamına gelir. Bu çok önemli bir şey gibi görünmeyebilir ancak oylama, airdrop ve bot koruması gibi kullanım alanları olan uygulamalar için ezber bozan bir özelliktir. Örneğin, benzersiz bir insanın belirli bir konu hakkında yalnızca bir kez oy verebilmesini sağlayan bir uygulama yapmak istersem, tüm kullanıcılarımın esasen bir Kimlik Sağlayıcı (IDP) görevi görecek olan Worldcoin SDK aracılığıyla kimlik doğrulamasını sağlayabilirim. ) ve önceden yapılandırdığım sınırlamanın uygulayıcısı (yani bir kez oy verin).
Bir kripto para birimi olarak Worldcoin, (EVM uyumlu) blockchainler için çalışan bir SDK uygulamasına ve herhangi bir blockchaine dokunmayı gerektirmeyen bulut tabanlı bir versiyona sahiptir. Her iki sürüm de, aşina değilseniz okumaya değer, kurcalamaya dayanıklı bir işlem günlüğü oluşturmak için gerçekten harika Merkle ağacı tabanlı şifreleme kullanır.
Worldcoin üzerinde test etme
Geliştiricilerin Worldcoin iş akışını test etmesine yardımcı olmak için Worldcoin, işlemleri ve doğrulamaları test etmek için bir simülatör sunar (bağlantı burada). Bir geliştirici hesabı oluşturursam, “eylemler” oluşturabilir (ör. “bu teklife oy verin”) ve maksimum sayıda “doğrulama” (ör. “bir insanın bir teklife oy verebileceği sayı) ayarlayabilirim. Tüm bunların nasıl çalıştığını anlamak için testlerimin çoğunu bu simülatör üzerinde yaptım ve istekleri Burp Suite aracılığıyla çalıştırdım.
“Kimlik bilgisi türü” (“küre” veya “cihaz”) veya “zincir” gibi şeyleri değiştirebilsem de isteklerin hepsi birbirine çok benziyordu. Akışı ve imzaları kırmak için saatlerce uğraştım ama ilginç bir şey elde etmekte başarısız oldum, bu yüzden birkaç hafta vazgeçtim.
DEF CON 31’e ilerleyin ve James Kettle Smashing The State Machine hakkındaki araştırmasını sundu. Blogunu okur okumaz bunun Worldcoin’de deneyebileceğim bir şey olduğunu fark ettim. Burp Repeater sekmesini açtım, “paralel gönder” özelliğine sahip Burp güncellemesini indirdiğimden emin oldum ve daha önce anlattığım Worldcoin akışını denedim.
Özellikle adımlar şunlardı:
- İsteği yakalayın ve tekrarlayıcıya gönderin
- İstek için yeni bir “sekme” oluşturun
- Orijinal isteği yeni “sekmede” ~20 kez kopyalayın
- Hepsini “paralel olarak” gönder
İsteklere baktığımda işe yaradı! “Eşsiz insanlar”ın yalnızca iki doğrulamasını görmem gerekirken 20 tane gördüm!
Bunu yalnızca uygulamanın “bulut” sürümünde test ettim çünkü bunun “blockchain” sürümünde çalışmayacağından oldukça emindim çünkü bu, bir işlemin sonuçlandırılmasını gerektirecekti.
Worldcoin projesi açık kaynak olduğundan kodu inceledim ve ‘canVerifyForAction’ kullanımında kırmızı bir bayrak gördüm:
dışa aktarma const canVerifyForAction = (
geçersizleştiriciler:
| Dizi<{
nullifier_hash: dize;
}>
| tanımlanmamış,
max_verifications_per_person: sayı
): boole => {
if (!geçersizleştiriciler?.uzunluk) {
// Kişi daha önce doğrulama yapmamıştır, her zaman ilk kez doğrulama yapabilir
doğruyu döndür;
} else if (max_verifications_per_person <= 0) {
// `0` veya `-1` sınırsız doğrulama anlamına gelir
doğruyu döndür;
}
// Aksi takdirde, yalnızca maksimum doğrulama sayısına ulaşılmadığı takdirde doğrulama yapılabilir
return (nullifiers?.length ?? 0) < max_verifications_per_person;
}
Spesifik olarak, burada kod tabanının diğer kısımlarında “nullifier”a başvurulma şekli, bir “kilit” olmadan bir diziye eklendiğinden bir yarış koşuluna izin veriyordu; bu, paralel isteklerin hepsinin eşit şekilde ele alınacağı anlamına geliyordu.
Azaltma
Worldcoin ekibi bu sorunu, veritabanını kullanarak yapay bir kilit oluşturarak çözdü; böylece iki istek aynı anda gelse bile, bunlar düzgün bir şekilde ele alınacak. Bu çekme isteğinde, artık “geçersiz kılıcılar” için yeni veritabanı tablolarına sahip olduklarını ve “canVerifyForAction” kodunu yalnızca uzunluk yerine “geçersiz kılıcı” kullanım sayısına referans verecek şekilde güncellediklerini görebilirsiniz:
dışa aktarma const canVerifyForAction = (
geçersizleştirici:
| {
kullanır: sayı;
nullifier_hash: dize;
}
| tanımlanmamış,
max_verifications_per_person: sayı
): boole => {
if (!nullifier) {
// Kişi daha önce doğrulama yapmamıştır, her zaman ilk kez doğrulama yapabilir
doğruyu döndür;
} else if (max_verifications_per_person <= 0) {
@@ -146,7 +147,7 @@ ihracat const canVerifyForAction = (
}
// Aksi takdirde, yalnızca maksimum doğrulama sayısına ulaşılmadığı takdirde doğrulama yapılabilir
return nullifier.uses < max_verifications_per_person;
};
İnsanlar bir “blockchain” veya “Web3” projesi düşündüklerinde genellikle herhangi bir güvenlik açığının ağ veya akıllı sözleşmeyle sınırlı olacağını varsayarlar; ancak durum çoğu zaman böyle değildir. Günümüzde Web3 hala büyük ölçüde Web2’ye dayanmaktadır ve bu, çok çeşitli yaratıcı saldırı vektörlerinin önünü açmaktadır. Eğer bir Javascript uzmanıysanız ve Web3 projelerinde hata aramayı denemediyseniz, parayı masada bırakıyorsunuz demektir!
Bu sorunu özenle çözdüğü ve bunu Hacktivity’de açıklamama izin verdiği için Dünya ekibine teşekkür etmek istiyorum.
Yarış Koşullarının Ele Alınması:
Yarış durumu zayıflıklarını önlemek veya azaltmak için geliştiriciler ve mimarlar aşağıdakiler gibi çeşitli stratejiler kullanabilir:
- Paylaşılan kaynaklara erişimi yönetmek için uygun senkronizasyon tekniklerinin uygulanması.
- Eşzamanlılık göz önünde bulundurularak sistemlerin tasarlanması, paylaşılan kaynaklar üzerindeki işlemlerin atomik olmasını sağlamak.
- Eşzamanlılığı güvenli bir şekilde ele almak için tasarlanmış üst düzey soyutlamalar ve programlama yapılarını kullanma.
- Potansiyel yarış koşullarını ortaya çıkarmak ve düzeltmek için stres testleri ve eşzamanlılık testleri de dahil olmak üzere kapsamlı testler yapmak.