İki ZK Güvenlik Açığının Derinlemesine Analizi

Orta SeviyeJun 05, 2024
Bu makale, Sıfır Bilgi Kanıtı (ZKP) sistemlerindeki iki olası güvenlik açığının derinlemesine bir analizini sağlar: "Load8 Veri Ekleme Saldırısı" ve "Sahtecilik İade Saldırısı". Makale, bu güvenlik açıklarının teknik özelliklerini, bunlardan nasıl yararlanılabileceğini ve bunları düzeltme yöntemlerini detaylandırıyor. Ek olarak, ZK sistemlerinin denetim ve resmi doğrulama süreçleri sırasında bu güvenlik açıklarının keşfedilmesinden öğrenilen dersleri tartışır ve ZK sistemlerinin güvenliğini sağlamak için en iyi uygulamaları önerir.
İki ZK Güvenlik Açığının Derinlemesine Analizi

Önceki bir makalede, Sıfır Bilgi Kanıtı (ZKP) sistemlerinin gelişmiş resmi doğrulamasını tartıştık: bir ZK talimatının nasıl doğrulanacağı. Her zkWasm komutunu resmi olarak doğrulayarak, tüm zkWasm devresinin teknik güvenliğini ve doğruluğunu tam olarak sağlayabiliriz. Bu makalede, güvenlik açığı keşfi perspektifine, denetim ve doğrulama süreçlerinde tespit edilen belirli güvenlik açıklarının analizine ve bunlardan çıkarılan derslere odaklanacağız. ZKP blok zincirlerinin gelişmiş resmi doğrulaması hakkında genel bir tartışma için lütfen ZKP blok zincirlerinin gelişmiş resmi doğrulaması hakkındaki makaleye bakın.

ZK güvenlik açıklarından bahsetmeden önce, CertiK'in ZK resmi doğrulamasını nasıl gerçekleştirdiğini anlayalım. ZK Sanal Makinesi (zkVM) gibi karmaşık sistemler için, resmi doğrulamanın (FV) ilk adımı, neyin doğrulanması gerektiğini ve özelliklerini açıkça tanımlamaktır. Bu, ZK sisteminin tasarımının, kod uygulamasının ve test kurulumunun kapsamlı bir şekilde gözden geçirilmesini gerektirir. Bu süreç, düzenli denetimlerle örtüşür, ancak incelemeden sonra doğrulama hedeflerinin ve özelliklerinin belirlenmesi gerektiği için farklılık gösterir. CertiK'te buna denetim odaklı doğrulama diyoruz. Denetim ve doğrulama çalışmaları genellikle entegre edilmiştir. zkWasm için hem denetim hem de resmi doğrulamayı aynı anda gerçekleştirdik.

ZK Güvenlik Açığı Nedir?

Sıfır Bilgi Kanıtı (ZKP) sistemlerinin temel özelliği, çevrimdışı veya özel olarak yürütülen hesaplamaların (blok zinciri işlemleri gibi) kısa bir şifreli kanıtının bir ZKP doğrulayıcısına aktarılmasına izin vermesidir. Doğrulayıcı, hesaplamanın iddia edildiği gibi gerçekleştiğinden emin olmak için kanıtı kontrol eder ve onaylar. Bu bağlamda, bir ZK güvenlik açığı, bir bilgisayar korsanının yanlış işlemler için sahte ZK kanıtları göndermesine ve bunları ZKP doğrulayıcısı tarafından kabul etmesine olanak tanır.

Bir zkVM kanıtlayıcı için, ZK kanıt süreci bir program çalıştırmayı, her adım için yürütme kayıtları oluşturmayı ve bu yürütme kayıtlarını bir dizi sayısal tabloya dönüştürmeyi ("aritmetikleştirme" olarak bilinen bir süreç) içerir. Bu sayılar, belirli tablo hücreleri, sabit sabitler, tablolar arasındaki veritabanı arama kısıtlamaları ve her bir bitişik tablo satırı çiftinin karşılaması gereken polinom denklemleri (veya "geçitler") arasındaki ilişkileri içeren bir dizi kısıtlamayı ("devre") karşılamalıdır. Zincir içi doğrulama, tablo içindeki belirli sayıları açıklamadan tüm kısıtlamaları karşılayan bir tablonun varlığını doğrulayabilir.


zkWasm'de Aritmetizasyon Tablosu

Her kısıtlamanın doğruluğu çok önemlidir. Bir kısıtlamadaki herhangi bir hata, ister çok zayıf ister eksik olsun, bir bilgisayar korsanının yanıltıcı kanıtlar sunmasına izin verebilir. Bu tablolar bir akıllı sözleşmenin geçerli bir şekilde yürütülmesini temsil ediyor gibi görünebilir, ancak gerçekte değildir. Geleneksel VM'lerle karşılaştırıldığında, zkVM işlemlerinin opaklığı bu güvenlik açıklarını güçlendirir. ZK olmayan zincirlerde, işlem hesaplamalarının ayrıntıları blok zincirine herkese açık olarak kaydedilir; ancak zkVM'ler bu ayrıntıları zincir üzerinde depolamaz. Bu şeffaflık eksikliği, bir saldırının ayrıntılarını veya bir saldırının gerçekleşip gerçekleşmediğini belirlemeyi zorlaştırır.

zkVM komutlarının yürütme kurallarını uygulayan ZK devresi son derece karmaşıktır. zkWasm için, ZK devresinin uygulanması 6.000'den fazla Rust kodu satırı ve yüzlerce kısıtlama içerir. Bu karmaşıklık genellikle keşfedilmeyi bekleyen birden çok güvenlik açığı olabileceği anlamına gelir.


zkWasm Devre Mimarisi

Gerçekten de, zkWasm'ın denetlenmesi ve resmi olarak doğrulanması yoluyla, bu tür birkaç güvenlik açığı keşfettik. Aşağıda, iki temsili örneği tartışacağız ve aralarındaki farkları inceleyeceğiz.

Kod Güvenlik Açığı: Load8 Veri Enjeksiyon Saldırısı

İlk güvenlik açığı, zkWasm'daki Load8 komutunu içerir. zkWasm'da, yığın belleği okumaları, N'nin yüklenecek verilerin boyutu olduğu bir dizi LoadN talimatı kullanılarak gerçekleştirilir. Örneğin, Load64 bir zkWasm bellek adresinden 64 bit veri okumalıdır. Load8, bellekten 8 bitlik verileri (yani bir bayt) okumalı ve 64 bitlik bir değer oluşturmak için sıfırlarla doldurmalıdır. Dahili olarak, zkWasm belleği 64 bitlik bir bayt dizisi olarak temsil eder, bu nedenle bellek dizisinin bir bölümünü "seçmesi" gerekir. Bu, birlikte tam 64 bit yük değerini oluşturan dört ara değişken (u16_cells) kullanılarak yapılır.

Bu LoadN komutlarının kısıtlamaları aşağıdaki gibi tanımlanır:

Bu kısıtlama üç duruma ayrılır: Load32, Load16 ve Load8. Load64'ün herhangi bir kısıtlaması yoktur çünkü bellek birimleri tam olarak 64 bittir. Load32 durumu için kod, bellek birimindeki yüksek 4 baytın (32 bit) sıfır olmasını sağlar.

Load16 durumu için kod, bellek birimindeki yüksek 6 baytın (48 bit) sıfır olmasını sağlar.

Load8 durumu için, bellek birimindeki yüksek 7 baytın (56 bit) sıfır olmasını gerektirmelidir. Ne yazık ki, kodda durum böyle değil.

Gördüğünüz gibi, yalnızca yüksek 9 ila 16 bit sıfırla sınırlıdır. Diğer yüksek 48 bit herhangi bir değer olabilir ve yine de "bellekten okuma" olarak geçebilir.

Bu güvenlik açığından yararlanan bir bilgisayar korsanı, meşru bir yürütme dizisinin ZK kanıtını kurcalayarak Load8 komutunun bu beklenmeyen baytları yüklemesine neden olarak veri bozulmasına neden olabilir. Ayrıca, çevredeki kod ve verilerin dikkatli bir şekilde düzenlenmesi yoluyla, yanlış yürütmeleri ve aktarımları tetikleyerek veri ve varlık hırsızlığına yol açabilir. Bu sahte işlemler, zkWasm denetleyicilerinin kontrollerini geçebilir ve blok zinciri tarafından yanlış bir şekilde meşru işlemler olarak tanınabilir.

Bu güvenlik açığını düzeltmek aslında oldukça basittir.

Bu güvenlik açığı, kodun uygulanmasından kaynaklandıkları ve küçük yerel kod değişiklikleriyle kolayca düzeltilebildikleri için "kod güvenlik açıkları" olarak adlandırılan bir ZK güvenlik açığı sınıfını temsil eder. Kabul edebileceğiniz gibi, bu güvenlik açıklarını insanların tanımlaması da nispeten daha kolaydır.

Tasarım Güvenlik Açığı: Sahte İade Saldırısı

Bu sefer zkWasm'ın çağrılması ve geri dönüşüyle ilgili başka bir güvenlik açığına bir göz atalım. Çağırma ve döndürme, çalışan bir bağlamın (örneğin, bir işlev) diğerini çağırmasına ve çağrılan yürütmeyi tamamladıktan sonra çağıran bağlamın yürütülmesini sürdürmesine izin veren temel VM yönergeleridir. Her çağrı daha sonra bir geri dönüş bekler. Çağırma ve geri dönüş yaşam döngüsü boyunca zkWasm tarafından izlenen dinamik veriler "çağrı çerçevesi" olarak bilinir. zkWasm talimatları sırayla yürüttüğünden, tüm çağrı çerçeveleri çalışma zamanı sırasında oluşumlarına göre sıralanabilir. Aşağıda, zkWasm üzerinde çalışan bir çağırma/dönüş kodu örneği verilmiştir.

Kullanıcılar, jeton satın almak için buy_token() işlevini çağırabilir (muhtemelen diğer değerli öğelerin ödenmesi veya aktarılması yoluyla). Temel adımlarından biri, add_token() işlevini çağırarak token hesap bakiyesini 1 artırmaktır. ZK kanıtlayıcının kendisi çağrı çerçevesi veri yapısını desteklemediğinden, bu çağrı çerçevelerinin tam geçmişini kaydetmek ve izlemek için Yürütme Tablosu (E-Tablosu) ve Atlama Tablosu (J-Tablosu) gereklidir.

Yukarıdaki şekil, buy_token()'nin add_token()'yi çağırma ve add_token()'den buy_token()'ye dönme sürecini göstermektedir. Token hesap bakiyesinin 1 arttığı görülebilir. Yürütme Tablosunda, yürütülmekte olan geçerli çağrı çerçevesi numarası, geçerli bağlam işlevi adı (yalnızca gösterim amacıyla), işlev içindeki geçerli çalışan talimatın numarası ve tabloda depolanan geçerli talimat (yalnızca gösterim amaçlı) dahil olmak üzere her yürütme adımı bir satır kaplar. Atlama Tablosu'nda, her çağrı çerçevesi bir satır kaplar ve çağıran çerçevenin numarasını, çağıran işlev bağlam adını (yalnızca gösterim amacıyla) ve çağıran çerçevenin bir sonraki yönerge konumunu (çerçevenin geri dönebilmesi için) depolar. Her iki tabloda da, geçerli talimatın bir çağrı/dönüş olup olmadığını (Yürütme Tablosunda) ve bu çerçeve için toplam çağrı/dönüş talimatı sayısını (Atlama Tablosunda) izleyen bir "jops" sütunu vardır.

Beklendiği gibi, her çağrının karşılık gelen bir dönüşü olmalıdır ve her karenin yalnızca bir çağrısı ve bir dönüşü olmalıdır. Yukarıdaki şekilde gösterildiği gibi, Atlama Tablosu'ndaki ilk karenin "jops" değeri 2'dir ve Yürütme Tablosu'ndaki birinci ve üçüncü satırlara karşılık gelir ve burada "jops" değeri 1'dir. Şu anda her şey normal görünüyor.

Ancak burada bir sorun var: Bir çağrı ve bir dönüş, çerçeve için "jops" sayısını 2'ye çıkarırken, iki çağrı veya iki dönüş de 2 sayısıyla sonuçlanacaktır. Kare başına iki arama veya iki geri dönüş yapmak saçma görünebilir, ancak bir bilgisayar korsanının beklentileri kırarak yapmaya çalışacağı şeyin tam olarak bu olduğunu hatırlamak önemlidir.

Şu anda heyecanlı hissediyor olabilirsiniz, ancak sorunu gerçekten bulduk mu?

Yürütme Tablosu ve Atlama Tablosu'nun kısıtlamaları iki çağrının bir çerçevenin aynı satırına kodlanmasını engellediğinden, her çağrı yeni bir çerçeve numarası, yani geçerli çağrı çerçeve numarası artı 1 oluşturduğundan, iki çağrının bir sorun olmadığı ortaya çıktı.

Bununla birlikte, durum iki geri dönüş için o kadar şanslı değildir: dönüşte yeni bir çerçeve oluşturulmadığından, bir bilgisayar korsanı gerçekten de meşru bir yürütme dizisinin Yürütme Tablosunu ve Atlama Tablosunu elde edebilir ve sahte dönüşleri (ve karşılık gelen çerçeveleri) enjekte edebilir. Örneğin, buy_token() öğesinin add_token() öğesini çağırdığı önceki Yürütme Tablosu ve Atlama Tablosu örneği, bir bilgisayar korsanı tarafından aşağıdaki senaryoya göre değiştirilebilir:

Bilgisayar korsanı, Yürütme Tablosundaki orijinal çağrı ve dönüş arasına iki sahte dönüş enjekte etti ve Atlama Tablosuna yeni bir sahte çerçeve satırı ekledi (Yürütme Tablosundaki orijinal dönüş ve sonraki talimat yürütme adımlarının 4 artırılması gerekir). Atlama Tablosundaki her satır için "jops" sayısı 2 olduğundan, kısıtlamalar karşılanır ve zkWasm kanıt denetleyicisi bu sahte yürütme dizisinin "kanıtını" kabul eder. Şekilden de görüldüğü gibi token hesap bakiyesi 1 yerine 3 kat artmaktadır. Bu nedenle, bilgisayar korsanı 1 fiyatına 3 jeton alabilir.

Bu sorunu çözmenin çeşitli yolları vardır. Açık bir yaklaşım, çağrıları ve geri dönüşleri ayrı ayrı izlemek ve her karenin tam olarak bir çağrı ve bir geri dönüşe sahip olmasını sağlamaktır.

Şimdiye kadar bu güvenlik açığı için tek bir kod satırı göstermediğimizi fark etmiş olabilirsiniz. Bunun birincil nedeni, sorunlu bir kod satırının olmamasıdır; Kod uygulaması, tablo ve kısıtlama tasarımlarıyla mükemmel bir şekilde uyumludur. Sorun tasarımın kendisinde yatıyor ve düzeltme de öyle.

Bu güvenlik açığının açık olması gerektiğini düşünebilirsiniz, ancak gerçekte öyle değil. Bunun nedeni, "iki çağrı veya iki geri dönüş de 2'lik bir 'jops' sayısıyla sonuçlanacaktır" ile "iki dönüş aslında mümkündür" arasında bir boşluk olmasıdır. İkincisi, Yürütme Tablosu ve Atlama Tablosundaki çeşitli kısıtlamaların ayrıntılı ve kapsamlı bir analizini gerektirir ve bu da tam gayri resmi akıl yürütmeyi zorlaştırır.

İki Güvenlik Açığının Karşılaştırılması

"Load8 Veri Enjeksiyon Güvenlik Açığı" ve "Sahtecilik İade Güvenlik Açığı", bilgisayar korsanlarının ZK kanıtlarını manipüle etmesine, yanlış işlemler oluşturmasına, kanıt denetleyicilerini aldatmasına ve hırsızlık veya ele geçirme eylemlerinde bulunmasına izin verme potansiyeline sahiptir. Ancak, doğaları ve keşfedilme biçimleri oldukça farklıdır.

"Load8 Veri Enjeksiyon Güvenlik Açığı", zkWasm'ın denetimi sırasında keşfedildi. 6.000'den fazla Rust kodunda ve düzinelerce zkWasm talimatında yüzlerce kısıtlamayı gözden geçirmemiz gerektiğinden, bu kolay bir iş değildi. Buna rağmen, güvenlik açığının tespit edilmesi ve onaylanması nispeten kolaydı. Bu güvenlik açığı resmi doğrulama başlamadan önce giderildiği için doğrulama işlemi sırasında karşılaşılmadı. Bu güvenlik açığı denetim sırasında keşfedilmemiş olsaydı, Load8 komutunun doğrulanması sırasında bulunmasını bekleyebilirdik.

"Sahtecilik İade Güvenlik Açığı", denetimden sonra resmi doğrulama sırasında keşfedildi. Denetim sırasında bunu keşfedemememizin bir nedeni, zkWasm'ın, zkWasm çalışma zamanı sırasında her bellek birimi için geçmiş verilere karşılık gelen bellek erişim talimatlarını izleyen "mops" adı verilen "jops" a benzer bir mekanizmaya sahip olmasıdır. Paspas sayımlarındaki kısıtlamalar gerçekten doğrudur çünkü yalnızca bir tür bellek talimatını, bellek yazmalarını izler ve her bellek biriminin geçmiş verileri değişmezdir ve yalnızca bir kez yazılır (paspas sayısı 1'dir). Ancak denetim sırasında bu potansiyel güvenlik açığını fark etmiş olsak bile, aslında yanlış olan hiçbir kod satırı olmadığından, ilgili tüm kısıtlamalar üzerinde titiz bir resmi akıl yürütme olmadan olası her senaryoyu kolayca doğrulayamaz veya ekarte edemezdik.

Özetle, bu iki güvenlik açığı sırasıyla "kod güvenlik açıkları" ve "tasarım güvenlik açıkları" kategorilerine aittir. Kod güvenlik açıkları nispeten basittir, keşfedilmesi daha kolaydır (hatalı kod) ve akıl yürütmesi ve onaylaması daha kolaydır. Tasarım güvenlik açıkları çok ince olabilir, keşfedilmesi daha zor ("hatalı" kod yok) ve akıl yürütmesi ve onaylaması daha zor olabilir.

ZK Güvenlik Açıklarını Keşfetmek için En İyi Uygulamalar

zkVM'yi ve diğer ZK ve ZK olmayan zincirleri denetleme ve resmi olarak doğrulama deneyimimize dayanarak, ZK sistemlerinin en iyi şekilde nasıl korunacağına dair bazı öneriler şunlardır:

Kodu ve tasarımı kontrol etme

Daha önce de belirtildiği gibi, ZK'nın hem kodu hem de tasarımı güvenlik açıkları içerebilir. Her iki güvenlik açığı türü de ZK sisteminin bütünlüğünü potansiyel olarak tehlikeye atabilir, bu nedenle sistem devreye alınmadan önce ele alınmaları gerekir. ZK sistemleriyle ilgili bir sorun, ZK olmayan sistemlerle karşılaştırıldığında, herhangi bir saldırının tespit edilmesinin ve analiz edilmesinin daha zor olmasıdır, çünkü hesaplama ayrıntıları halka açık değildir veya zincirde tutulmaz. Sonuç olarak, insanlar bir hacker saldırısının gerçekleştiğinin farkında olabilirler, ancak bunun nasıl gerçekleştiğine dair teknik ayrıntıları bilmiyor olabilirler. Bu, herhangi bir ZK güvenlik açığının maliyetini çok yüksek hale getirir. Sonuç olarak, ZK sistemlerinin güvenliğini önceden sağlamanın değeri de çok yüksektir.

Denetimler ve resmi doğrulama gerçekleştirin

Burada tartıştığımız iki güvenlik açığı, denetim ve resmi doğrulama yoluyla keşfedildi. Bazıları, tüm güvenlik açıkları resmi doğrulama yoluyla tespit edileceğinden, resmi doğrulamanın tek başına denetim ihtiyacını ortadan kaldırdığını varsayabilir. Ancak bizim önerimiz her ikisini de gerçekleştirmenizdir. Bu makalenin başında açıklandığı gibi, yüksek kaliteli resmi doğrulama çalışması, denetimle örtüşen kod ve tasarım hakkında kapsamlı bir inceleme, inceleme ve gayri resmi akıl yürütme ile başlar. Ek olarak, denetim sırasında daha basit güvenlik açıklarının bulunması ve çözülmesi, resmi doğrulama sürecini basitleştirebilir ve kolaylaştırabilir.

Bir ZK sistemi için hem denetim hem de resmi doğrulama yapıyorsanız, en uygun yaklaşım her ikisini de aynı anda gerçekleştirmektir. Bu, denetçilerin ve resmi doğrulama mühendislerinin verimli bir şekilde işbirliği yapmasına olanak tanır ve resmi doğrulama için yüksek kaliteli denetim girdileri gerektiğinden potansiyel olarak daha fazla güvenlik açığı keşfeder.

ZK projeniz zaten denetimden (övgüler) veya birden fazla denetimden (büyük övgüler) geçtiyse, önerimiz önceki denetim sonuçlarına dayanarak devre üzerinde resmi doğrulama yapmaktır. Hem ZK hem de ZK olmayan zkVM ve diğerleri gibi projelerde denetim ve resmi doğrulama konusundaki deneyimimiz, resmi doğrulamanın genellikle denetim sırasında gözden kaçan güvenlik açıklarını yakaladığını defalarca göstermiştir. ZKP'nin doğası göz önüne alındığında, ZK sistemlerinin ZK olmayan çözümlerden daha iyi blok zinciri güvenliği ve ölçeklenebilirliği sunması gerekirken, güvenliklerinin ve doğruluklarının kritikliği, geleneksel ZK olmayan sistemlerden çok daha yüksektir. Bu nedenle, ZK sistemleri için yüksek kaliteli resmi doğrulamanın değeri, ZK olmayan sistemlerinkinden çok daha fazladır.

Devrelerin ve akıllı sözleşmelerin güvenliğini sağlayın

ZK uygulamaları tipik olarak iki bileşenden oluşur: devreler ve akıllı sözleşmeler. zkVM tabanlı uygulamalar için evrensel zkVM devreleri ve akıllı sözleşme uygulamaları vardır. zkVM'ye dayalı olmayan uygulamalar için, L1 zincirinde veya bir köprünün diğer ucunda konuşlandırılan ilgili akıllı sözleşmelerle birlikte uygulamaya özel ZK devreleri vardır.

zkWasm için denetim ve resmi doğrulama çabalarımız yalnızca zkWasm devresini içerir. Bununla birlikte, ZK uygulamaları için genel güvenlik açısından bakıldığında, akıllı sözleşmelerini de denetlemek ve resmi olarak doğrulamak çok önemlidir. Ne de olsa, devre güvenliğini sağlamak için önemli bir çaba harcadıktan sonra, akıllı sözleşme incelemesindeki gevşekliğin uygulamanın tehlikeye girmesine yol açması üzücü olacaktır.

İki tür akıllı sözleşme özellikle dikkat edilmeyi hak ediyor. İlk tip doğrudan ZK kanıtlarını ele alır. Ölçek olarak büyük olmasalar da, riskleri son derece yüksektir. İkinci tür, zkVM'nin üzerinde çalışan orta ila büyük ölçekli akıllı sözleşmeleri içerir. Bu sözleşmelerin bazen oldukça karmaşık olabileceğini ve özellikle yürütme ayrıntıları zincir üzerinde görünmediği için en değerli sözleşmelerin denetim ve doğrulamadan geçmesi gerektiğini biliyoruz. Neyse ki, yıllar süren geliştirmeden sonra, akıllı sözleşmeler için resmi doğrulama artık pratik ve uygun yüksek değerli hedefler için hazırlandı.

Resmi doğrulamanın (FV) ZK sistemleri ve bileşenleri üzerindeki etkisini aşağıdaki noktalarla özetleyelim.

Beyanat:

  1. Bu makale [panewslab]'dan alınmıştır, telif hakkı orijinal yazara [CertiK] aittir, yeniden baskıya herhangi bir itirazınız varsa, lütfen Gate Learn ekibiyle iletişime geçin ve ekip bunu ilgili prosedürlere göre mümkün olan en kısa sürede halledecektir.

  2. Yasal Uyarı: Bu makalede ifade edilen görüş ve görüşler yalnızca yazarın kişisel görüşlerini temsil eder ve herhangi bir yatırım tavsiyesi teşkil etmez.

  3. Makalenin diğer dillerdeki versiyonları Gate Learn ekibi tarafından çevrilir ve Gate.io'da bahsedilmez, çevrilen makale çoğaltılamaz, dağıtılamaz veya intihal edilemez.

İki ZK Güvenlik Açığının Derinlemesine Analizi

Orta SeviyeJun 05, 2024
Bu makale, Sıfır Bilgi Kanıtı (ZKP) sistemlerindeki iki olası güvenlik açığının derinlemesine bir analizini sağlar: "Load8 Veri Ekleme Saldırısı" ve "Sahtecilik İade Saldırısı". Makale, bu güvenlik açıklarının teknik özelliklerini, bunlardan nasıl yararlanılabileceğini ve bunları düzeltme yöntemlerini detaylandırıyor. Ek olarak, ZK sistemlerinin denetim ve resmi doğrulama süreçleri sırasında bu güvenlik açıklarının keşfedilmesinden öğrenilen dersleri tartışır ve ZK sistemlerinin güvenliğini sağlamak için en iyi uygulamaları önerir.
İki ZK Güvenlik Açığının Derinlemesine Analizi

Önceki bir makalede, Sıfır Bilgi Kanıtı (ZKP) sistemlerinin gelişmiş resmi doğrulamasını tartıştık: bir ZK talimatının nasıl doğrulanacağı. Her zkWasm komutunu resmi olarak doğrulayarak, tüm zkWasm devresinin teknik güvenliğini ve doğruluğunu tam olarak sağlayabiliriz. Bu makalede, güvenlik açığı keşfi perspektifine, denetim ve doğrulama süreçlerinde tespit edilen belirli güvenlik açıklarının analizine ve bunlardan çıkarılan derslere odaklanacağız. ZKP blok zincirlerinin gelişmiş resmi doğrulaması hakkında genel bir tartışma için lütfen ZKP blok zincirlerinin gelişmiş resmi doğrulaması hakkındaki makaleye bakın.

ZK güvenlik açıklarından bahsetmeden önce, CertiK'in ZK resmi doğrulamasını nasıl gerçekleştirdiğini anlayalım. ZK Sanal Makinesi (zkVM) gibi karmaşık sistemler için, resmi doğrulamanın (FV) ilk adımı, neyin doğrulanması gerektiğini ve özelliklerini açıkça tanımlamaktır. Bu, ZK sisteminin tasarımının, kod uygulamasının ve test kurulumunun kapsamlı bir şekilde gözden geçirilmesini gerektirir. Bu süreç, düzenli denetimlerle örtüşür, ancak incelemeden sonra doğrulama hedeflerinin ve özelliklerinin belirlenmesi gerektiği için farklılık gösterir. CertiK'te buna denetim odaklı doğrulama diyoruz. Denetim ve doğrulama çalışmaları genellikle entegre edilmiştir. zkWasm için hem denetim hem de resmi doğrulamayı aynı anda gerçekleştirdik.

ZK Güvenlik Açığı Nedir?

Sıfır Bilgi Kanıtı (ZKP) sistemlerinin temel özelliği, çevrimdışı veya özel olarak yürütülen hesaplamaların (blok zinciri işlemleri gibi) kısa bir şifreli kanıtının bir ZKP doğrulayıcısına aktarılmasına izin vermesidir. Doğrulayıcı, hesaplamanın iddia edildiği gibi gerçekleştiğinden emin olmak için kanıtı kontrol eder ve onaylar. Bu bağlamda, bir ZK güvenlik açığı, bir bilgisayar korsanının yanlış işlemler için sahte ZK kanıtları göndermesine ve bunları ZKP doğrulayıcısı tarafından kabul etmesine olanak tanır.

Bir zkVM kanıtlayıcı için, ZK kanıt süreci bir program çalıştırmayı, her adım için yürütme kayıtları oluşturmayı ve bu yürütme kayıtlarını bir dizi sayısal tabloya dönüştürmeyi ("aritmetikleştirme" olarak bilinen bir süreç) içerir. Bu sayılar, belirli tablo hücreleri, sabit sabitler, tablolar arasındaki veritabanı arama kısıtlamaları ve her bir bitişik tablo satırı çiftinin karşılaması gereken polinom denklemleri (veya "geçitler") arasındaki ilişkileri içeren bir dizi kısıtlamayı ("devre") karşılamalıdır. Zincir içi doğrulama, tablo içindeki belirli sayıları açıklamadan tüm kısıtlamaları karşılayan bir tablonun varlığını doğrulayabilir.


zkWasm'de Aritmetizasyon Tablosu

Her kısıtlamanın doğruluğu çok önemlidir. Bir kısıtlamadaki herhangi bir hata, ister çok zayıf ister eksik olsun, bir bilgisayar korsanının yanıltıcı kanıtlar sunmasına izin verebilir. Bu tablolar bir akıllı sözleşmenin geçerli bir şekilde yürütülmesini temsil ediyor gibi görünebilir, ancak gerçekte değildir. Geleneksel VM'lerle karşılaştırıldığında, zkVM işlemlerinin opaklığı bu güvenlik açıklarını güçlendirir. ZK olmayan zincirlerde, işlem hesaplamalarının ayrıntıları blok zincirine herkese açık olarak kaydedilir; ancak zkVM'ler bu ayrıntıları zincir üzerinde depolamaz. Bu şeffaflık eksikliği, bir saldırının ayrıntılarını veya bir saldırının gerçekleşip gerçekleşmediğini belirlemeyi zorlaştırır.

zkVM komutlarının yürütme kurallarını uygulayan ZK devresi son derece karmaşıktır. zkWasm için, ZK devresinin uygulanması 6.000'den fazla Rust kodu satırı ve yüzlerce kısıtlama içerir. Bu karmaşıklık genellikle keşfedilmeyi bekleyen birden çok güvenlik açığı olabileceği anlamına gelir.


zkWasm Devre Mimarisi

Gerçekten de, zkWasm'ın denetlenmesi ve resmi olarak doğrulanması yoluyla, bu tür birkaç güvenlik açığı keşfettik. Aşağıda, iki temsili örneği tartışacağız ve aralarındaki farkları inceleyeceğiz.

Kod Güvenlik Açığı: Load8 Veri Enjeksiyon Saldırısı

İlk güvenlik açığı, zkWasm'daki Load8 komutunu içerir. zkWasm'da, yığın belleği okumaları, N'nin yüklenecek verilerin boyutu olduğu bir dizi LoadN talimatı kullanılarak gerçekleştirilir. Örneğin, Load64 bir zkWasm bellek adresinden 64 bit veri okumalıdır. Load8, bellekten 8 bitlik verileri (yani bir bayt) okumalı ve 64 bitlik bir değer oluşturmak için sıfırlarla doldurmalıdır. Dahili olarak, zkWasm belleği 64 bitlik bir bayt dizisi olarak temsil eder, bu nedenle bellek dizisinin bir bölümünü "seçmesi" gerekir. Bu, birlikte tam 64 bit yük değerini oluşturan dört ara değişken (u16_cells) kullanılarak yapılır.

Bu LoadN komutlarının kısıtlamaları aşağıdaki gibi tanımlanır:

Bu kısıtlama üç duruma ayrılır: Load32, Load16 ve Load8. Load64'ün herhangi bir kısıtlaması yoktur çünkü bellek birimleri tam olarak 64 bittir. Load32 durumu için kod, bellek birimindeki yüksek 4 baytın (32 bit) sıfır olmasını sağlar.

Load16 durumu için kod, bellek birimindeki yüksek 6 baytın (48 bit) sıfır olmasını sağlar.

Load8 durumu için, bellek birimindeki yüksek 7 baytın (56 bit) sıfır olmasını gerektirmelidir. Ne yazık ki, kodda durum böyle değil.

Gördüğünüz gibi, yalnızca yüksek 9 ila 16 bit sıfırla sınırlıdır. Diğer yüksek 48 bit herhangi bir değer olabilir ve yine de "bellekten okuma" olarak geçebilir.

Bu güvenlik açığından yararlanan bir bilgisayar korsanı, meşru bir yürütme dizisinin ZK kanıtını kurcalayarak Load8 komutunun bu beklenmeyen baytları yüklemesine neden olarak veri bozulmasına neden olabilir. Ayrıca, çevredeki kod ve verilerin dikkatli bir şekilde düzenlenmesi yoluyla, yanlış yürütmeleri ve aktarımları tetikleyerek veri ve varlık hırsızlığına yol açabilir. Bu sahte işlemler, zkWasm denetleyicilerinin kontrollerini geçebilir ve blok zinciri tarafından yanlış bir şekilde meşru işlemler olarak tanınabilir.

Bu güvenlik açığını düzeltmek aslında oldukça basittir.

Bu güvenlik açığı, kodun uygulanmasından kaynaklandıkları ve küçük yerel kod değişiklikleriyle kolayca düzeltilebildikleri için "kod güvenlik açıkları" olarak adlandırılan bir ZK güvenlik açığı sınıfını temsil eder. Kabul edebileceğiniz gibi, bu güvenlik açıklarını insanların tanımlaması da nispeten daha kolaydır.

Tasarım Güvenlik Açığı: Sahte İade Saldırısı

Bu sefer zkWasm'ın çağrılması ve geri dönüşüyle ilgili başka bir güvenlik açığına bir göz atalım. Çağırma ve döndürme, çalışan bir bağlamın (örneğin, bir işlev) diğerini çağırmasına ve çağrılan yürütmeyi tamamladıktan sonra çağıran bağlamın yürütülmesini sürdürmesine izin veren temel VM yönergeleridir. Her çağrı daha sonra bir geri dönüş bekler. Çağırma ve geri dönüş yaşam döngüsü boyunca zkWasm tarafından izlenen dinamik veriler "çağrı çerçevesi" olarak bilinir. zkWasm talimatları sırayla yürüttüğünden, tüm çağrı çerçeveleri çalışma zamanı sırasında oluşumlarına göre sıralanabilir. Aşağıda, zkWasm üzerinde çalışan bir çağırma/dönüş kodu örneği verilmiştir.

Kullanıcılar, jeton satın almak için buy_token() işlevini çağırabilir (muhtemelen diğer değerli öğelerin ödenmesi veya aktarılması yoluyla). Temel adımlarından biri, add_token() işlevini çağırarak token hesap bakiyesini 1 artırmaktır. ZK kanıtlayıcının kendisi çağrı çerçevesi veri yapısını desteklemediğinden, bu çağrı çerçevelerinin tam geçmişini kaydetmek ve izlemek için Yürütme Tablosu (E-Tablosu) ve Atlama Tablosu (J-Tablosu) gereklidir.

Yukarıdaki şekil, buy_token()'nin add_token()'yi çağırma ve add_token()'den buy_token()'ye dönme sürecini göstermektedir. Token hesap bakiyesinin 1 arttığı görülebilir. Yürütme Tablosunda, yürütülmekte olan geçerli çağrı çerçevesi numarası, geçerli bağlam işlevi adı (yalnızca gösterim amacıyla), işlev içindeki geçerli çalışan talimatın numarası ve tabloda depolanan geçerli talimat (yalnızca gösterim amaçlı) dahil olmak üzere her yürütme adımı bir satır kaplar. Atlama Tablosu'nda, her çağrı çerçevesi bir satır kaplar ve çağıran çerçevenin numarasını, çağıran işlev bağlam adını (yalnızca gösterim amacıyla) ve çağıran çerçevenin bir sonraki yönerge konumunu (çerçevenin geri dönebilmesi için) depolar. Her iki tabloda da, geçerli talimatın bir çağrı/dönüş olup olmadığını (Yürütme Tablosunda) ve bu çerçeve için toplam çağrı/dönüş talimatı sayısını (Atlama Tablosunda) izleyen bir "jops" sütunu vardır.

Beklendiği gibi, her çağrının karşılık gelen bir dönüşü olmalıdır ve her karenin yalnızca bir çağrısı ve bir dönüşü olmalıdır. Yukarıdaki şekilde gösterildiği gibi, Atlama Tablosu'ndaki ilk karenin "jops" değeri 2'dir ve Yürütme Tablosu'ndaki birinci ve üçüncü satırlara karşılık gelir ve burada "jops" değeri 1'dir. Şu anda her şey normal görünüyor.

Ancak burada bir sorun var: Bir çağrı ve bir dönüş, çerçeve için "jops" sayısını 2'ye çıkarırken, iki çağrı veya iki dönüş de 2 sayısıyla sonuçlanacaktır. Kare başına iki arama veya iki geri dönüş yapmak saçma görünebilir, ancak bir bilgisayar korsanının beklentileri kırarak yapmaya çalışacağı şeyin tam olarak bu olduğunu hatırlamak önemlidir.

Şu anda heyecanlı hissediyor olabilirsiniz, ancak sorunu gerçekten bulduk mu?

Yürütme Tablosu ve Atlama Tablosu'nun kısıtlamaları iki çağrının bir çerçevenin aynı satırına kodlanmasını engellediğinden, her çağrı yeni bir çerçeve numarası, yani geçerli çağrı çerçeve numarası artı 1 oluşturduğundan, iki çağrının bir sorun olmadığı ortaya çıktı.

Bununla birlikte, durum iki geri dönüş için o kadar şanslı değildir: dönüşte yeni bir çerçeve oluşturulmadığından, bir bilgisayar korsanı gerçekten de meşru bir yürütme dizisinin Yürütme Tablosunu ve Atlama Tablosunu elde edebilir ve sahte dönüşleri (ve karşılık gelen çerçeveleri) enjekte edebilir. Örneğin, buy_token() öğesinin add_token() öğesini çağırdığı önceki Yürütme Tablosu ve Atlama Tablosu örneği, bir bilgisayar korsanı tarafından aşağıdaki senaryoya göre değiştirilebilir:

Bilgisayar korsanı, Yürütme Tablosundaki orijinal çağrı ve dönüş arasına iki sahte dönüş enjekte etti ve Atlama Tablosuna yeni bir sahte çerçeve satırı ekledi (Yürütme Tablosundaki orijinal dönüş ve sonraki talimat yürütme adımlarının 4 artırılması gerekir). Atlama Tablosundaki her satır için "jops" sayısı 2 olduğundan, kısıtlamalar karşılanır ve zkWasm kanıt denetleyicisi bu sahte yürütme dizisinin "kanıtını" kabul eder. Şekilden de görüldüğü gibi token hesap bakiyesi 1 yerine 3 kat artmaktadır. Bu nedenle, bilgisayar korsanı 1 fiyatına 3 jeton alabilir.

Bu sorunu çözmenin çeşitli yolları vardır. Açık bir yaklaşım, çağrıları ve geri dönüşleri ayrı ayrı izlemek ve her karenin tam olarak bir çağrı ve bir geri dönüşe sahip olmasını sağlamaktır.

Şimdiye kadar bu güvenlik açığı için tek bir kod satırı göstermediğimizi fark etmiş olabilirsiniz. Bunun birincil nedeni, sorunlu bir kod satırının olmamasıdır; Kod uygulaması, tablo ve kısıtlama tasarımlarıyla mükemmel bir şekilde uyumludur. Sorun tasarımın kendisinde yatıyor ve düzeltme de öyle.

Bu güvenlik açığının açık olması gerektiğini düşünebilirsiniz, ancak gerçekte öyle değil. Bunun nedeni, "iki çağrı veya iki geri dönüş de 2'lik bir 'jops' sayısıyla sonuçlanacaktır" ile "iki dönüş aslında mümkündür" arasında bir boşluk olmasıdır. İkincisi, Yürütme Tablosu ve Atlama Tablosundaki çeşitli kısıtlamaların ayrıntılı ve kapsamlı bir analizini gerektirir ve bu da tam gayri resmi akıl yürütmeyi zorlaştırır.

İki Güvenlik Açığının Karşılaştırılması

"Load8 Veri Enjeksiyon Güvenlik Açığı" ve "Sahtecilik İade Güvenlik Açığı", bilgisayar korsanlarının ZK kanıtlarını manipüle etmesine, yanlış işlemler oluşturmasına, kanıt denetleyicilerini aldatmasına ve hırsızlık veya ele geçirme eylemlerinde bulunmasına izin verme potansiyeline sahiptir. Ancak, doğaları ve keşfedilme biçimleri oldukça farklıdır.

"Load8 Veri Enjeksiyon Güvenlik Açığı", zkWasm'ın denetimi sırasında keşfedildi. 6.000'den fazla Rust kodunda ve düzinelerce zkWasm talimatında yüzlerce kısıtlamayı gözden geçirmemiz gerektiğinden, bu kolay bir iş değildi. Buna rağmen, güvenlik açığının tespit edilmesi ve onaylanması nispeten kolaydı. Bu güvenlik açığı resmi doğrulama başlamadan önce giderildiği için doğrulama işlemi sırasında karşılaşılmadı. Bu güvenlik açığı denetim sırasında keşfedilmemiş olsaydı, Load8 komutunun doğrulanması sırasında bulunmasını bekleyebilirdik.

"Sahtecilik İade Güvenlik Açığı", denetimden sonra resmi doğrulama sırasında keşfedildi. Denetim sırasında bunu keşfedemememizin bir nedeni, zkWasm'ın, zkWasm çalışma zamanı sırasında her bellek birimi için geçmiş verilere karşılık gelen bellek erişim talimatlarını izleyen "mops" adı verilen "jops" a benzer bir mekanizmaya sahip olmasıdır. Paspas sayımlarındaki kısıtlamalar gerçekten doğrudur çünkü yalnızca bir tür bellek talimatını, bellek yazmalarını izler ve her bellek biriminin geçmiş verileri değişmezdir ve yalnızca bir kez yazılır (paspas sayısı 1'dir). Ancak denetim sırasında bu potansiyel güvenlik açığını fark etmiş olsak bile, aslında yanlış olan hiçbir kod satırı olmadığından, ilgili tüm kısıtlamalar üzerinde titiz bir resmi akıl yürütme olmadan olası her senaryoyu kolayca doğrulayamaz veya ekarte edemezdik.

Özetle, bu iki güvenlik açığı sırasıyla "kod güvenlik açıkları" ve "tasarım güvenlik açıkları" kategorilerine aittir. Kod güvenlik açıkları nispeten basittir, keşfedilmesi daha kolaydır (hatalı kod) ve akıl yürütmesi ve onaylaması daha kolaydır. Tasarım güvenlik açıkları çok ince olabilir, keşfedilmesi daha zor ("hatalı" kod yok) ve akıl yürütmesi ve onaylaması daha zor olabilir.

ZK Güvenlik Açıklarını Keşfetmek için En İyi Uygulamalar

zkVM'yi ve diğer ZK ve ZK olmayan zincirleri denetleme ve resmi olarak doğrulama deneyimimize dayanarak, ZK sistemlerinin en iyi şekilde nasıl korunacağına dair bazı öneriler şunlardır:

Kodu ve tasarımı kontrol etme

Daha önce de belirtildiği gibi, ZK'nın hem kodu hem de tasarımı güvenlik açıkları içerebilir. Her iki güvenlik açığı türü de ZK sisteminin bütünlüğünü potansiyel olarak tehlikeye atabilir, bu nedenle sistem devreye alınmadan önce ele alınmaları gerekir. ZK sistemleriyle ilgili bir sorun, ZK olmayan sistemlerle karşılaştırıldığında, herhangi bir saldırının tespit edilmesinin ve analiz edilmesinin daha zor olmasıdır, çünkü hesaplama ayrıntıları halka açık değildir veya zincirde tutulmaz. Sonuç olarak, insanlar bir hacker saldırısının gerçekleştiğinin farkında olabilirler, ancak bunun nasıl gerçekleştiğine dair teknik ayrıntıları bilmiyor olabilirler. Bu, herhangi bir ZK güvenlik açığının maliyetini çok yüksek hale getirir. Sonuç olarak, ZK sistemlerinin güvenliğini önceden sağlamanın değeri de çok yüksektir.

Denetimler ve resmi doğrulama gerçekleştirin

Burada tartıştığımız iki güvenlik açığı, denetim ve resmi doğrulama yoluyla keşfedildi. Bazıları, tüm güvenlik açıkları resmi doğrulama yoluyla tespit edileceğinden, resmi doğrulamanın tek başına denetim ihtiyacını ortadan kaldırdığını varsayabilir. Ancak bizim önerimiz her ikisini de gerçekleştirmenizdir. Bu makalenin başında açıklandığı gibi, yüksek kaliteli resmi doğrulama çalışması, denetimle örtüşen kod ve tasarım hakkında kapsamlı bir inceleme, inceleme ve gayri resmi akıl yürütme ile başlar. Ek olarak, denetim sırasında daha basit güvenlik açıklarının bulunması ve çözülmesi, resmi doğrulama sürecini basitleştirebilir ve kolaylaştırabilir.

Bir ZK sistemi için hem denetim hem de resmi doğrulama yapıyorsanız, en uygun yaklaşım her ikisini de aynı anda gerçekleştirmektir. Bu, denetçilerin ve resmi doğrulama mühendislerinin verimli bir şekilde işbirliği yapmasına olanak tanır ve resmi doğrulama için yüksek kaliteli denetim girdileri gerektiğinden potansiyel olarak daha fazla güvenlik açığı keşfeder.

ZK projeniz zaten denetimden (övgüler) veya birden fazla denetimden (büyük övgüler) geçtiyse, önerimiz önceki denetim sonuçlarına dayanarak devre üzerinde resmi doğrulama yapmaktır. Hem ZK hem de ZK olmayan zkVM ve diğerleri gibi projelerde denetim ve resmi doğrulama konusundaki deneyimimiz, resmi doğrulamanın genellikle denetim sırasında gözden kaçan güvenlik açıklarını yakaladığını defalarca göstermiştir. ZKP'nin doğası göz önüne alındığında, ZK sistemlerinin ZK olmayan çözümlerden daha iyi blok zinciri güvenliği ve ölçeklenebilirliği sunması gerekirken, güvenliklerinin ve doğruluklarının kritikliği, geleneksel ZK olmayan sistemlerden çok daha yüksektir. Bu nedenle, ZK sistemleri için yüksek kaliteli resmi doğrulamanın değeri, ZK olmayan sistemlerinkinden çok daha fazladır.

Devrelerin ve akıllı sözleşmelerin güvenliğini sağlayın

ZK uygulamaları tipik olarak iki bileşenden oluşur: devreler ve akıllı sözleşmeler. zkVM tabanlı uygulamalar için evrensel zkVM devreleri ve akıllı sözleşme uygulamaları vardır. zkVM'ye dayalı olmayan uygulamalar için, L1 zincirinde veya bir köprünün diğer ucunda konuşlandırılan ilgili akıllı sözleşmelerle birlikte uygulamaya özel ZK devreleri vardır.

zkWasm için denetim ve resmi doğrulama çabalarımız yalnızca zkWasm devresini içerir. Bununla birlikte, ZK uygulamaları için genel güvenlik açısından bakıldığında, akıllı sözleşmelerini de denetlemek ve resmi olarak doğrulamak çok önemlidir. Ne de olsa, devre güvenliğini sağlamak için önemli bir çaba harcadıktan sonra, akıllı sözleşme incelemesindeki gevşekliğin uygulamanın tehlikeye girmesine yol açması üzücü olacaktır.

İki tür akıllı sözleşme özellikle dikkat edilmeyi hak ediyor. İlk tip doğrudan ZK kanıtlarını ele alır. Ölçek olarak büyük olmasalar da, riskleri son derece yüksektir. İkinci tür, zkVM'nin üzerinde çalışan orta ila büyük ölçekli akıllı sözleşmeleri içerir. Bu sözleşmelerin bazen oldukça karmaşık olabileceğini ve özellikle yürütme ayrıntıları zincir üzerinde görünmediği için en değerli sözleşmelerin denetim ve doğrulamadan geçmesi gerektiğini biliyoruz. Neyse ki, yıllar süren geliştirmeden sonra, akıllı sözleşmeler için resmi doğrulama artık pratik ve uygun yüksek değerli hedefler için hazırlandı.

Resmi doğrulamanın (FV) ZK sistemleri ve bileşenleri üzerindeki etkisini aşağıdaki noktalarla özetleyelim.

Beyanat:

  1. Bu makale [panewslab]'dan alınmıştır, telif hakkı orijinal yazara [CertiK] aittir, yeniden baskıya herhangi bir itirazınız varsa, lütfen Gate Learn ekibiyle iletişime geçin ve ekip bunu ilgili prosedürlere göre mümkün olan en kısa sürede halledecektir.

  2. Yasal Uyarı: Bu makalede ifade edilen görüş ve görüşler yalnızca yazarın kişisel görüşlerini temsil eder ve herhangi bir yatırım tavsiyesi teşkil etmez.

  3. Makalenin diğer dillerdeki versiyonları Gate Learn ekibi tarafından çevrilir ve Gate.io'da bahsedilmez, çevrilen makale çoğaltılamaz, dağıtılamaz veya intihal edilemez.

Şimdi Başlayın
Kaydolun ve
100 USD
değerinde Kupon kazanın!