Jak sprytny gracz okradł bitcoinowe kasyno internetowe na milion dolarów

dodał 30 czerwca 2015 o 11:52 w kategorii Wpadki  z tagami:
Jak sprytny gracz okradł bitcoinowe kasyno internetowe na milion dolarów

Graliście kiedyś w internetowym kasynie? Stara zasada mówi, że kasyno – internetowe czy zwykłe – zawsze wygrywa. Ten gracz znalazł jednak sposób na pokonanie kasyna – a wszystko przez dość prosty błąd programistów.

Primedice to jedno z największych i najpopularniejszych internetowych kasyn, w których można grać za bitcoiny. Obdarzone zaufaniem przez tysiące użytkowników, korzysta z przejrzystego mechanizmu zapewniającego uczciwość kasyna i możliwość jej weryfikacji przez użytkownika. Jednemu z graczy udało się jednak oszukać mechanizm losowania i ograć kasyno na około milion dolarów.

Skąd wiem, że kasyno mnie nie oszukało

By opisać mechanizm oszustwa gracza trzeba zacząć od opisania sposobu rozgrywki w internetowych kasynach. Jeśli wiecie, jak generowane są losowe wartości i skąd gracz wie, że kasyno go nie oszukało – możecie przejść do kolejnego rozdziału. Pozostałych Czytelników zapraszamy na krótką wycieczkę do świata hazardu.

Gracze w ruletkę widzą, jak kulka przeskakuje po kolejnych polach. Gracze w karty widzą, jak krupier otwiera i rozdaje świeżą talię. Gracze w kasynach internetowych, gdzie o wyniku gry decyduje komputer, też potrzebują możliwości weryfikacji uczciwości gry. Z pomocą przychodzi prosty, ale sprytny algorytm.

Dla potrzeb wyjaśnienia mechanizmu weryfikacji uczciwości gry w kasynie przyjmijmy założenie, że gracz stawia jednego bitcoina w podstawowej grze 2x. Polega ona na tym, że komputer wylosuje wartość z przedziału od 0,00 do 99,99 i jeśli ta wartość będzie mniejsza od 49,50, to gracz wygra bitcoina, a jeśli wartość będzie równa lub większa 49,50, to gracz traci bitcoina.

Ekran z zakładem

Ekran z zakładem

Próg wygranej na poziomie 49,50 oznacza, że kasyno zawsze wygrywa w dłuższym terminie – 1% brakujący do 100 to przychód Primedice. Jak jednak obliczana jest najważniejsza wartość, czyli wynik losowania? Poniższe wyjaśnienie oparte jest na publikacji serwisu dicesites.com.

Proces obliczeń opiera się na trzech wartościach – losowym ciągu znaków dostarczonym przez serwer, ciągu znaków dostarczonym przez użytkownika oraz liczniku kolejnych gier. Na przykład mogą one wyglądać tak:

Losowy ciąg serwera: 293d5d2ddd365f54759283a8097ab2640cbe6f8864adc2b1b31e65c14c999f04
Ciąg użytkownika: ClientSeedForDiceSites.com
Licznik: 0 (to pierwsza gra z tym zestawem danych)

Następnie serwer oblicza kod uwierzytelniający wiadomość z wmieszanym kluczem tajnym (HMAC, w uproszczeniu rodzaj rozszerzonej funkcji skrótu)

hmac-sha512(293d5d2ddd365f54759283a8097ab2640cbe6f8864adc2b1b31e65c14c999f04, ClientSeedForDiceSites.com-0)

a w wyniku tej operacji otrzymuje długi ciąg znaków

aa671aad5e4565ebffb8dc5c185e4d[.....]8f6ca2

W kolejnym kroku serwer bierze pierwsze 5 znaków i przelicza je z zapisu szesnastkowego na dziesiętny

aa671 HEX = 697969 DEC

Jeśli otrzymana wartość przekracza 999 999, to algorytm bierze kolejne pięć znaków. Jeśli wartość jest mniejsza lub równa 999 999, to serwer bierze 4 cyfry z prawej i powstałą liczbę dzieli przez 100 – i jest to wynik losowania.

(697169 modulo 10 000) / 100 = 71,69

Wartość przekracza 49,5, zatem gracz przegrał. W kolejnym losowaniu zmianie ulega wartość licznika, co powoduje całkowitą zmianę wylosowanej wartości.

Jak ten algorytm gwarantuje uczciwość? Podczas rozgrywki gracz nie może znać wartości wylosowanej przez serwer, ponieważ mógłby wtedy szybko obliczyć czy wygra, czy przegra i na tej podstawie pokonać kasyno. Zamiast zatem ogłaszać wartość serwera dla tego gracza, kasyno podaje mu jedynie wynik funkcji skrótu (hash) dla tej wartości. Gdy gracz postanawia wygenerować nową wartość po stronie serwera, serwer pokazuje mu wartość poprzednią. Wtedy gracz może sprawdzić, czy hash, który otrzymał, zgadza się z samą wartością a także znając wartość serwera oraz swoją policzyć, czy wyniki wcześniejszych losowań były prawidłowe.

Gra pozostaje sprawiedliwa i weryfikowalna post factum tak długo, jak gracz nie zna wartości przypisanej do danej sesji przez serwer. Jak zatem wyglądał atak, który przyniósł tajemniczemu graczowi milion dolarów?

Najszczęśliwszy gracz świata

W sierpniu 2014 serwis Primedice uruchomił nową, trzecią już wersję swojej platformy. Ze względu na presję czasu platforma była testowana zaledwie przez tydzień zanim trafiła w ręce użytkowników. Natychmiast po jej uruchomieniu dwóch graczy, pod pseudonimami Nappa oraz Kane, zaczęło regularnie wygrywać zakłady z kasynem. Kane wypłacił swoje zyski automatycznie, z kolei sprawa Nappy była już analizowana przez zespół serwisu. Programiści nie dopatrzyli się jednak żadnych oznak nieprawidłowości i choć fala zwycięstw wyglądała podejrzanie, to wygrane również wypłacono.

Po kilku tygodniach przerwy pojawił się gracz Hufflepuff, który obstawiał zakłady w ilościach i wartościach jakich serwis wcześniej nie widział. Gracz przez wiele godzin stawiał co sekundę 12 bitcoinów w zakładach x3 (jeśli system wylosuje wartość poniżej 0,33 nagroda wynosi dwukrotność zakładu) i choć regularnie przegrywał, to jeszcze bardziej regularnie wygrywał, z poziomem szczęścia o ok. 4% większym, niż zakładał to algorytm serwisu.

Obsługa serwisu cały czas szukała problemu, lecz nie była go w stanie zlokalizować. Początkowo wstrzymała wypłaty, jednak wierząc, że system działa prawidłowo i lada moment szczęśliwy gracz zacznie tracić pieniądze, odblokowała je i czekała na rozwój wypadków. Tymczasem Hufflepuff zarobił ponad 2000 bitcoinów i nie zanosiło się na to, że je wkrótce straci. Dwa dni później główny programista odkrył sztuczkę złodzieja.

Wyścig po bitcoiny

Hufflepuff użył prostej sztuczki – tzw. race condition, czyli sytuacji, w której serwer nie potrafi prawidłowo obsłużyć wielu żądań od klienta otrzymanych w krótkim przedziale czasu. W ten sposób można np. wysyłając setki lub tysiące żądań do serwera w ciągu sekundy 10 razy zrealizować ten sam kupon rabatowy. W przypadku Primedice gracz tak bombardował żądaniami serwer gry, że w bazie jednocześnie potrafiły znajdować się przypisane do jego konta te same losowe ciągi uznawane za aktywne i uznawane za nieaktywne. Dzięki temu gracz mógł poznać w trakcie gry losowy ciąg wygenerowany przez serwer i dodając do niego swój własny ciąg oraz numer losowania obliczyć szanse na wygraną. Był to ewidentny błąd programisty – system nie powinien nigdy pozwolić na to, by gracz w trakcie gry mógł poznać losowy ciąg serwera.

Gdy obsługa serwisu skontaktowała się z graczem z prośbą, by ten oddał ponad 2400 zarobionych nieuczciwie bitcoinów (wartych wówczas około miliona dolarów), ten założył konto Robbinhood i wykorzystując fakt, że programiści serwisu nieudolnie załatali problem, wygrał jeszcze 2000 bitcoinów, lecz zdążył wypłacić 60, ponieważ tylko tyle było w gorącym portfelu. Następnie w wiadomości do serwisu wyśmiał jego obsługę i zaproponował, by każdy udał się w swoją stronę i nie wracał więcej do tematu. Primedice podało do publicznej wiadomości adresy IP, adresy email oraz adresy portfeli BTC oszusta, jednak raczej nic nie wskazuje na to, by zanosiło się na jego złapanie.

Największym naszym zaskoczenie jest to, że prowadzący kasyno uwierzył w to, że jeden z jego klientów ma o 4% więcej szczęścia niż pozostałe tysiące. A można było zainwestować ułamek straconej kwoty w profesjonalny audyt serwisu…