Back to Blog

EVM Uyumluluğunu ve Güvenliğini Korumaya Yönelik Sistematik Yaklaşım

Code Auditing
March 27, 2023
6 min read

EVM (Ethereum Sanal Makinesi) uyumlu blok zincirleri, Ethereum blok zincirinin akıllı sözleşme işlevselliği, programlama dili (Solidity) ve araç ekosistemiyle uyumlu olacak şekilde tasarlanmıştır. Bu süreçte, EVM uyumlu bir sanal makinenin uygulanması temel adımlardan biridir. Ancak araştırmalarımız sırasında, farklı uygulamalarda EVM uyumluluğunun sürdürülmesinin kolay olmadığını fark ettik.

Bu sorunu çözmek için BlockSec, EVM uygulaması içindeki hataları ve güvenlik açıklarını sistematik olarak tespit edebilen dahili bir sistem geliştirdi. Bu sistem oldukça etkili oldu. Aurora Engine'de dört hata ve Moonbeam'de dört hata tespit etti. Tüm hatalar raporlandı ve düzeltildi. Bu test metodolojisinin, geçen yıl Solana rbpf uygulamasındaki iki kritik güvenlik açığını (CVE-2021–46102, CVE-2022–23066) tespit etmek için de kullanıldığını belirtmek gerekir.

1. Arka Plan

Günümüzde düşük gaz ücreti, yüksek verim ve yüksek performans optimizasyonu ile birçok farklı blok zinciri önerilmektedir. Bu durumda yeni sanal makineler veya geliştirme dilleri önerilmekte, bu da orijinal Solidity geliştiricileri için dönüşüm engelini artırmaktadır. Bu bağlamda, kullanıcıların Solidity ile geliştirdikleri DApp'leri bu yeni zincirlere dağıtmalarına olanak tanıyan pek çok EVM uyumlu çözüm önerilmektedir. Aurora ve Moonbeam, bu EVM uyumlu çözümlerin temsilcileridir. Ancak bu EVM uygulamalarının sağlamlığı, güvenilirliği ve hassasiyeti bilinmemekte olup dikkatimizi hak etmektedir. Bu amaçla diferansiyel bulanıklaştırma tekniğini kullanarak uygulamalarda herhangi bir kusur bulunup bulunmadığını kontrol ediyoruz.

2. Diferansiyel Bulanıklaştırma

Temel fikir, aynı girdileri bu EVM uygulamalarına (ör. Aurora, Moonbeam) ve son teknoloji Ethereum istemcisine (yani geth) besleyerek aynı çıktıyı üretip üretmediklerini kontrol etmektir. Özellikle, Ethereum üzerindeki geçmiş işlemleri toplayarak sözleşme kodlarını ve işlem durumlarını farklı stratejilerle değiştirip test senaryoları oluşturuyoruz. Bulgularımız, Aurora Engine ve Moonbeam'in bazı durumlarda spesifikasyona uymadığını göstermektedir. Neyse ki raporlanan tüm sorunlar giderildi ve şimdi ayrıntıları paylaşacağız.

3. Bulunan Hatalar

Bu hataların büyük çoğunluğu önceden derlenmiş sözleşmelerde yer almaktadır ve kök nedenleri ile etkileri çeşitlilik göstermektedir. Örneğin, bazı hatalar nonce değerinin hesaplanmasını etkilerken diğerleri gaz hesaplamasını etkileyebilmekte ve DoS saldırısına yol açabilmektedir. Bulunan tüm hatalar, EVM spesifikasyonunun belirlenen yürütme mantığına aykırıdır ve belirli durumlarda beklenmedik davranışlara neden olabilir. Bulunan hatalar için ayrıntılı açıklamaları aşağıda bulabilirsiniz.

3.1 Hatalı Doğrulama

Kriptografik mantık karmaşıktır. Bu durumda, ilgili mantığı EVM bayt kodunda uygulamak oldukça yüksek gaz kullanımına neden olabilir. Bunun yerine, yerel kodla geliştirilen önceden derlenmiş sözleşmeler performansı artırabilir. Ancak önceden derlenmiş sözleşmelerde hatalı doğrulamadan kaynaklanan birkaç hata bulduk.

Aurora Engine: ecPairing

Bu hata, önceden derlenmiş ecPairing sözleşmesinde bulunmaktadır.

ecPairing'in girdisi, iki eliptik eğri üzerindeki birden fazla noktadan oluşmaktadır. Spesifikasyona göre, (0, 0) noktası her iki eğri üzerinde de bulunmaktadır ve geçerli bir girdi olmalıdır:

Ancak Aurora Engine (sürüm 2.7.0), girdi (0,0) noktasını içerdiğinde geri dönüş yapacaktır.

İlgili PR burada.

Moonbeam: ecMul

Bu hata, önceden derlenmiş ecMul sözleşmesindedir. Aurora Engine'den farklı olarak, Moonbeam girdi geçerli olduğunda işlemi geri alır. Spesifikasyona göre, önceden derlenmiş ecMul sözleşmesi, girdi uzunluğu 64'ten az olduğunda girdiyi sıfırlarla doldurmalıdır. Ancak Moonbeam, doldurma işlemini gerçekleştirmek yerine geri dönüş yapar.

Ayrıca önceden derlenmiş ecAdd ve modexp sözleşmelerinin de aynı soruna sahip olduğunu tespit ettik.

Moonbeam: ecRecover

Bu hata, Ethereum adresini kurtarmak için kullanılan önceden derlenmiş ecRecover sözleşmesindedir.

Spesifikasyona göre, input[32..63] v bir U256 tanımlayıcısını temsil eder ve 27 ya da 28 olması beklenir; aksi takdirde ecRecover hiçbir şey döndürmemelidir (ancak tüm işlem geri alınmamalıdır).

Bununla birlikte, Moonbeam burada iki hata yapmaktadır:

  • input[32..63]'ü U256 türüne dönüştürüp değeri kontrol etmek yerine yalnızca input[63]'ü kontrol eder.
  • Tanımlayıcı 0 veya 1 olduğunda girdi geçerli kabul edilir (yalnızca 27 veya 28 olmalıdır).

Moonbeam: ecPairing

Bu hata, önceden derlenmiş ecPairing sözleşmesindedir. Moonbeam, girdi geçersiz olduğunda işlemi geri almaz. Spesifikasyona göre, önceden derlenmiş ecPairing sözleşmesinin girdisi 192'nin katı olmalıdır. Aksi takdirde işlem geri alınmalıdır.

Ancak Moonbeam, yukarıda belirtilen gereksinimler karşılanmadığında işlemi geri almaz.

3.2 Hatalı Gaz Hesaplama

Her önceden derlenmiş sözleşmenin gaz kullanımını belirleyen bir algoritması vardır. Hatalı gaz hesaplama, DoS saldırısına neden olabilir.

Hem Aurora Engine'de hem de Moonbeam'de gaz hesaplamasının hatalı olduğuna dair iki hata tespit ettik.

Aurora Engine: modexp

Hata, önceden derlenmiş modexp sözleşmesindedir. Gaz kullanımını hesaplama algoritması EIP-2565 tarafından tanımlanmıştır. Gaz kullanımı, yineleme sayısıyla ilişkilidir.

Yineleme sayısını hesaplama algoritması aşağıdaki gibidir.

def calculate_iteration_count(exponent_length, exponent):
   iteration_count = 0
   if exponent_length <= 32 and exponent == 0: iteration_count = 0
   elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1
   elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1)
   return max(iteration_count, 1)

Yukarıdaki algoritmaya göre, yineleme sayısı en az birdir. Ancak Aurora Engine, max(iteration_count, 1) yerine doğrudan iteration_count değerini döndürür. Bu durumda döndürülen değer (yani iteration_count) 0 olabilir; bu da Aurora'nın belirli durumlarda beklenenden çok daha düşük gaz ücreti talep edeceği anlamına gelir.

İlgili konu bağlantısı burada.

Moonbeam: modexp

Hata, önceden derlenmiş modexp sözleşmesinin calculate_iteration_count işlevindedir. Ancak bu hata Moonbeam'de bulunmaktadır.

exponent_length 32'den büyük olduğunda, iteration_count aşağıdaki algoritmayla hesaplanır.

(8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1)

Burada exponent & (2**256 - 1) kullanıldığına dikkat edin; bu, exponent'in en düşük 32 baytını alır ve Moonbeam'in uygulaması bu algoritmayı izler.

Ancak spesifikasyona göre, gaz hesaplama formülü exponent'in en yüksek 32 baytını kullanmalıdır:

3.3 Nonce Artırma Hatası

Harici olarak sahip olunan bir hesabın (EOA) nonce değeri, bu adres tarafından imzalanan başarılı işlem sayısını gösterir. Ancak Aurora Engine'de geçersiz işlemler gönderilerek nonce değerinin artırılabildiğini fark ettik.

EIP-1559'a göre, bir işlemi yürütmeden önce EVM, imzalayanın aktarılan yerel token'ı (ör. ETH) ve gerekli gazı karşılamaya yetecek bakiyeye sahip olduğunu doğrulamalıdır. Aksi takdirde işlem reddedilmeli ve imzalayanın nonce değeri artırılmamalıdır.

Aurora Engine bu durumda işlemi reddetse de imzalayanın nonce değerini artırmaya devam eder.

İlgili PR burada.

3.4 Hatalı Opcode Uygulaması

Bu hata, belirli bir opcode'un (yani PUSH) uygulamasıyla ilgilidir. PUSH opcode'unun ardından gelen baytlar eksik olduğunda, bunların sağa hizalanması gerekir. Örneğin, 0x64ffff bayt kodu şu şekilde çözümlenebilir:

PUSH5 0xffff

İşlenen sağa hizalanması gerektiğinden, yığına 0xffff000000 değeri itilmelidir. Ancak hem Aurora Engine hem de Moonbeam'deki EVM uygulamaları bunun yerine 0xffff değerini iter; bu hatalıdır.

İlgili PR burada.

4. Hizmetimiz

BlockSec olarak, farklı blok zinciri uygulamalarında EVM uyumluluğunu ve güvenliğini sürdürmenin önemini anlıyoruz. Bu nedenle, EVM uygulamalarındaki güvenlik açıklarını kolaylıkla tespit edebilen sistematik bir hata algılama yaklaşımı geliştirdik.

Dahili sistemimiz, EVM uygulamalarındaki hataları ve güvenlik açıklarını tespit etmede son derece etkili olduğunu kanıtlamıştır. Aurora Engine'de dört hata ve Moonbeam'de dört hata başarıyla raporlanmış ve düzeltilmiştir. Bunun yanı sıra, test metodolojimiz geçen yıl Solana rbpf uygulamasındaki iki kritik güvenlik açığını (CVE-2021–46102, CVE-2022–23066) tespit etmek için kullanılmış; bu da yaklaşımımızın etkinliğini ortaya koymaktadır.

Sistematik hata algılama yaklaşımımızı uygulayarak müşterilerimiz, EVM uygulamalarının güvenli ve güvenilir olduğundan emin olabilir. EVM uyumluluğu ve güvenliği için birinci sınıf çözümler sunmaya kararlıyız; müşterilerimizin kullanıcıları ve paydaşları nezdinde güven inşa etmelerine yardımcı oluyoruz.

BlockSec Hakkında

BlockSec Ekibi, blok zinciri ekosisteminin güvenliğine odaklanmakta ve ürünlerini güvence altına almak için önde gelen DeFi projeleriyle iş birliği yapmaktadır. Ekip, hem akademi hem de sektörden üst düzey güvenlik araştırmacıları ve deneyimli uzmanlar tarafından kurulmuştur. Prestijli konferanslarda birden fazla blok zinciri güvenlik makalesi yayımlamışlar, DeFi uygulamalarına yönelik çeşitli sıfır gün saldırılarını raporlamışlar ve yüksek etkili güvenlik olaylarının ayrıntılı analiz raporlarını yayınlamışlardır.

Resmi Web Sitesi | Twitter | Medium

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit