Cosmos EVM açığı aylar sonra istismar edildi, 6 zincir etkilendi

Anasayfa » Cosmos EVM açığı aylar sonra istismar edildi, 6 zincir etkilendi
Cosmos EVM açığı aylar sonra istismar edildi, 6 zincir etkilendi

Cosmos EVM ekosistemindeki kritik bir hata, Cosmos Labs’in yamayı yayımlayıp sorunun kapsamını daha sonra doğrulamasının ardından istismar edildi. Etkilenen yapı, Cosmos EVM çalıştıran ve vesting hesapları ile staking işlemleri arasında bakiye uyumsuzluğu oluşan blok zincirlerini kapsıyor. Şirket, açık için GHSA-7g4w-cg88-2cq2 kimliğini verdi; ancak bulgu bir CVE numarası, zafiyet sınıflaması ya da CVSS puanı olmadan yayımlandı.

Yama 19 Ağustos’ta v0.6.2 ve v0.7.2 sürümleriyle dağıtıldı. Cosmos Labs, 28 Ağustos’ta yayımladığı olay sonrası değerlendirmede, açığın 25 Nisan’da bug bounty programı üzerinden bildirildiğini, ilk incelemede ise canlı ağlardaki fonlar için risk taşımadığı sonucuna vardıklarını açıkladı. Şirket, 18 ondalıklı ağlarda hatayı yeniden üretemediğini, bu yüzden yalnızca 18 ondalıklı olmayan ağları etkilediğini düşündüğünü de kabul etti. 13 Ağustos’a gelindiğinde, decimal ayarından bağımsız olarak tüm Cosmos EVM zincirlerinin etkilendiği doğrulandı.

Cosmos Labs, buna rağmen düzeltmeyi canlı ağlarda fon kaybına yol açmayan sorunlar için sakladığı “silent patch” süreciyle ilerletti. Olay sonrası notta, normalde kullanıcı fonlarını tehdit eden bir açık karşısında yamayı özel kanallardan etkilenen ağlara ulaştırdıklarını, ancak yama ana dalda zaten kamuya açık olduğu ve henüz bir istismar sinyali görülmediği için sessiz yama akışını sürdürdüklerini yazdı. Şirketin kendi sessiz yama politikası ise farklı bir yol çiziyor: Acil ya da ağ genelinde risk oluşturan durumlarda kamu duyurusu öncesi acil azaltımlar, özel düzeltme dağıtımı veya koordineli yükseltme yapılacağını belirtiyor.

Bakiye uyumsuzluğu nasıl istismara dönüştü

Açığın kökü, Ethereum Virtual Machine durumunu Cosmos SDK’nın x/bank modülüyle uzlaştıran kodda yatıyor. EVM tarafındaki StateDB yalnızca harcanabilir bakiyeyi takip ediyor. Cosmos SDK durumundaki vesting hesapları ise hem harcanabilir hem de kilitli bakiyeyi tutuyor. Ayrıca x/staking modülü ile staking precompile’ı, kilitli kısmın delegasyona konu olmasına izin veriyor.

Bir vesting hesabı, harcanabilir bakiyesinden daha fazla tutarı delege ettiğinde sorun başlıyor. Delegasyon sonrası yazılan geri kayıt, toplam delegasyon miktarını daha küçük olan harcanabilir bakiyeden düşüyor. Bu çıkarma işlemi kontrol edilmediği için bakiye yaklaşık 2^256 değerine sarılıyor. Ardından uzlaştırma mantığı pozitif farkta mint, negatif farkta burn yapıyor. Saldırgan, sarılmış hesaptan sınırlı miktarda varlık çekebiliyor ya da kurban hesabına bakiyesinden 2^256 eksi tutar göndererek uzlaştırmanın kurbanın gerçek varlığını yakmasını sağlayabiliyor.

0.6.x sürümlerinde mint ve burn işlemleri arka plandaki SDK defterinde yapıldığı için büyük bir mint, arz taşmasına yol açıp zinciri durduruyor. 0.7.x çalışan zincirlerde ise bakiyeler doğrudan x/bank içinde ayarlanıyor ve uint256 ile int256 dönüşümünü geçen değişiklikler kabul ediliyor. Her iki taraf da tek bir işlem içinde, net arz değişimi sıfır olacak şekilde çalışıyor. Saldırı için, önceden hesaplanmış bir adrese dağıtılan sözleşmenin önce vesting hesabına dönüştürülmesi gerekiyor. Cosmos Labs’e göre istismar, zincirin izinsiz vesting hesabı oluşturulmasına izin vermesini de şart koşuyor.

Şirket, operatörlere v0.6.2 veya v0.7.2 ya da daha yeni sürümlere koordineli ağ yükseltmesiyle geçmelerini söyledi. Değişiklik state-breaking olduğu için düzeltme sıradan bir güncelleme değil, zincirin birlikte yükseltilmesini gerektiriyor. Hemen geçiş yapamayan operatörlere ise zinciri durdurmaları, koordineli bir yönetişim oylamasıyla ilerlememeleri tavsiye ediliyor. Duyuruda, yapılandırma değişikliğiyle çözülebilecek bir açık olmadığı da belirtiliyor; staking precompile’ını devre dışı bırakmanın ana tetik yolunu kapatsa bile yama yerine geçmeyeceği vurgulanıyor.

Kuruluş ayrıca ante handler içinde MsgCreateVestingAccount, MsgCreatePermanentLockedAccount ve MsgCreatePeriodicVestingAccount mesajlarının reddedilmesini önerdi. Genesis’te tanımlı vesting hesaplarının bu önlemden etkilenmediği kaydedildi. Buna ek olarak, canlı kod yolunun bir fork üzerinde doğrulanması gerektiği de hatırlatıldı. Uyarıda, yalnızca dışa açık yardımcı işlevin yamalanmasının, aynı işlevin içe açık bir kopyası varsa testi geçen ama üretimde açık bırakan bir duruma yol açabileceği not edildi.

Cosmos Labs’in kendi bug bounty politikasında ise farklı bir ayrıntı daha yer alıyor. Kurum, acil veya ağ genelinde risk oluşturan bir sorun görüldüğünde kamu açıklaması yapılmadan önce özel düzeltme dağıtımı ve koordineli yükseltme başlatacağını söylüyor. Ancak 27 Temmuz’da son kez senkronize edilen bu politika metni, bu olayda izlenen silent patch akışıyla birebir örtüşmüyor.

İstismar zinciri, özel bildirim ve yayılma

Cosmos ekosisteminde bu açık için kamuya açık ayrıntılar ilk kez 20 Ağustos saat 07:16 UTC’de Push Chain’in Cosmos EVM fork’unda yayımlanan bir pull request ile ortaya çıktı. Bu paylaşım, zafiyetin ve istismar yolunun ayrıntılarını içeren ilk kamu kaydı oldu. Yamanın çıkışından sekiz saat 15 dakika sonra gelen bu ifşanın ardından ilk saldırı, MANTRA’ya karşı 20 Ağustos saat 19:06 UTC’de başladı.

Cosmos Labs, MANTRA’nın istismar edildiğini bildirmesinden yaklaşık iki saat sonra, 21 Ağustos saat 03:36 UTC’de güvenli e-posta üzerinden ilk özel bildirimi gönderdi. Şirket, son 13 ay içinde 37 zafiyet için sessiz yama yayımladığını, ancak downstream geliştiricilerin kamuya açık alanda istismar yollarını bu kadar net tarif etmediğini de not etti. 19 Ağustos tarihli v0.6.2 ve v0.7.2 sürüm notlarında yalnızca “önemli güvenlik düzeltmeleri” ifadesi yer alıyor; hangi pull request’lerin dahil edildiği changelog’a yazılmamış durumda. 29 Ağustos’ta yapılan doğrulama, bu iki sürüm notunda ilgili backport’un listelenmediğini gösterdi.

Olay sırasında Cosmos Labs, açık saldırısının kullanıldığı altı zincirden haberdar olduğunu bildirdi. Şirketin verdiği rakamlara göre saldırganlar, etkilenen varlıkların yaklaşık 2,87 milyon dolarlık kısmını 19 Ağustos fiyatlarıyla merkeziyetsiz borsalarda sattı. Bu tutarın etkilenen zincirler tarafından sağlandığı, ancak bağımsız denetimden geçmediği belirtiliyor. Ayrıca yaklaşık 2,85 milyon dolarlık ek satışın merkezi borsalarda yapıldığı, bu hesabın da Cosmos Labs tarafından kamuya açık hacim verilerine dayanarak oluşturulduğu aktarıldı.

Cosmos Labs’in olay sonrası notunda öne çıkan bir başka başlık da ekosistemin dağılımı oldu. Cosmos ağının 115’ten fazla bilinen genel blok zincirine yayıldığını, ancak şirketin yazılımını çalıştıran ağlar için tam bir kayıt tutmadığını açıkladı. Bu eksiklik, temmuz ayında paketlenmiş dosya sistemi açıklarının düzeltilmesinde downstream satıcıların yaşadığı benzer kör noktayı da hatırlatıyor.

Teknik ayrıntılara bakıldığında, upstream tarafta tek açıkça belgelenen değişiklik 15 Mayıs’ta main dalına alınan ve 13 Ağustos’ta backport edilen SubBalance underflow koruması oldu. Pull request #1176 olarak geçen bu yama, state-breaking bir değişiklik olmasına rağmen yaklaşık doksan gün sonra geriye taşındı. Aynı depoda yer alan ve belge dışında kalan iki bakiye düzeltmesi daha bulunuyor. Pull request #1187, 20 Mayıs’ta bir hesabın kilitli bakiyesini snapshot’layarak bir precompile değişiklik yaptıktan sonra bank bakiyesinin doğru yeniden kurulmasını sağlıyor. Bu backport’lar her iki release hattı için de aynı gün açıldı ve yirmi dört saat içinde kabul edildi.

Üçüncü değişiklik ise 3524ebc commit’inde yer alıyor. “Merge commit from fork” başlıklı bu yama, module account bakiyesini ayarlama girişimlerini reddediyor. ZetaChain katkıcısı morde08, 21 Ağustos’ta yayımlanan üç düzeltmenin portunda, cherry-pick edilen yamanın fork’un canlı yolunu açık bırakabildiğini söyledi. Nedeni, fork’ta çiftlenmiş unexported yardımcı işlevlerin bulunması ve upstream değişikliğinin yalnızca exported sürümü hedeflemesi. Bu nedenle testlerin geçmesine rağmen üretim yolunun yamalanmamış kalabildiğini belirtti.

Warden Protocol ise iki gün sonra farklı bir yol izledi ve vesting hesabı oluşturmayı tamamen kapattı. Warden Protocol katkıcısı jlehtimaki, commit mesajında vesting hesaplarının Warden üzerinde kilitli bakiyelerin tek kaynağı olduğunu, kullanıcıların bunları oluşturmasına hiçbir özelliğin bağlı olmadığını yazdı. Ona göre bu yolun kaldırılması, bakiyenin doğru yeniden oluşturulmasına güvenmek yerine doğrudan ön koşulu ortadan kaldırıyor.

Farklı fork’larda alınan önlemler de sorunun tek bir kod satırından ibaret olmadığını gösterdi. Bir fork’ta exported yardımcı işlevin düzeltilmesi yeterli sayılırken, başka bir projede vesting hesabı oluşturma akışı tamamen kaldırıldı. Cosmos Labs’in kendi notunda ise 11 Cosmos EVM dağıtımının olay sırasında güvenlik kanallarına hiç kayıt yaptırmadığı öğrenildiği de yer aldı.

Açığın kaynağı, yamanın yayımlandığı andan istismarın ilk kez görüldüğü ana kadar geçen süreçte zincir operatörlerinin ve fork geliştiricilerinin farklı hızlarda hareket etmesi oldu. Cosmos Labs, 37 zafiyeti son 13 ayda sessizce yamaladığını belirtiyor; bu olayda ise kamuya açık bir pull request, yamadan saatler sonra gerçek istismar yolunu görünür hale getirdi. Şirket, altı zincirde exploit kullanıldığını doğrularken, dağıtım ağları arasındaki kayıt eksikliğinin de müdahale ve bildirim süreçlerini zorlaştırdığını kabul ediyor.