Tamamen meşru noterlik kayıtlarına, değiştirilmiş bir durum kökü (state root) içeren, çift oluşturulmuş kötü amaçlı kayıtlar eklendi. Bu kayıtlar Verus noterleri tarafından imzalandı ve ardından Ethereum'a iletilerek gerçek güvenilir state root'un yerine geçti. Saldırgan bu değer üzerinde kontrol elde ederek, köprü üzerinden sahte bir içe aktarma (import) kanıtı gönderebildi; bu da orijinal dışa aktarmanın yalnızca 0.01 VRSC olmasına rağmen, fiilen gönderilenden çok daha fazla fonun çekilmesine olanak tanıdı.
Noterlik onayı nedir
Verus ağında noterlik onayı, iki blockchain arasında imzalanmış bir kontrol noktasıdır. Transfer ve dışa aktarma işlemlerine ilişkin kanıtların daha sonra kendisine göre doğrulandığı ağ durumunu tam olarak bu belirler.
Böyle bir onay şunları içerir:
- blockchain veya para birimi tanımlayıcısı;
- noterlik onayının yüksekliği;
- aşağıdakileri içeren bir veya daha fazla kanıt kökü (proofRoots):
- ağ tanımlayıcısı;
- blok yüksekliği;
- durum kökü (state/proof root);
- blok hash'i;
- biriken hesaplama gücü;
- para birimi ve dönüştürücü durumu hakkında bilgiler;
- önceki noterlik onayına referans;
- önceki cross-chain noterlik onayının hash'i;
- düğüm ve başlatıcı hakkında bilgiler.
Kanıt kökleri, Verus ve Ethereum blockchain'lerinin açık verilerine dayanılarak oluşturulur. Herhangi bir kullanıcı bir noterlik onayı adayı oluşturup iletebilir; ancak ağ, bunu yalnızca uzlaşı gereklilikleri karşılandığında ve önceki noterlik onayı zincirinin doğru UTXO'su kullanıldığında kabul eder.
Noter imzaları (CNotarySignature), CNotaryEvidence yapısının bir parçasıdır ve açık şekilde yayımlanır. Bu sayede saldırgan, bu imzaları elde edip yeniden kullanabildi.
Saldırının kronolojisi (UTC)
Saldırganlar hack için titizlikle hazırlandı ve iki gün boyunca hareket etti.
Saldırı nasıl gerçekleşti: dört aşama
Protokolün hacklenmesine ilişkin tüm algoritma dört önemli aşamaya ayrılabilir.
1. Verus ağında noterlik onayının değiştirilmesi
İlk işlem, noterlik zincirinin önceki onaylanmış çıktısını (4f4f…:1) kullandı ve yeni bir çıktı (0c247…:0) oluşturdu. Blok gezgini arayüzünde yalnızca iki meşru kayıt görünse de, serileştirilmiş verilerin içine sahte state root'lara sahip ek kayıtlar gizlice yerleştirildi.
Bunun nedeni, veri işlemenin kendine özgü niteliklerinde yatıyordu. Verus önce kök listesini bir dizi (array) olarak okuyor, ardından bunu bir Map yapısına aktarıyordu. Bu sayede saldırgan, her biri ayrıca değiştirilmiş state root'lara sahip birkaç gizli kötü amaçlı kayıt içeren, birbirini izleyen iki işlem oluşturabildi.
2. Ethereum'da durum kökünün değiştirilmesi
Bunun ardından saldırgan, noterlerin yazılımının doğru olan ilk kayıtları doğrulamasını bekledi. Ardından 11 noter düğümü, Verus sisteminin fiilen yok saydığı, kötü amaçlı verilere sahip gizli çift kayıtlar da dâhil olmak üzere noterlik onayının tamamını imzaladı.
Elde edilen imzalar CNotaryEvidence yapısına dâhil edildi. Ardından saldırgan, Verus'un RPC arayüzü üzerinden bu imzaları elde etti ve Ethereum'da setLatestData() fonksiyonuna bir çağrı oluşturdu.
Ethereum tarafında saldırgan yalnızca bir aktarıcı (relay) rolü üstlendi: noterlik onayının bayt verilerini meşru noter imzalarıyla birlikte kopyaladı ve akıllı kontrata iletti.
deserializeNotarization() fonksiyonunun yürütülmesi sırasında Ethereum kontratı, proofRoots dizisini sırayla işliyordu. Bu sırada Verus sistem tanımlayıcısına sahip her kayıt, stateRoot değerinin üzerine yazıyordu:
- birinci kayıt - gerçek state root;
- ikinci - Ethereum verileri;
- üçüncü - kötü amaçlı bir state root;
- dördüncü - yine kötü amaçlı;
- beşinci - yine kötü amaçlı.
Sonuç olarak son kayıt, gerçek güvenilir durum kökünün yerine tamamen geçti. Köprü üzerinden yapılan sahte transfer kanıtını doğrulamak için daha sonra tam olarak bu sahte state root kullanıldı.
3. Verus üzerinden dışa aktarmanın hazırlanması
Ardından saldırgan, tamamen sıradan bir cross-chain transfer talebi oluşturdu. 5b5043febfd7f7c089e976d11d0f87a904881266bb96dd118b3d69b0e02aab52 işleminde yeni bir adres, Bridge.vETH üzerinden yaklaşık 12 birim komisyon ödeyerek yalnızca 0.01 VRSC'lik bir dışa aktarma başlattı.
Bunun ardından talep dönüştürücü tarafından işlendi ve LuckPool, ayrı bir işlemde toplu bir dışa aktarma oluşturdu. Sahte kanıtın oluşturulmasına daha sonra temel oluşturan, tam olarak bu tamamen meşru talep oldu.
Özellikle şu parametreler kullanıldı:
- hashtransfers: 440787f9114dbb41b7d3d6f6c48980d51221f62ef0a33613d1d305b98ae85053
- sourceheightstart: 4162638
- sourceheightend: 4162847
4. Sahte içe aktarma ve Ethereum üzerinden fon çekme
Son aşamada saldırgan, submitImports() fonksiyonunu çağırdı. 14 alandan oluşan CCE yapısında yalnızca birkaç önemli parametre değiştirildi. hashtransfers alanı, fon çekme işlemlerine karşılık gelecek şekilde tamamen tahrif edildi.
Ayrıca:
- numInputs değeri 8 olarak değiştirildi;
- firstInput - 0 olarak;
- totalAmounts, totalFees ve totalBurned alanları ise tamamen yoktu.
Kanıtın bir kısmı orijinal kaldı. Özellikle şu gerçek değerler kullanıldı:
- işlem tanımlayıcısı (TxID);
- kanıt ağacının ilk düğümü (First node);
- kanıt formatının genel parametreleri, sürümler ve sistem tanımlayıcıları.
Diğer tüm ögeler yapay olarak oluşturuldu. Kötü amaçlı state root Ethereum tarafından zaten güvenilir olarak kaydedildiği için, ortaya çıkan kanıt, orijinal transferde buna karşılık gelen fon hacmi bulunmamasına rağmen doğrulamayı başarıyla geçti.
Güvenlik açığı neydi: Verus ve Ethereum verileri farklı okuyordu
Verus, serileştirilmiş kayıtları, dizinin Map'e dönüştürülmesinin ardından çift ögelerin fiilen yok sayıldığı bir yapı olarak algılıyordu.
Ethereum ise tam tersine tüm kayıtları sırayla işliyordu; bu nedenle her sonraki kayıt, state root değerinin üzerine yazabiliyordu.
Sonuç olarak Verus noterleri, tamamen doğru saydıkları verileri imzaladı; ancak Ethereum aynı baytları farklı yorumladı ve sonunda güvenilir durum kökü olarak, tamamen saldırganın kontrolündeki bir değeri kaydetti.
Ethereum bu sahte state root'u güvenilir olarak kabul ettikten sonra, onun üzerine kurulan her içe aktarma kanıtı sistem tarafından meşru olarak değerlendirildi.
Ek bir etken de Ethereum köprü kontratındaki mantıksal bir hataydı. Kontrat, içe aktarma talebinde belirtilen tutarın, Verus ağından fiilen dışa aktarılan varlık hacmiyle örtüşüp örtüşmediğini denetlemiyordu.
CCE yapısının doğrulamasını başarıyla geçmek için, yalnızca fon çekme işlemleriyle örtüşen sahte bir hashtransfers parametresi oluşturmak yeterliydi.
Çalınan fonların hareketi: Tornado Cash üzerinden 2,778 ETH

Saldırgan, güvenlik açığından başarıyla yararlandıktan sonra çalınan varlıkları Relay üzerinden 2,778.8662 ETH'ye çevirdi ve ardından elde ettiği fonları anonimleştirme servisi Tornado Cash'e aktardı.
