Resmi olmayan müşterileri ağ oyunlarında engelleme teknikleri?


22

Çok oyunculu ağ oyunlarında, kullanıcıların resmi müşteri uygulamasıyla bağlantı kurmasını sağlamak için bazı teknikler hacklenmemiş istemci uygulamasıyla bağlantı kurmalarını sağlamak için hangi teknikler mevcut?

Bunu yapmanın kesin bir yolu olmadığının farkındayım, bunun yerine sorunu hafifletmek için kullanılabilecek tekniklerle ilgileniyorum.

Özellikle web tabanlı oyunlar için kullanılabilecek herhangi bir teknikle ilgileniyorum, ancak çoğunun genel olarak uygulanabileceğini tahmin ediyorum.

Teşekkür ederim!


Bazıları genelleştirilmiş bulut oyunlarının köşede olduğuna inanıyor. Bu soruyu tamamen çözüyor.
Laurent Couvidou

Yanıtlar:


13

Bu ilginç bir problem, ama bence yanlış soruyu burada soruyorsun. Saldırıya uğramış müşteri yaklaşımını tespit etmekten başlayalım:

Müşteriniz kullanıcının tarafında yürütülürse, kodunuzla ne isterse yapabilir (kendisi için çok karmaşık olana kadar, ancak her zaman satırda daha akıllı biri olacaktır). Müşteri ile sunucu arasında mesajların şifrelenmesini şifrelemek, müşteri sertifikaları oluşturmak, hatta müşterinin sağlama toplamını hesaplayabilmesini sağlamak için yapabileceğiniz her şey, ayrıştırılabilir ve kırılabilir. Bir dongle ile gelen bir yazılım gördüm, bu dongle uygulamanın kodunun bir parçasıydı, ancak onu çalıştırabilmek için, dongle uygulamasının ilk crc'sini kontrol etmediyse tabii ki temperlenmediyse .. tabi ki dongle hacklendikten sonra ayrıca .. artı bir yazılım güncellemesi yaparsanız, dongle'ı tekrar göndermeniz gerekir.

Buna ek olarak, kullanıcı hile yapmak için kendi istemcinizi kullanabilir - örneğin fare hareketini ve tıklamaları taklit ederek.

Öyleyse soru şu - bir bot oyuncusu nasıl tespit edilir?

Burada birkaç seçeneğiniz var - tıklamalar arasındaki süreyi ölçmek, fare hareketlerinin hızını ölçmek - fare tam olarak A noktasından B noktasına sayısız kez hareket ediyor ve aynı kodlayıcılara çarpıyor mu? Kullanıcı hareketi tekrarlanabilir mi? Hangi kullanıcının topladığı kaynak tükenirse, kullanıcı başka bir eyleme geçiyor mu veya saatlerce yerinde bekler mi? Günün sonunda kalıpları tanıma kodunu yazıyorsunuz.


4
Bot kontrol teknikleriniz, bot aksiyonunun etrafına biraz gürültü ekleyerek dakikalar içerisinde yenilebilir.
As

Buna + 1; Önlemenin imkansız olduğu düşünülürse (ve eğer birisi gerçekten belirlenirse, sürücülerini hack edecek kadar ileri gidebilirlerdi, ki bu gerçeğin altını çizmeliler) odak noktanız kesinlikle bunun üzerinde olmalıdır. Ayrıca, bir oyun etrafında toplanabilecek makul bir topluluğun muhtemelen polislik yapmasıyla sonuçlanacağını da eklerim, böylece buna yardımcı olacak araçlar sağlamak için bazı çalışmalar yapabilirsiniz.
Maximus Minimus 9:12

2
Programatik önleme tek başına imkansızdır, bu yüzden WoW gibi oyunların insanları tekrarlayan şeyler yapan ve insan olduklarını ispatlayacak sorular soran tonlarca yöneticisine sahip olmasının nedeni budur.
DampeS8N

1
@AsTeR Bunlar doğru yöne itmek için bazı fikirlerdi. Bu problemi daha derinlemesine ele alan çok sayıda makale ve sunum var, örneğin bunun gibi: iis.sinica.edu.tw/~swc/pub/bot_trajectory.html
Kamil

5
“Öyleyse soru şu olmalı - bir bot oyuncusu nasıl tespit edilir?” Kabul etmiyorum, bir bot olmadan hile yapmanın birçok yolu vardır. Örneğin, müşterinin fazla bilgi almasına veya müşteriye güvenmesine izin vermek.
Matsemann

9

Çok oyunculu ağ oyunlarında, kullanıcıların resmi müşteri uygulamasıyla bağlantı kurmasını sağlamak için bazı teknikler hacklenmemiş istemci uygulamasıyla bağlantı kurmalarını sağlamak için hangi teknikler mevcut?

Buna yaklaşmanın doğru yol olduğunu ya da en azından ilgilenmen gereken tek şey olduğunu sanmıyorum.

  1. Her müşteriye yalnızca müşteriye özel bilgiler gönderdiğinizden emin olun (örneğin bir müşterinin örneğin bir canavara ne düşebileceğini bilmesi gerekmez, sadece öldürdükten sonra bilgileri gönderin, ve yalnızca belirtilen istemcilere gönderin)

  2. Sunucu tarafında yapılan hesaplamaların çoğunu yapın (konumlandırma vb.). Müşteri kendi hesaplamalarını yapıyor ancak ANCAK asla kendi değerlerini yalnızca eylemlerini gönderemiyor. Sunucu, bu işlemin geçerli olup olmadığını ve oyunu nasıl etkileyeceğini kontrol etmek zorundadır.

  3. 1 ve 2 genellikle tahminlerle birleştirilir. İstemci ve sunucu belirli davranışları tahmin etmeye çalışır. Örneğin müşteri oynatıcıyı hareket ettirir, ancak her x saniyede veya ms. sunucu tarafından bir düzeltme alır

  4. Kullanıcıları müşterileri için değil, hesapları için ücretlendirin, bu şekilde bir kullanıcı çatlak bir sürümü ele geçirebilir ancak bir hesap olmadan oynayamaz.

2 ile para, pozisyon veya duvar korsanları vs. olmadığından emin olabilirsiniz ancak botlar birçok şirket için her zaman bir problem olmuştur. Blizzard gibi büyük şirket isimleri bile bununla sorun yaşıyor. Yapabileceğiniz şey, hesap başına oynanabilir süreyi sınırlamak, böylece bir kimse ayda 540 saatten fazla çevrimiçi olamayacak. XP yetiştirmek için canavarların renk değerlerini + fare girişini kullanan bir botu hatırlıyorum. Başka bir yol, çalışan diğer uygulamaları ve hafıza erişimini kontrol eden ek bir program sağlamak olabilir, ancak bu, yeni sorunlara bir avuç getiriyor.

Düzenle:

Yeni başlayanlar için çok iyi yazılmış makaleler: http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/


Evet, ilgilenmemiz gereken tek şey olmadığını kabul ediyorum. Bunların çoğunu şimdiden yapıyoruz, ancak müşteri tarafında bazı açık elemanlar kaçınılmaz.
UpTheCreek

@UpTheCreek En çok neyle ilgilendiğinizi söyleyebilir misiniz? Botlar, verileri değiştirerek, müşteriye ya da müşteriden korunması gereken ne tür bilgiler gönderilir. Zaten bir müşterinin güvenliğini sağladığını farkettiğin için kolay bir iş değil, ama endişelerinin kökenine giderek sana daha iyi yardımcı olabiliriz.

Bizim için, sunucu tarafı kontrollerini / simülasyonunu sunucu maliyetleriyle dengeleme durumudur. İstediğimiz her şeyi dahil edemiyoruz. Bunun hakkında çok düşündüm, ancak müşteriyi daha iyi koruyacak ustaca hileler olup olmadığını görmek istedim :) Müşteri javascript temelli, bu yüzden kullanıcıların bilgisayar korsanlarının normalden daha kolay olduğunu hayal edebilirsiniz. !
UpTheCreek

4

“Resmi müşterinin” çalıştığını garanti etmek için kusursuz bir yol yoktur; bu tür herhangi bir mekanizma, yeterli zaman verildiğinde tersine mühendislikle geri döndürülebilen sunucuya bir tür "sır" geri ileten doğrulama koduna dayanacaktır. Temel olarak, bilgisayar korsanlığı önleme yazılımı, istemciye Tamam olduğunu bildirdiğinde ne olur.

Düzenleme: Yukarıdakileri biraz detaylandırmak için müşteri tarafını doğrulayan kodu düşünün. İki çok zor işi var: orijinal kodun kullanıldığını kontrol etmek (ve orijinal kodu dinamik olarak / çalışma zamanında (!) Engelleyebilecek başka hiçbir şey mevcut değil) ve bu sonucu sunucuya bu şekilde iletmek Bu iletişim sahte olamaz. İlk kısım delicesine zor olsa da, ikinci kısım düpedüz mümkün değildir.

Hem istemciyi hem de sunucuyu düzenli olarak güncelleyebilirseniz, krakerlerin yetişmesini zorlaştırma umuduyla sırrı düzenli olarak devre dışı bırakabilirsiniz. Ancak, her durumda, sırrın kodlanma / uygulama şeklini değiştirmediğiniz sürece, yine çok hızlı bir şekilde kırılabilir. Yani, temelde, siz ve kim onu ​​çatlamak isteyenler arasındaki bir silahlanma yarışıdır - soruna atmak için daha fazla zamanı ve parası olan.

Bu kısmı kabul ettikten sonra yapabileceğimiz başka bir şey var mı? Mükemmel bir dünyada, sınırsız bilgi işlem gücü ve bant genişliği ile, müşteri ile sunucu arasında durumu sürekli olarak transfer edebilirsiniz ve sunucunun, müşteride olan bitenin mükemmel bir simülasyonunu çalıştırmasını sağlayabilirsiniz. Bu model daha sonra müşterinin iddia ettiğini iddia ettiği eylemleri doğrulamak için kullanılabilir. Bu, bir insanın mı yoksa bir botun mu oynadığını tespit etmeyecek, ancak müşterinin bir duvardan mı yoksa başka bir akla gelebilecek bir eylemden mi geçtiğini iddia edip etmediğini doğrulayabilecektir.

Sunucuda yeterli veriye sahip olmak aynı zamanda düzensiz davranışları saptamanın ilk adımıdır - bunun belki de insanlar için çok hızlı olmasını amaçlamaktır. birçok durum.


+1. Buraya sık sık sırrı değiştirme fikrinden bahsetmeye geldim, bu hackerların çalışmalarını tekrarlamaları gerektiği anlamına geliyor. Karmaşık sırlar daha da iyi hale gelirdi, örneğin. Sunucunun ne gönderdiğine bağlı olarak değişen
Kylotan

4

Oyunun türünü belirtmezsiniz, bu yüzden yoğun olarak RPG / MMO oyunlarına yaslanacağım. Fakat bunun bir çoğu FPS, Strateji ve Aksiyon oyunları için geçerli olabilir. Blizzard gibi büyük çok oyunculu oyun şirketlerinin oyunlarında bu sorunla uğraşması:

  1. Tüm hesaplama ve oyun eylemlerini sunucu tarafında yapın, istemci sadece aptal bir terminal ve grafik motorudur. Eğer oyuncular farklı bir müşteri kullanıyorlarsa, oyun açısından gerçekten önemi yoktur, oyunun fiziğini aldatmazlar.
  2. Tıklama olaylarının ve fare hareketlerinin mükemmel tekrarı gibi açık bilgisayar eylemlerini arayarak açık bot programlarını / istemcilerini denetler.
  3. Açıkça görülmeyen bot programlarını / istemcileri denetler ve oyundaki moderatörleri konuyla ilgili uyarır.

Daha sonra oyunda görünürler (eğer mümkünse, Starcraft 2 gibi aynı oyunlar için değildir) veya başka bir şekilde oyuncu ile 'insan kontrolü' olarak yaptıkları eylemleri izleyin. Ya da en azından böyle yapılması gerekiyor. Blizzard bu konuda oldukça iyi, ancak tarihsel olarak diğer MMO şirketleri olmadı.

Belirgin olmayan botları kontrol etmek kolay değildir, ancak uyulması gereken birkaç temel kural

  • Sadece hafif bir değişiklikle tekrar tekrar aynı işlemleri yapan oyuncuları aramak. Bu, bir MMO'daki bir kaynak düğümünde oturuyor olabilir ve yeniden doğduğunda tarım yapıyor olabilir veya FPS'deki sağlık / cephane paketleri arasındaki çevrelerde çalışıyor ve hiçbir zaman belirli bir yoldan sapmıyor ve her zaman aynı silahı kullanıyor olabilir. (FPS'lerdeki alt-optimal botlar nadirdir, ancak oyununuzda bazı modern FPS'ler gibi oyuncunun yeteneğinin önemli olduğu yerlerde oyunların sayısının daha önemli olduğu bir merdiven çıkması durumunda, botlar tekrar değerli hale gelir)
  • Bir RTS'de aynı acele veya stratejiyi tekrar tekrar yürüten oyuncuları aramak. Starcraft'ta bir bot tarafından gerçekleştirildiğinde neredeyse rakipsiz olabilen belirli yapım siparişleri var.
  • Çok büyük miktarda kaynak toplayan ve artık hiç bitmeden bir öğeyi öğüten oyuncuları aramak. Bu Ultima Online'da büyük bir problemdi.

Sorun şu ki, oyununuz ne kadar popülerse ve oyunda ne kadar verimli botlar oyundaki tediyumu azaltıyorsa, insanların bu botları kullanması ve yaratması o kadar fazla olacaktır. Ve fare hareket hızını kısıtlamak, tıklamalara rastgele insancıl bir varyasyon eklemek, hatta botun insan hızında hatalar yapması, menü parçalarını açıp kapatması, yanlış düğmeye basması ve ardından pencereyi kapatması, klavye ve klavye arasında geçiş yapmak çok önemlidir. insanlar gibi fare çalışması, el yorgunluğunu azaltmak için yapar. (yaptığını bile bilmiyorsun)

Birisi veya bir botun çok uzun süre tekrarlayan bir şey yaptığı son adım, gerçekten oyuncuya gelen ve onlarla konuşan insan bir mod olmalı. Oradalarsa ve insan cevaplarıyla cevap veriyorlarsa, onlar insandır. Tipik olarak, modlar oyuncudan bir süre durmasını ya da bir yerden onları takip etmesini ve bazı diğer eylemleri gerçekleştirmesini ister, çemberler zamanla daha karmaşık hale gelir.

Tanget

Tabii ki, sonunda birileri Turing testini geçerek gerçek bir kişiden ayırt edilemez bir bot yaratacaktır. Ve sadece bunu yapmayı amaçlayan çok sayıda bot yazar var.

Programlamaya ilk başladığımda ve Ultima Online için kasabada duracak ve NPC'leri taklit edecek işe yaramaz botlar yarattığım zaman kendimi çok etkilemişim. Komutlar süper basitti, kolay yapılıyorlardı, sadece farklı yönlere adım atmak için tuşa basıyorlardı ve sohbet günlüğünü kendi adlarıyla izliyorlar ve mesajları AI'nin bir web sürümü üzerinden ALICE'a aktarıyorlardı . Hangisini hatırlamıyorum ve muhtemelen artık yok.

/Teğet

Demek istediğim, çizgiyi nereye çekeceğine karar vermen gerekiyor. Eğer sisteminizin bot olarak tanımladığı insanlarla konuşmak için bir moderatörler ordusunun parasını ödeyemiyorsanız, topluluğun insanları bot olarak işaretlemesine izin vererek, zaman içinde yeterince zaman yaptığında, oyuncuyu yaklaşık bir saat boyunca tekmelemek daha iyi olacaktır. Yasak değil, sadece tekme at. Çoğu oyuncu için asıl sorun, botların diğer insan oyuncuların kullanabileceği domuz kaynaklarını oluşturmasıdır. Çetelerin kıt olması durumunda, Ragnarok Online'da olduğu gibi, o zaman etrafta dolaşan ve tüm düşmanlık alanlarını temizleyen ve eşyaları toplarken (veya değil) ortak olan botlar yaygındır ve diğer insanlar için oyunu mahvederler. Böylece yönetici ordularının maliyetini bu şekilde artırabilirsiniz.

Son olarak, oyun alanınızın gerçekliği olarak botlarla yaşayabilir ve kullanımlarını teşvik edebilirsiniz. Bu, oyununuzu botların, eğiticilerin ve yardımcı programların nihai ve ortak kullanımı etrafında tasarlamayı gerektirir. 10 yıl önce bunu yapan bir MMO olduğunu söylemek istiyorum, ama hangisinin olduğunu hatırlayamıyorum. Oyunun sonunu heceledi, çünkü MMO'lar çok sert ve oyuncuların% 95'i herhangi bir zamanda klavyelerinden uzak tutup toplumu mahvettiğimiz anlamına geliyordu. Bu rotaya giderseniz, dikkatli olun.


3
Son paragrafınızda, SOE'nin Yıldız Savaşları Galaksileri, oldukça sağlam bir oyun içi komut dosyası / makro dili olan bir MMO örneğiydi, ancak çok fazla bot sorunu yoktu. Bunun sona ermesi, daha sıkıcı oyun içi ihtiyaçların bazılarının komut dosyası olarak yazılmasının (örneğin, çoğu starport'un tam otomatik bir şifreleme patlatma botunun önünde bir oyuncu sırasına sahip olması) ve düşük seviyeli XP taşlama genellikle bu şekilde yapıldı. çok. IMO, bunların hepsini oyuna ekledi, onu öldüren şey, inanılmaz derecede kötü kararlar ve oyun değişimleriydi, çok az ikaz ya da iletişim yoktu.
GAThrawn

3

Özellikle tarayıcı benzeri oyunlarda, tekrarlayan görevler yaparak kullanıcının kazanabileceği oyun özelliklerine sahip olmaktan kaçının . tekrarlayan görevlere neden olan oyun özellikleri yalnızca diğer kullanıcıların öfkelenmesine neden olmaz, çünkü onları yapacak zamanları yoktur, ama aynı zamanda oyunu çok daha kolay oynanabilir hale getirir (ve çok daha az eğlenceli!)

Belirli bir oyun özelliği botable olabilir, neden yine de oyunda bu özelliği var? Bu özellik açıkça bir bot oluşturmak için kullanıcıyı çağırıyor.

Oyunun, oyuncuya normalde önemsiz olmayan seçimlerle makul miktarda eğlence verilmesiyle oynanması amaçlanmıştır. Önemsiz olmayan seçeneklerle yüzleşmeye karar verme yeteneği bir insanı bottan ayırır. Sonuçta, bot aramak yerine, bir botun uygulanabileceği oyununuzu araştırın ve herkes tarafından kullanılmak üzere sizi kendiniz uygulayın. Bunu yaparak, kökündeki botlarla savaşırken sıkıcı görevler yapmaktan kaçınarak bir oyun oyuncusuna zaman kazandırır: Eğer botable oyun özellikleri yoksa, botlar nasıl olabilir?

Sonuç olarak: Bir oyunun botable olmaması için gereken asgari karmaşıklık miktarında bir eşik olduğunu söyleyebilirim. Sonunda kullanıcı deneyimini artıracak önemsiz seçimler ekleyerek oyununuzu bu eşiğin üzerinde yapın.

Her neyse, belki bu paradigma bugünlerde geçerli değildir ... ama yine de iyi bir oyun yapan şeyin bu olduğuna inanıyorum.


1
+1 Hile yapmanın tek etkili yolu, oyunu ilk önce hile yapmanın etkili olmayacağı şekilde tasarlamaktır.
API-Beast


2

Var olan cevaplar zaten iyi, ancak çeklerinizin pahalı olması durumunda (ör: müşterinin hile yapmadığından emin olmak için oyun sunucusunun tamamını çalıştırmak), yalnızca bazılarını yapmayı seçebilirsiniz . zaman .

Örneğin, yalnızca belirli bir bölgedeki veya belirli oyuncular tarafından yapılan eylemleri kontrol edebilir (bir süre sonra rasgele değişen) veya yalnızca bir eylemler sırasına sahip olabilir ve hangilerini doğrulayacaklarını (ve diğerlerini yok sayarlar) rasgele seçebilirsin. Belki de aldatma olasılığı yüksek olan (temel olarak en başarılı olanları arayın) ve sunucudaki eylemlerini onaylayan bir buluşsal buluşma ortaya çıkar.

Sunucunun eylemleri doğrularken ve yapmadığında pes etmediğinden emin olun. Her zaman harekete geçmeye hazır olana kadar standart yanıtınızı gönderin (ve onaylarken ve yapmadığınızda bir yanıt göndermek için daha uzun süre vererek bunu bırakmayın).

Bu şekilde, yalnızca yedekleyebileceğiniz sunucu gücünü kullanarak aldatmalara karşı oldukça iyi bir koruma elde edebilirsiniz (her ne kadar her eylemi onaylamak için daha açık olsanız da, aldatmaya karşı daha iyi koruma sağlarsınız).


1

Şey, bir "Ultiamte-kirliliği" olduğunu sanmıyorum. Veri Paketlerini kodlayabilir ve paketleri alan kuralları sunucuya verebilirsiniz. Örneğin, en büyük gerçekçi / izin verilen hareketin +1 olduğunu ve daha hızlı olması için 5 veya daha yükseğe ayarlayacak bir dolandırıcı / bilgisayar korsanı gibi olmadığını ayarlayabilirsiniz. Sadece bir bilgisayar korsanının diğer oyunculardan daha iyi olmak için neler yapabileceğini düşünün ve bunun için kurallar koyun.


0

En basit yöntem, özünde müşteriyi aptal bir terminal yapmaktır. Her şey sunucuda yapılır ve istemci sadece sunucuya komutları gönderir. Bu şekilde sunucu her şeyin kontrolünü tamamen elinde tutar.

Ancak bu muhtemelen sizin için en uygun durum değildir, çünkü sunucunun daha fazla hesaplama yapması gerekir ve kullanıcı deneyimi caydırıcı olacaktır. Bu nedenle, müşteriye ne kadar çok mantık sergileyecek olursanız, kullanıcı deneyimi o kadar iyi olur, ancak daha az güvenlik vardır. Yani sizin için kabul edilebilir bir orta yol bulmanız gerekecek.

Ayrıca, müşteriye yalnızca bilmesi gerekenleri gönderin. Örneğin, bir düşman oyuncu bir duvarın arkasındaysa, bu bilgiyi bir müşteriye göndermeyin, yoksa saldırıya uğramış bir müşteri bu bilgiyi ayırt edebilir (okuma: duvar kepçesi).


-1

DÜZENLE: Ben soruyu yanlış anladım. "Oyuncu için 1 milyar altın üretecek bir mesaj gönderebilecek hack yazılımı" yerine "korsan / hack anahtarını engelle" olarak yorumladım.

Günümüzde çoğu oyun bir veritabanındaki bir hesaba bağlı bir değere sahiptir çünkü bir müşterinin bir sunucuya gönderebileceği herhangi bir şey değiştirilebilir. Bu muhtemelen en basit ve en etkili yöntemdir.

Yüksek hızlı internet ve P2P dosya transferi yaygınlığı ile şirketler, yerel olarak müşteride depolanan cd anahtarlarından sunucularındaki bir hesaba bağlı anahtarlara geçtiler. Herhangi birileri müşteriyi indirebildiğinden, "resmi" veya "resmi olmayan" istemci yazılımı yoktur. Ancak, yalnızca oyuna erişimi olan bir hesabınız varsa oynayabilirsiniz.

Yazılımın fiziksel kopyalarını üretmek için harcama yapmak zorunda olmadıkları için bunun şirkete yararı da var.


Sana oy veren ben değildim, ama bana göre bu gerçekten bir koruma sağlamıyor. Sadece yetkili kullanıcıların bağlantı kurmasına izin vermekten bahsediyor gibisiniz - kolayca anlaşılabilir. Fakat sorun şu ki, geçerli bir hesabı olan birini mesajlaşmayı tersine çeviren ve kendi saldırıya uğramış müşterimi yazmayı durduracak hiçbir şey olmayacaktı.
UpCreek

-1 bu soruyu yanıtlamaz, çevrimiçi bir hesaba sahip olmak birinin oyun içi eylemleri otomatikleştiren, saldırıya uğramış bir müşteriyle bağlantı kurmasını engellemez. vay tamamen çevrimiçi tabanlı ve hala sürekli saldırıya uğradı. Bu kar fırtınasını önlemek için, söz konusu sorunla başa çıkmanın bir örneği olan "garip" dolandırıcılık karşıtı yazılımlarını kullanıyor
dreta

Arg, haklısın. Soruyu yanlış anladım.
Orin MacGregor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.