Stride Airdrop Güvenlik Açığı Analizi

IBC üzerine inşa eden geliştiriciler ve IBC entegrasyonlarını inceleyen güvenlik mühendisleri, kötü niyetli IBC istemcilerine veya kanallarına maruz kalan saldırı yüzeyini dikkatlice incelemelidir.

Yazan: Will

Önsöz: Bu makale, Jump Crypto'nun Stride airdrop programında keşfettiği bir güvenlik açığını açıklamaktadır: Stride, Cosmos ekosisteminde sıvı staking için kullanılan bir Cosmos zinciridir. Bu sorun, bir saldırganın Stride'da sahipsiz tüm airdrop'ları çalmasına izin verebilir. Keşif anında 1,6 milyondan fazla STRD (yaklaşık 4 milyon $'a eşdeğer) risk altındaydı. Jump, güvenlik açığını Stride'a katkıda bulunanlara özel olarak bildirdi ve sorun o zamandan beri düzeltildi ve çabalarımızın sonucu olarak hiçbir kötü amaçlı istismar meydana gelmedi. Orijinal bağlantı adresi [1]

Uzun Adımda Airdrop

Stride, ağ etkinliğini teşvik etmek ve yönetişimi geniş bir taraf grubu genelinde merkezsizleştirmek için düzenli olarak kendi yerel [$STRD] jetonunun büyük airdrop'larını yürütür. Airdrop tahsis etme ve talep etme kodu x/claim konumundadır [2] modülde uygulanmaktadır. Airdrop tahsisi, LoadAllocationData aracılığıyla yapılır [3] adresleri ve airdrop tahsislerini içeren bir tahsis dosyasını yükleyen bir işlev tarafından tanımlanır. Çoğu airdrop için, yüklenen adresler, Osmosis veya Juno gibi diğer Cosmos zincirlerindeki kullanıcıları tanımlar, böylece kod önce utils.ConvertAddressToStrideAddress işlevini kullanarak onları Stride adreslerine dönüştürür.

Airdrop'taki her hesap için modül bir ClaimRecord oluşturur. [4] belirli bir airdrop için airdrop tanımlayıcısını, dönüştürülen adresi ve kullanıcıya tahsis edilen jeton miktarını içerir. Bir ClaimRecord oluşturduktan sonra, karşılık gelen Stride adresine sahip bir kullanıcı, zincire bir MsgClaimFreeAmount gönderebilir. [5] Gelin ve airdroplarını talep edin.

Ancak, utils.ConvertAddressToStrideAddress işlevi Evmos adreslerini erişilemeyen Stride adresleriyle eşlediğinden, bu uygulama en son EVMOS airdrop sırasında çalışmadı. Bunun nedeni, EVMOS adreslerinin madeni para türü 60 kullanılarak türetilmesi, Stride adreslerinin ise madeni para türü 118 kullanılarak türetilmesidir.

Ekip, etkilenen kullanıcıların airdrop'u hâlâ talep edebilmesi için, ilgili EVMOS hesabından zincirler arası bir IBC mesajı aracılığıyla talep edilmemiş bir ClaimRecord'un hedef adresini güncelleme özelliğini ekledi. Bu güncelleme mekanizması, x/autopilot modülünün bir parçası olarak uygulanmaktadır. x/otomatik pilot [6] Gelen bir IBC ICS-20 iletimini durdurun ve not veya alıcı alanından Stride'a özel talimatları çıkarmaya çalışın (alıcı alanı, v5'ten önceki IBC sürümlerinde not alanı olarak ikiye katlanır):

func(imIBCModule)OnRecvPacket(

ctxsdk.Bağlam,

paketkanal türleri.Paket,

relayersdk.AccAddress,

)ibcexported.Acknowledgement{

//NOT: onay, IBC işleyici işlemi sırasında eşzamanlı olarak yazılacaktır.

datatransfertypes.FungibleTokenPacketData

iferr:=transfertypes.ModuleCdc.UnmarshalJSON(packet.GetData(),&data);err!=nil{

dönüşkanaltipleri.NewErrorAcknowledgement(hata)

}

[..]

//ibc-gov5hasaİletme bilgilerini saklayabilen bir Not Alanı

//ibc-go'nun eski sürümü için, verilerin alıcı alanında saklanması gerekir

meta veri dizisi

ifdata.Memo!=""{//ibc-gov5+

metaveri=veri.Memo

}başka{//beforeibc-gov5

metaveri=veri.Alıcı

}

[..]

//herhangi bir yönlendirme bilgisini ayrıştır

packageForwardMetadata,err:=types.ParsePacketMetadata(meta veri)

iferr!=sıfır{

dönüşkanaltipleri.NewErrorAcknowledgement(hata)

}

//Ayrıştırılan meta veri sıfırsa, bu, yönlendirme mantığı olmadığı anlamına gelir

//Paketi bir sonraki ara yazılıma geçir

ifpacketForwardMetadata==sıfır{

returnim.app.OnRecvPacket(ctx,paket,relayer)

}

//JSON metadata alanını bir alıcı adresiyle değiştirerek paket verilerini değiştirin

//paketin yığında devam etmesine izin vermek için

yeniVeri:=veri

newData.Receiver=packetForwardMetadata.Receiver

bz,err:=transfertypes.ModuleCdc.MarshalJSON(&newData)

iferr!=sıfır{

dönüşkanaltipleri.NewErrorAcknowledgement(hata)

}

yeniPaket := paket

newPacket.Data=bz

//yeni paketiönce orta donanım yığınından aşağı geçirin

ack:=im.app.OnRecvPacket(ctx,newPacket,relayer)

if!ack.Success(){

dönüş

}

autopilotParams:=im.keeper.GetParams(ctx)

//Aktarım başarılıysa, ilgili modüle yönlendir, varsa

switchroutingInfo:=packetForwardMetadata.RoutingInfo.(tür){

casetypes.StakeibcPacketMeta verileri:

[...]

casetypes.ClaimPacketMeta verileri:

//Eğer iddia yönlendirmesi etkin değilse (ancak paket yönlendirme bilgi bilgi notunu döndürür) bir hata hatası döndürür

[..]

im.keeper.Logger(ctx).Info(fmt.Sprintf("Forwaringpacketfrom%stoclaim",newData.Sender))

iferr:=im.keeper.TryUpdateAirdropClaim(ctx,newData,routingInfo);err!=nil{

im.keeper.Logger(ctx).Error(fmt.Sprintf("Errorupdatingairdropclaimfromautopilotfor%s:%s",newData.Sender,err.Error()))

dönüşkanaltipleri.NewErrorAcknowledgement(hata)

}

dönüş

varsayılan:

returnchanneltypes.NewErrorAcknowledgement(errorsmod.Wrapf(types.ErrUnsupportedAutopilotRoute,"%T",routingInfo))

}

}

Dahil edilen meta veriler, gelen aktarımın bir airdrop talebi olduğunu gösteriyorsa, modül TryUpdateAirdropClaim işlevini çağırır:

func(kKeeper)TryUpdateAirdropClaim(

ctxsdk.Bağlam,

datatransfertypes.FungibleTokenPacketData,

packageMetadatatypes.ClaimPacketMetadata,

)hata{

[..]

//alakalı adresleri topla

senderStrideAddress:=utils.ConvertAddressToStrideAddress(data.Sender)

ifsenderStrideAddress==""{

returnerrorsmod.Wrapf(sdkerrors.ErrInvalidAddress,fmt.Sprintf("invalidsenderaddress(%s)",data.Sender))

}

newStrideAddress:=packetMetadata.StrideAddress

//hava damlasını güncelle

airdropId:=packetMetadata.AirdropId

k.Logger(ctx).Info(fmt.Sprintf("airdropaddress%s(orig%s)to%sforairdrop%s güncelleniyor",

senderStrideAddress,data.Sender,newStrideAddress,airdropId))

returnk.claimKeeper.UpdateAirdropAddress(ctx,senderStrideAddress,newStrideAddress,airdropId)

}

İşlev, gönderen IBC paketinin adresini senderStrideAddress adlı bir Stride adresine dönüştürür ve airdropId ile yeni airdrop adresini newStrideAddress paket meta verisinden çıkarır. Ardından, senderStrideAddress ve airdropId kombinasyonunu yeni adresle eşleştiren açık bir ClaimRecord'u güncellemek için UpdateAirdropAddress'i çağırır.

ClaimRecord güncellemesiyle, newStrideAddress artık airdrop'u talep edebilir. Bu güncelleme mekanizmasının yalnızca IBC paketinde belirtilen gönderici adresi tarafından korunduğunu unutmamak önemlidir. Stride, airdrop güncellemelerinin gerçek alıcılar tarafından tetiklendiğinden emin olmak için başka herhangi bir doğrulama gerçekleştirmez.

Bunun neden ciddi bir güvenlik açığı olduğunu anlamak için blok zincirler arası iletişim protokolü olan IBC'ye daha yakından bakmamız gerekiyor.

IBC Güvenliği

IBC, hafif bir istemci tabanlı zincirler arası iletişim mekanizmasıdır. Klasik ağ protokollerine benzer şekilde, temel IBC modülü pek çok alt düzey ayrıntıyı soyutlayarak geliştiricilerin bunun üzerine kendi entegrasyonlarını kolayca oluşturmasına olanak tanır. IBC özellikli bir zinciri (Zincir A) başka bir IBC özellikli zincire (Zincir B) bağlamak biraz şuna benzer:

OluşturulansolomachineclientonIBCenabledchain[ClientID=06-solomachine-6]

Oluşturulantendermintclientonsolomachine[ClientID=07-tendermint-M48f]

IBCetkin zincirde başlatılmış bağlantı[ConnectionID=connection-4]

Solomakinede başlatılmış bağlantı[ConnectionID=bağlantı-Kinb]

IBCenabledchain'de onaylanan bağlantı[ConnectionID=connection-4]

Makinede onaylanan bağlantı[ConnectionID=bağlantı-Kinb]

InitializedchannelonIBCenabledchain[ChannelID=channel-0]

Başlatıldıchannelonsolomachine[ChannelID=channel-wwl6]

OnaylanmışkanalonIBCenabledchain[ChannelID=channel-0]

Onaylandıkanalonsolomachine[ChannelID=channel-wwl6]

Bağlantı kuruldu!

İlk adımda, zincir B'de A zincirinin bir IBC hafif istemcisi oluşturulur ve bunun tersi de geçerlidir IBC istemcisi, uzak zincirin durumunu izlemek ve doğrulamak için kullanılan istemci kimliğiyle benzersiz bir şekilde tanımlanır. İstemciler oluşturulduktan sonra, dört yönlü bir el sıkışma ile başlatılan bir bağlantı aracılığıyla bağlanabilirler. Bu, A zincirinde B zincirinin hafif istemcileriyle A zincirinde bir ConnectionEnd ve B'de A zincirinin hafif istemcileriyle B zincirinde bir tane daha oluşturur. Bağlantılar oluşturulduktan sonra kalıcıdır ve iki hafif istemci tarafından şifrelenir.

Bağlantılar üzerinden iletişim de farklı kanallara ayrılmıştır. Kanallar, temeldeki bağlantı ve kaynak ve hedef bağlantı noktaları tarafından tanımlanır. Her bağlantı noktası, IBC yoluyla bağlanan karşılık gelen zincirdeki bir modülü tanımlar. Bağlantı ile ilişkili ChannelEnd, her iki zincirde de oluşturulur ve kanal kimliği ile tanımlanır. Veriler artık kurulan kanal aracılığıyla iki zincir arasında aktarılabilir.

IBC'nin varsayılan olarak izinsiz bir protokol olduğunu unutmamak önemlidir. Bu, herkesin önceden izin veya onay almadan herhangi iki IBC özellikli zinciri bağlayabileceği anlamına gelir. Aslında, IBC sözde Solo Makineleri destekler [7] Standart, bir istemci bir blok zinciri değil, tek bir ana bilgisayarı veya makineyi temsil eder. IBC paket içeriği tamamen gönderici (tipik olarak kaynak zincirindeki kaynak modül) tarafından kontrol edildiğinden, gelen IBC paketlerinde ayrıcalıklı işlemler gerçekleştiren modüllerin her zaman mesajın güvenilir bir kanaldan geldiğini doğrulaması gerekir.

güvenlik açıkları

Ancak, Stride söz konusu olduğunda, x/autopilot modülünde kanal denetimi eksik. Kod, belirli bir gönderici adresine sahip ICS-20 IBC paketlerinin yalnızca bu adres üzerinde denetimi olan biri tarafından gönderilebileceğini varsayar. Bu, yalnızca EVMOS gibi güvenilir iş ortağı zincirlerindeki taşıma modüllerini düşünürsek doğrudur, ancak bir saldırgan, kontrolleri altındaki kötü niyetli bir IBC istemcisini kullanmak için tam kontrollü IBC paket verilerini gönderebilir. Bu güvenlik açığından yararlanmak nispeten basittir:

  1. Kötü amaçlı bir IBC istemcisi oluşturun
  2. Stride IBC aktarım modülüne bir IBC kanalı oluşturmak için kötü niyetli istemci Craft'ı kullanmak,
  3. Kimden alanı olarak sahipsiz ClaimRecords adresini kullanarak kötü amaçlı bir IBC aktarımı gönderin. Otomatik pilotu tetiklemek ve airdrop adresini saldırganın kontrolündeki bir Stride hesabına güncellemek için ClaimMetadata not alanını kullanın.
  4. MsgClaimFreeAmount'u x/claim modülüne göndererek airdrop'u çalın

Hata düzeltmeleri

Hızlı raporumuzu aldıktan sonra, Stride katılımcısı, hiçbir fonun risk altında olmadığından emin olmak için Airdrop bayi cüzdanındaki tüm fonları hızla geri çekti. IBC airdrop adresi güncelleme paketlerinin doğru güvenilir IBC kanalı üzerinden ulaşmasını sağlamak için uzun vadeli düzeltme uygulandı.

Sonuç olarak

IBC aracılığıyla çapraz zincir iletişim için güçlü destek, Cosmos ekosisteminin benzersiz bir avantajıdır. IBC sağlam kriptografik ilkeller üzerine inşa edilmiş olsa da, onunla güvenli bir şekilde bütünleşmek, temeldeki güven modelinin iyi anlaşılmasını gerektirir. IBC üzerine inşa eden geliştiriciler ve IBC entegrasyonlarını inceleyen güvenlik mühendisleri, kötü niyetli IBC istemcilerine veya kanallarına maruz kalan saldırı yüzeyini dikkatlice incelemelidir. Stride'a katkıda bulunanlara profesyonel yaklaşımları ve bu soruna hızlı yanıt verdikleri için teşekkür ederiz.

WeChat Harici Bağlantı

[1] Orijinal bağlantı adresi:

[2] x/iddia:

[3] LoadAllocationData:

[4] Talep Kaydı:

[5] MsgClaimFreeAmount:

[6] x/otomatik pilot:

[7] Yalnız Makineler:

View Original
The content is for reference only, not a solicitation or offer. No investment, tax, or legal advice provided. See Disclaimer for more risks disclosure.
  • Reward
  • Comment
  • Share
Comment
0/400
No comments
  • Pin
Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate app
Community
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)