W ramach naszej witryny stosujemy pliki cookies zgodnie z Polityką Cookie. Zasady przechowywania lub dostępu plików cookie możesz zmienić w swojej przeglądarce.
X

mywebcases
.com



Blog

Geekowy blog o łamigłówkach, JavaScript i wszystkim, co ciekawe.

Przykład 1: Speedy Gonzales the GAME!

Cheat Champ - Cheat -
napisał Jakub Caban

Zgodnie z obietnicą dzisiaj coś złamiemy. Będzie to prosta gra z wieloma dziurami - w sam raz na rozgrzewkę.

 Panie i Panowie, pozwólcie mi przedstawić Speedy Gonzales the GAME!:

sg
Speedy Gonzales the GAME!

Na czym polega ta gra? Można sobie to wyobrazić tak, że zadanie zwykłego ("uczciwego") gracza polega na kliknięciu start, a następnie kliknięciu w czerwony kwadrat latający po ekranie. Próbowałem parę razy i nie bardzo mi się to udawało, więc nie można powiedzieć, że jest to gra łatwa...

Jest za to łatwa do złamania i niektórzy mogą uznać, że zajmuję się dziś rzeczami zbyt prostymi. Ale zapewniam, że nawet już techniki dziś opisane wystarczają do złamania wielu aplikacji. Niestety...

Co w trawie piszczy?

Czyli zaczynamy inspekcję gry. Ponieważ aplikacja ma charakter typowo szkoleniowy nie mamy tu regulaminu ani listy wyników, nic też nie możemy wygrać. Dlatego dzisiaj pozwolę sobie pominąć wszelkie kroki przygotowawcze opisywane wcześniej i przejść do rzeczy.

Warto przynajmniej raz spróbować zagrać normalnie, żeby zobaczyć, jak gra działa oraz jakie informacje wysyłane są i odbierane z serwera. W tym celu odpalamy Firebuga, wchodzimy w zakładkę "Console", zaznaczamy "Persistent" (nie jest w tym przykładzie potrzebne, ale wyrabiajmy dobre nawyki) i... Gramy!

Po udanej grze i rozwinięciu wszystkich opcji zobaczymy coś w tym rodzaju:

Zapytania wysłane
Zapytania wysłane
Odpowiedzi z serwerra
Odpowiedzi z serwera

Jak to czytać? Przede wszystkim - w czasie gry wysłane zostały 2 zapytania do serwera. Oba do pliku "case1.php", z różnymi parametrami. Tutaj rzuca się w oczy fakt, że parametry "action" oraz "time" są wysyłane w obu przypadkach. Nie trudno się domyślić, iż wartość "action=start" informuje o rozpoczęciu gry, a "action=end" o zakończeniu. Dodatkowo parametr "time" w pierwszym przypadku wygląda na znacznik czasu rozpoczęcia gry, natomiast w przypadku zakończenia jest to czas użyty do kliknięcia kwadratu. Pozostaje tajemniczy parametr "code"...

Tu z pomocą przychodzi podzakładka "JSON", przedstawiająca odpowiedź z serwera. Możemy zauważyć, że przy pierwszym zapytaniu uzyskujemy zwrotnie "code" - dokładnie ten sam, który później musimy wysłać z odpowiedzią, aby została przyjęta (zachęcam do sprawdzenia, co się stanie przy złym kodzie - na prawdziwej aplikacji byłoby to równoznaczne ze zbanowaniem użytkownika). W przypadku wysłania monitu o zakończeniu gry zwrotnie otrzymujemy "msg", które każdy, kto grał, rozczyta jako wyświetlaną wiadomość.

Jak to działa?

Wiemy już, jakie informacje serwer dostaje oraz domyślamy się, jak je weryfikuje. Często ta informacja wystarcza (tu również), ale pozwolę sobie kontynuować i drążyć temat. Zajrzyjmy do skryptów, które tą grą sterują. Zakładka "Script" firebuga. Prawdopodobnie jest teraz pusta; należy odświeżyć stronę, aby się załadowała danymi.

Czego jednak szukamy? No właśnie - na chwilę cofnijmy się do zakładki "HTML" i dokonajmy inspekcji przycisku "START!!!!!11111". Po prawej w zakładce "Events" zobaczymy:

Eventy dla elementu "START"
Wydarzenia dla elementu "START"

Czyli po kliknięciu w ten przycisk wydarzenie wywołuje jedynie funkcję "start_game". Wracamy do zakładki "Script", w wyszukiwarce (u góry po prawej) wpisujemy "start_game" i... Wszystko mamy podane na tacy!

Kod JavaScript sterujący grą
Kod JavaScript sterujący grą

Można stąd bezpośrednio wylistować cały kod JS, który jest odpowiedzialny za tą grę:

var target, plej, start, code;
 function start_game(){
 var e = document.getElementById("case1");
 target = document.createElement("div");
 target.className = "target";
 e.innerHTML = "";
 callMe("case1.php?action=start", function(o){
 code = o.code;
 target.onclick = function(){ end_game(); };
 e.appendChild(target);
 plej = setInterval(function(){
 target.style.top = 350*Math.random()+"px";
 target.style.left = 550*Math.random()+"px";
 }, 250);
 start = +new Date();
 }, true);
 }
 function end_game(){
 end = +new Date();
 var t = end-start;
 clearInterval(plej);
 callMe("case1.php?action=end&code="+code+"&time="+t, function(o){
 alert(o.msg);
 }, true);
 }

Kod jest tak czytelny, że brakuje chyba tylko komentarzy dla tych, którym nie chce się czytać. Funkcja start_game czyści zawartość elementu o ID "case1", tworzy DIVa o klasie "target"; następnie wysyła zapytanie na serwer do case1.php. Po otrzymaniu odpowiedzi zapisuje otrzymany kod, ustawia wydarzenie na wcześniej stworzonym elemencie, dodaje go do drzewa DOM jako dziecko elementu "#case1", ustawia interwał losowo przesuwający cel i na koniec zapisuje czas rozpoczęcia. Nie jest ważne nawet, czym jest funkcja "callMe", gdyż jej użycie daje nam wszystkie potrzebne informacje.

Po zakończeniu działania funkcji start_game w zmiennej target mamy przesuwający się element, plej jest odniesieniem do interwału, start określa czas rozpoczęcia gry, a code jest otrzymanym kodem.

Funkcja end_game jest jeszcze prostsza - pobiera aktualny czas, by wyliczyć różnicę czasów, czyści interwał zapisany w plej oraz wysyła wynik do "case1.php". Po otrzymaniu odpowiedzi wyświetla otrzymany komunikat.

Co możemy z tym zrobić?

Po takiej analizie działania gry mamy już wszelkie potrzebne informacje do zmanipulowania jej działania. Teraz przedstawię kilka ciekawych skryptów, które w mniejszym bądź większym stopniu modyfikują jej działanie.

Najpierw skrypt zatrzymujący latanie kwadratu. Po uruchomieniu gry wklejamy go w zakładkę "Console" i uruchamiamy. Kwadrat po prostu przestanie latać, znacznie ułatwiając nam trafienie weń.

clearInterval(plej);

Jedyne, co musimy zrobić, to wyczyścić interwał przesuwający kwadratem.

Jeśli w dowolnym momencie chcielibyśmy zakończyć grę wystarczy w ten sam sposób wywołać:

end_game();

Zadziała to dokładnie tak, jak kliknięcie w kwadrat.

Możemy też oczywiście podmienić funkcje w JS. Na ten przykład jeśli ktoś by chciał, aby kliknięcie w czerwony kwadrat przenosiło użytkownika na stronę jego sponsora wystarczy wywołać (tym razem możemy nawet przed rozpoczęciem gry):

function end_game(){
 location.href = "http://trololololololololololo.com/";
}

a po kliknięciu na czerwony kwadrat użytkownik usłyszy swoją ulubioną piosenkę.

Co ja paczę?

Przykładów skryptów zmieniających bądź kontrolujących działanie Speedy Gonzales the GAME! można by wymieniać wiele. W ten sposób można nawet dokonać iniekcji zupełni innej gry, jeśli komuś się nudzi. Ale po co?

Ano po to, aby poćwiczyć i może się nauczyć czegoś nowego. Zachęcam do kreatywnej zabawy tych, którym się chce. A dla tych, którym się nie chce, przygotowałem konkretne zadanie, które jest celem dzisiejszego przykładu:

Sprawcie, aby skrypt przyjął czas 6.666s jako Wasz czas gry. Jeśli się to Wam uda zostaniecie wpisani do hali chwały. Ostatnie zgłoszenie złamania wyświetla się pod grą, więc możecie robić screeny i chwalić się koleżankom. Jedna uwaga - system przyjmie raz złamanie z jednego numeru IP, więc po złamaniu szybko F5 i print screen, bo przepadnie!

Mam nadzieję, że po lekturze całego posta nikt nie będzie miał problemów z rozwiązaniem tego łatwego zadania. A już za tydzień wrócę z następnym przykładem i postaram się powoli podnosić poprzeczkę.

Cheat
Oszukiwanie internetowych aplikacji konkursowych w najczystszym wydaniu. Dzięki wiedzy Tymoteusza możecie się dowiedzieć jak wygrać tak, aby nikt nie miał Wam nic do zarzucenia.

Podobne artykuły:

Skomentuj: