5 Mart 2025'te, 1inch'in Fusion V1 protokolüyle entegre edilmiş bir üçüncü taraf çözümleyici sözleşmesi, toplam 5 milyon doları aşan kayıplarla sonuçlanan koordineli bir saldırıya maruz kaldı. Temel neden, uzlaşım akışındaki güvensiz calldata yeniden yapılandırmasıydı; burada saldırgan tarafından kontrol edilen etkileşim uzunluğu, sonek birleştirme sırasında bir işaretçi alt taşmasını tetikleyerek sahte uzlaşım verisinin enjekte edilmesine olanak sağladı. Saldırı ayrıca yanlış konumlandırılmış bir güven sınırıyla da mümkün kıldı: çözümleyici sözleşmeler, uzlaşım sözleşmesi tarafından iletilen tüm calldata'ya yalnızca msg.sender'a dayanarak örtük olarak güveniyordu; bu durum, tüm erişim kontrol denetimlerini geçmesine rağmen saldırgan tarafından kontrol edilen verinin uzlaşım düzeyinde yetki kazanmasına yol açtı.
Bu olay, 2025'in en sofistike DeFi saldırılarından biri olarak öne çıkıyor; bunun nedeni yeni bir finansal ilkel değil, düşük seviyeli ABI ve bellek düzeni varsayımlarının istismar edilmesi, akıllı sözleşme güvenlik açıkları ile klasik ikili istismar teknikleri arasındaki sınırı bulanıklaştırmasıdır.
Arka Plan
1inch'in Fusion V1 Protokolü
1inch, kullanıcılara optimize edilmiş takas yürütümü sağlamak amacıyla birden fazla DEX'ten likidite toplayan merkezi olmayan bir borsa (DEX) toplayıcısıdır. Toplayıcının limit emir altyapısının üzerine inşa edilen 1inch Fusion, kullanıcıların fiyat aralıkları ve takas zaman pencereleri gibi esnek yürütme parametreleri belirlemesine olanak tanıyan Hollanda açık artırmasına dayalı bir emir eşleştirme modeli sunar.
Fusion modelinde, kullanıcı emirleri doğrudan protokolün kendisi tarafından karşılanmaz. Bunun yerine, çözümleyiciler olarak bilinen özel aktörler tarafından yürütülür. Çözümleyiciler, ayrıcalıklı ve beyaz listeye alınmış katılımcılar olarak değerlendirilebilir: uygun hale gelebilmek için ekonomik bir kapı mekanizması işlevi gören yeterli Unicorn Power elde etmek amacıyla token stake etmeleri gerekir.
Operasyonel olarak, çözümleyiciler kullanıcı emirlerini keşfetmek ve bunları doldurup doldurmayacaklarını ve ne zaman dolduracaklarını belirlemek için 1inch'in arka uç API'leriyle arayüz kuran kendi zincir dışı altyapılarını çalıştırır. Bir çözümleyici bir emri yürütmeye karar verdiğinde, asıl takası gerçekleştiren Settlement sözleşmesine ayrılmış bir hesap aracılığıyla zincir üzerinde bir işlem gönderir. (Fusion, çözümleyiciler arasında rekabetçi bir Hollanda açık artırması içerse de bu mekanizma saldırıyı anlamak için gerekli değildir ve bu nedenle burada ele alınmamıştır; basitlik adına çözümleyicinin kullanıcının emir koşullarını doğrudan karşılayabildiği varsayılmaktadır.)
Bir takas gerçekleştirirken, çözümleyici kullanıcının minimum gereksinimlerinden daha iyi bir yürütüm sağlamak için harici piyasalardan likidite temin edebilir ya da ticareti kendi varlıklarını kullanarak doğrudan gerçekleştirebilir. Bu süreçte elde edilen fazla değer, çözümleyiciye kâr olarak birikir. Bu blog yazısında ele alınan saldırı, böyle bir çözümleyici sözleşmeyi hedef almaktadır. Özellikle, varlıklar bulunduran ve Settlement sözleşmesine onay veren bir zincir üzeri piyasa yapımı sözleşmesi, bu varlıkların kaybedilmesine yol açmıştır.
Emir İşleme ve Yerine Getirme
1inch Fusion'da emir yürütümü, Settlement sözleşmesi tarafından koordine edilir ve doğrusal bir yürütme akışı yerine etkileşim verisi tarafından yönlendirilen özyinelemeli bir uzlaşım modeli izler.
Süreç, bir çözümleyicinin settleOrders() fonksiyonunu çağırmasıyla başlar; bu fonksiyona bir etkileşim yükü ile birlikte ilk emri kodlayan calldata iletilir. Settlement, tüm emirleri aynı anda gerçekleştirmeye çalışmak yerine, onları dahili _settleOrder() fonksiyonunun tekrarlanan çağrıları aracılığıyla artımlı biçimde işler.
Her emir için _settleOrder() fonksiyonu, bellekte Limit Emir Protokolüne (AggregationRouterV5.fillOrderTo()) yapılacak bir çağrıyı yeniden oluşturur. Bu yeniden oluşturma sırasında Settlement, dinamik bir sonek biçiminde etkileşim verisine çözümleyiciyle ilgili ek bağlam ekler. Bu sonek; çözümleyici kimliği ve birikmiş ücretler gibi yürütme meta verilerini taşır ve Limit Emir Protokolü tarafından opak olarak ele alınır. Değiştirilmeden iletilir ve daha sonra etkileşim geri çağrısı sırasında Settlement'ın kendisi tarafından çözümlenir.
Emir doldurulduktan sonra, kontrol fillOrderInteraction() fonksiyonu aracılığıyla Settlement'a geri döner. Etkileşim verisine bağlı olarak Settlement, kalan etkileşim yükü ile _settleOrder() fonksiyonunu özyinelemeli olarak çağırarak uzlaşımı sürdürür ya da bir sonlandırma adımına geçer. Son aşamada Settlement, birikmiş yürütme bağlamını ileterek çözümleyici sözleşmedeki resolveOrders() fonksiyonunu çağırarak kontrolü çözümleyiciye aktarır.
Bu tasarım, tüm protokol düzeyindeki yürütme adımları tamamlanana kadar çözümleyiciye özgü mantığı erteleyerek tek bir işlem içinde birden fazla emrin sırayla gerçekleştirilmesine olanak tanır.
Güvenlik Açığı Analizi
Güvenlik açığı, dahili _settleOrder() fonksiyonundaki güvensiz calldata yeniden yapılandırma mantığından, özellikle de etkileşim verisine eklenen dinamik sonekin yerleştirilmesi sırasında ortaya çıkmaktadır.
Çözümleyici sözleşmeler, açık erişim kontrolüyle korunmaktadır: çağrıların Settlement sözleşmesinden kaynaklandığını ve çözüm sırasında sağlanan çözümleyici adresinin çözümleyici sözleşmenin kendisiyle eşleştiğini doğrularlar. Bu denetimler, uzlaşım süreci boyunca yayılan çözümleyici kimliğinin doğru bir şekilde oluşturulduğunu ve bütünlüğünü koruduğunu varsayar. Bu varsayım, calldata yeniden yapılandırması sırasında çözümleyiciyle ilgili verinin nasıl kodlandığına ve eklendiğine bağlıdır.
Somut olarak, çözümleyicinin resolveOrders() fonksiyonu iki koruma uygular:
require(msg.sender == _settlement, OnlySettlement());
require(this == resolver, NotTaker());
İlk denetim, çağrının Settlement sözleşmesinden kaynaklandığını doğrular. İkincisi, sonek üzerinden çözümlenen resolver parametresinin çözümleyici sözleşmenin kendi adresiyle eşleştiğini doğrular. Normal işlem altında, her iki alan da _settleOrder() tarafından doğru şekilde ayarlanır. Saldırı altında, her iki denetim de geçmeye devam eder: saldırgan uzlaşım akışının içinde faaliyet gösterir (dışında değil), dolayısıyla msg.sender gerçekten Settlement sözleşmesidir; resolver alanı ise sahte sonekten çözümlenir ve saldırgan buraya kurban çözümleyicinin adresini yazmıştır.
Uzlaşım sırasında _settleOrder(), calldata'yı bellekte yeniden oluşturur ve çözümleyiciye özgü yürütme bağlamını taşıyan dinamik bir sonek ekler. Bu sonek yalnızca çözümleyici adresini değil, aynı zamanda çözümleyicinin uzlaşımı meşru olarak yorumlamak için dayandığı emirle ilgili bilgileri de içerir. Sonek, ptr + interactionOffset + interactionLength olarak hesaplanan bir bellek konumuna yazılır; burada interactionLength doğrudan calldata'dan tam 32 baytlık bir değer olarak okunur.
Bu ofset hesaplaması sınır denetimi yapılmadan gerçekleştirildiğinden, saldırgan interactionLength'i kontrol ederek aritmetik taşmaya neden olabilir ve sonekin bellekte nereye yazıldığını manipüle edebilir. Böylece saldırgan, amaçlanan soneği sahte bir sonekle değiştirerek kurban çözümleyicinin adresi ile birlikte saldırgan tarafından kontrol edilen emir bağlamını sağlayabilir.
Sonuç olarak, uzlaşım akışı soneği daha sonra çözümlediğinde, yürütümü meşru bir çözümleyiciden kaynaklanıyor ve geçerli emir verisi içeriyor olarak yorumlayabilir; oysa her iki varsayım da geçerli değildir. Saldırgan, birkaç wei karşılığında milyonlarca dolar takas etmek için çözümleyici gibi davranarak emir sonekinin kendi versiyonunu enjekte etmeyi başarır.
Saldırı Analizi
0x74bc işlemini örnek alarak. Saldırı, ihmal edilebilir miktarda token (birkaç wei) takas eden ancak orantısız derecede büyük çıktı miktarları talep eden beş geçerli emrin oluşturulmasıyla başlar. Bu emirler sözdizimsel olarak geçerlidir ve protokol düzeyindeki denetimleri geçer.
Saldırgan daha sonra emir calldata'sını geniş bir null bayt bölgesiyle doldurur. Bu dolgu, hatalı sonek yerleşimi nedeniyle daha sonra üzerine yazılacak kontrollü bir bellek alanı işlevi görür.
Kritik olarak, saldırgan son emir için geçersiz bir interactionLength değeri belirtir. Bu değer 0xffff…fe00 olarak seçilmiştir; işaretli tam sayı olarak yorumlandığında -512'ye karşılık gelir. interactionLength işaretsiz 256 bitlik bir değer olarak ele alındığından ve doğrudan işaretçi aritmetiğinde kullanıldığından, sonek yazma ofsetini hesaplarken aritmetik taşmaya neden olur.
Aşağıdaki kötü amaçlı etkileşim yapısı sonek olarak ele alınır:
Sahte Sonekten Varlık Çıkarımına
Settlement son emri işlediğinde, taşma meşru sonekin null ile doldurulmuş bölgeye yazılmasına neden olur ve sıfırların üzerine zararsız biçimde yazar. Saldırganın gerçek okuma konumuna yerleştirdiği sahte sonek daha sonra meşru uzlaşım bağlamı olarak yorumlanır.
Sahte sonek sonlandırma bayrağını ayarlayarak Settlement'ın özyinelemeli emir işleminden sonlandırma adımına geçmesine neden olur. Settlement, sonekten çözümlenen adres olan kurban çözümleyici üzerinde resolveOrders() fonksiyonunu çağırır. Güvenlik Açığı Analizinde açıklandığı gibi, her iki erişim denetimi de geçer: msg.sender Settlement sözleşmesidir (çağrı meşru uzlaşım yolundan geçer) ve resolver kurbanın adresiyle eşleşir (saldırgan tarafından sahte soneke yazılmıştır).
Kurban çözümleyici daha sonra saldırgan tarafından seçilen varlık adreslerini ve miktarlarını içeren tokensAndAmounts dizisini işler. Çözümleyici daha önce normal işlem için Settlement sözleşmesine token onayları verdiğinden, transfer gerçekleşir. Çözümleyici, yalnızca birkaç wei girdi gerektiren emirleri karşılamak için tuttuğu varlıkları gönderir ve bu durum 5 milyon doları aşan kayıpla sonuçlanır.
Özet
Bu olay, 1inch'in kullanımdan kaldırılmış Fusion V1 protokolüyle entegre edilmiş bir üçüncü taraf çözümleyici sözleşmeyi hedef alarak önemli kayıplara yol açmış ve birkaç önemli dersi gün yüzüne çıkarmıştır.
- Güvensiz Veri Varsayımları: Dinamik olarak oluşturulmuş girdi verisine dayanan sistemler, herhangi bir bölümün kullanıcı etkisinde olduğu durumlarda uzunlukları, ofsetleri veya yapı bütünlüğünü varsaymamalıdır.
- Örtük Güven Zincirleri: Sözleşmeler kritik bağlamı her sınırda doğrulamak yerine üst akış bileşenlerinin bu bağlamı korumasına güvendiğinde güvenlik denetimleri zayıflayabilir.
- Eski Yüzey Alanı: Güncelliğini yitirmiş bileşenleri desteklemek saldırı yüzeyini artırır ve protokolleri yeni istismar tekniklerine karşı daha savunmasız hale getirir.
- Alanlar Arası İstismar Desenleri: Geleneksel yazılımlarda yaygın olan güvenlik açıkları, düşük seviyeli bellek veya veri düzeni mantığı söz konusu olduğunda zincir üzerinde yeniden ortaya çıkabilir.
Referans
-
https://blog.decurity.io/yul-calldata-corruption-1inch-postmortem-a7ea7a53bfd9
-
https://paragraph.com/@cookies-research/1inch-fusion-cost-efficient-mev-resistant-swaps
-
https://blog-zh.1inch.com/fusion-swap-resolving-onchain-component/#steps-5-6
BlockSec Hakkında
BlockSec, tam yığın blok zinciri güvenliği ve kripto uyumluluk sağlayıcısıdır. Müşterilerin kod denetimi (akıllı sözleşmeler, blok zinciri ve cüzdanlar dahil) gerçekleştirmesine, saldırıları gerçek zamanlı olarak önlemesine, olayları analiz etmesine, yasadışı fonları takip etmesine ve protokollerin ile platformların tam yaşam döngüsü boyunca AML/CFT yükümlülüklerini yerine getirmesine yardımcı olan ürün ve hizmetler geliştiriyoruz.
BlockSec, saygın konferanslarda birden fazla blok zinciri güvenlik makalesi yayımlamış, DeFi uygulamalarının birçok sıfır gün saldırısını bildirmiş, 20 milyonun üzerinde doları kurtarmak için birden fazla saldırıyı engellemiş ve milyarlarca değerinde kripto parayı güvence altına almıştır.
-
Resmi web sitesi: https://blocksec.com/
-
Resmi Twitter hesabı: https://twitter.com/BlockSecTeam



