-
Notifications
You must be signed in to change notification settings - Fork 2
Diskusjon
Hvis Arduinomon skal bli et kommersielt produkt ønsker vi selvfølgelig ikke at brukerne skal bli skadelig avhengige. Selv om Arduinomonen ikke er et spill i den forstand, men heller kanskje noe nærmere relatert til samlekort, vil det å motvirke spillavhengighet være en viktig ting å forsøke å unngå. Noen måter dette kan bli gjort på er gjennom typ påtvungne pauser, noe som allerede er implementert (man må vente 10 sekunder mellom hver gang man kan forsøke å fange en pokemon). Et energisystem kunne også vært passende i fremtiden, der man beholdt fordelen av å at spilleren kan oppnå framgang over kort tid, men at mye spilling over lengre tid har avtagende resultater.
Med de funksjonene som er implementert til nå er det ikke mye annet vi får gjort for å forebygge spillavhengighet, og det er heller ikke mye som kan forårsake avhengighet, men hvis vi skulle solgt produktet ville måtte vi ha lagt til mer funksjonalitet, som kanskje muligheten til å bytte pokemon, en sjanse for å fange en shiny versjon av pokemon, mulighet til å kjempe mot andre spillere med de pokemon man har fanget osv. Dette vil gi flere grunnen til at forbrukerne kan bli avhengige av produktet og vi føler det er viktig å i alle fall ha dette i bakhodet hvis produktet skulle videreutvikles.
I dette prosjektet eksisterer det tre forskjellige ledd i sikkerheten som kan potensielt utnyttes til et eller annet formål. Vi går igjennom mulige angrepsmåter her.
- Wi-fi sniffing
- Web / Database
- Arduinoen
Trafikken som Arduinoen sender til telefonen er kryptert ved hjelp av en microchip ved navn ATECC608A. Krypteringen er ment for bruk i IoT tilfeller hovedsakelig, men tilbyr mer enn nok sikkerhet i vårt tilfelle. Microchippen støtter følgende kryptering: ECC P256 (ECDH and ECDSA), SHA256, AES-GCM. Hvem som helst som er koblet på samme nettverk som Arduinoen kan fange opp den krypterte trafikken, men dette oppnår lite. Teoretisk så kan en angriper fange opp trafikken, for å så sende trafikken gjennom en proxy som dekrypterer SSL/TLS sikkerheten om de har tilgang til selve SSL/TLS nøkkelen. Selve routerenheten som i vårt tilfelle sannsynligvis er en telefon som man er koblet til via et Wi-Fi hotspot, har ikke mer innsyn i trafikken som sendes enn hvilken som helst annen person som er koblet til nettverket og overvåker det med wireshark.
Om målet til en angriper er å stanse funksjonen til Arduinomon så kan man gjøre dette på et par måter, blant annet så kan man forhindre koblingen mellom Arduinoen og APIene som den kobler seg til. Dette kan utføre ved hjelp av et denial-of-service angrep for å kræsje et av APIene, enten databasen eller pokeAPI. Man kan også prøve å hacke database APIet. En populær måte er SQL injection, som vi kan gå videre på i Arduino delen. Selve maskinen som kjører databasen kan også komme under angrep, men det er ikke veldig relevant å inkludere det her
I et teoretisk case der vi har lansert et produkt basert på hva vi viser fram i dette prosjektet, så kan man ved hjelp av kredentialene til Arduinoene vi selger utføre SQL injection angrep. Dette kan resultere i tilgang til hele databasen, eller så kan man eventuelt slette den om motivet til angriperen er sabotasje. Dette kan utføres ved å veldig enkelt endre en linje i koden.
Om vi sletter det etter = tegnet, og skriver: “DROP DATABASE arduinomon”; så har vi da slettet databasen, i hvert fall inntil den blir gjenopprettet.
Rent teknisk har dette prosjektet vært både utfordrende og lærerikt. Til å begynne med er Arduino noe helt nytt for oss; noe vi aldri har utviklet med tidligere. Dette innebar med andre ord å sette seg inn i både hvordan en Arduino opererer, men også selve programmeringsspråket (C++).
Når det kommer til implementasjonen vår i Arduino så måtte vi først og fremst sette oss inn i hvordan tilkoble den til nettverk. Av åpenbare grunner måtte vi velge å tilkoble til internett via WiFi. På grunn av valget av hvilken Arduino vi bruker har vi ikke trengt å lodde fast en WiFi modul (ESP8266), noe som har spart oss for ekstra arbeid. Siden dette er et Arduino prosjekt så finnes det mange åpne og tilgjengelige biblioteker for hvordan koble seg til nettverk, så dette viste seg å ikke være problematisk.
Akselerometeret vi har benyttet har også tilgjengelige biblioteker for oppsett, så vi slet heller ikke med å få satt opp denne. Vi hadde derimot problemer med selve loddingen av denne enheten, men etter litt prøv-og-feil fikk vi det til. Når det gjelder selve implementasjonen av den kodemessig benyttet vi enkle metoder som hører med biblioteket vi har benyttet. Strengt tatt trengs det ikke avansert funksjonalitet for å få registrert bevegelse, men det som var mer utfordrende var å konfigurere akselerometeret til å reagere på de riktige verdiene. Det vil si hvor mye kraft må til for at den skal registrere det vi vil. Ideelt sett ønsket vi å oppnå den verdien for når et «ekte kast» hadde blitt registrert, men dessverre kom vi aldri så langt som å anskaffe oss en ball. Dette medførte at vi kun har brukt en midlertidig verdi for testing av prosjektet.
Etter at Arduino’en klarte å tilkoble til nettverk og registrere bevegelse måtte vi videre til å implementere kjernefunksjonaliteten i prosjektet; å generere en Pokemon. Rent teknisk er ikke det så vanskelig; det skal genereres en tilfeldig ID for en Pokemon.
Utfordringene startet når selve kommunikasjonen mellom Arduino’en, API’et og databasen måtte iverksettes. Til å begynne med utforsket vi muligheten å hente data direkte fra PokeAPI.
Den første utfordringen vi støtte på var å sette opp en kommunikasjon mellom Arduino og PokeAPI (og hvilken som helst HTTP-server). Det resulterte bare i HTTP feilmeldinger alt ut ifra hvordan vi sendte requestet. Det første forsøket fikk vi HTTP 403 feilmelding. Etter litt undersøkelser og analysering av hvordan pakkene ble sendt til PokeAPI viste det seg at PokeAPI klarte å forstå requestet, men den nekter å autorisere oss (https://tools.ietf.org/html/rfc7231#section-6.5.3). Dette har med at PokeAPI ikke klarer å tolke Arduino’en som en «gyldig» klient.
En enkel løsning på dette var å putte inn en parameter brukt i HTTP requests kalt User-Agent. Kort fortalt tillater User-Agent parameteren serveren som mottar HTTP requestet å identifisere klienten. Vi mistenker at dette er for å styrke forsvaret mot potensielle DDOS angrep.
Deretter hadde vi en del trøbbel med HTTP 400. Denne er ganske enkel å forstå; kort fortalt betyr det at HTTP requestet vårt er ikke satt opp riktig. Det er derimot vanskelig å diagnostisere. Det kan være alt fra ett mellomrom for mye til å ha en ugyldig parameter. Det viste seg i vårt tilfelle at klienten vi bruker for å spørre PokeAPI ikke bruker SSL kryptering (HTTPS). For at kommunikasjon mellom to enheter skal bli satt så må klienten støtte SSL dersom serveren gjør det. Dette var en relativt lett løsning siden biblioteket vårt for WiFi kommunikasjon støtter nettopp SSL; man må bare definere det. Dette gjør man i koden gjennom to enkle steg: første endre fra WiFiClient til WiFiSSLClient, også må porten som trafikken skal gå gjennom endres fra standard porten til HTTP server 80 endres til porten for SSL trafikk 443. Etter å ha klart å sette opp ett riktig HTTP request (med SSL) klarte vi å kommunisere med PokeAPI. Men på grunn av de tekniske begrensingene med Arduino i forhold til minne, så viser det seg at Arduino ikke klarer å innhente så mye data som PokeAPI responderer med. Alt ettersom hvilket aksesspunkt vi prøver å «requeste», så returnerer PokeAPI med for mye data for det aksesspunktet vi trenger, og Arduinoen rebooter av seg selv som en naturlig respons til overflødig minne. Dette medførte til at vi måtte ta et valg mellom to alternativer: enten «scrape» all data fra PokeAPI og lagre i en database, eller lage et egendefinert API som «speiler» data fra PokeAPI. Av relativt åpenbare grunner valgte vi å lage et egendefinert API på grunn av at først og fremst så vet vi ikke nødvendigvis hvilken data vi trenger, og for det andre så hadde vi endt opp med altfor mye data for databasen dersom vi skulle hentet all data fra PokeAPI.
Dette medførte til at vi måtte sette oss inn i hvordan sette opp ett API. Med den tidligere kunnskapen i PHP kunne vi allerede sette opp en webserver som hoster dette API’et. I tillegg med kunnskapen vi har fått tidligere med hvordan HTTP servere fungerer, så vet vi at vi må definere hvilken datatype som representeres på webserveren. Dette gjøres gjennom parameteret Content-Type, og er vitalt for at PHP skal forstå at det er JSON data som returneres fra PokeAPI, og ikke vanlig klartekst. Uten dette parameteret hadde ikke PHP klart å «parse» data fra API’et. I tillegg er det også viktig å definere at dette aksesspunktet har JSON data. Uten dette hadde ikke Arduino klart å dekode dataen som den henter, noe som vi fant ut av senere.
Det vi derimot måtte finne ut av var å først og fremst hvordan hente data fra PokeAPI, og for det andre vise data fra PokeAPI.
I utgangspunktet var ikke dette rent teknisk vanskelig. PHP har allerede innebygget metoder for å både dekode JSON data, og kode JSON data, så det var null problemer med å hente og vise data fra PokeAPI. Til å begynne med siden dette var ett nytt felt har vi valgt å hente en balansert mengde med data for det prosjektet krever. Utfordringen derimot var å sette oss inn i hvordan Arduino kan håndtere JSON data.
Etter at det lokale API aksesspunktet var satt opp, kunne Arduino hente data fra den med null problemer. Det viste seg derimot at Arduino ikke har noen måte å dekode JSON data på, så vi klarte ikke å hente ut de variablene vi trengte. Løsningen var relativ enkel; Arduino har et bibliotek for å dekode JSON data.
Etter å ha inkludert dette biblioteket kunne vi lese data problemfritt. Dette medførte til at vi nå kunne komme så langt som å:
- Bevege på Arduino; registrere bevegelse
- Generere en tilfeldig ID
- Hente data fra lokalt API om Pokemon ut ifra ID *Bruke data for å regne ut om den blir fanget eller ikke
Neste utfordring er altså å sende data til database. Slik vi har lært av Arduino og Arduino prosjekter generelt så vet vi at det finnes biblioteker for nesten alt, og selvfølgelig var det et bibliotek for å tillate støtte mellom Arduino og MySQL databaser.
Dette var også en relativt lett prosess. Man må ha en WiFi klient for å kommunisere mellom Arduino og database. Siden vi allerede hadde en WiFi klient for å kommunisere mellom Arduino og API’et, så ønsket vi å bruke denne. Dette viste seg derimot å ikke fungere; vi endte bare opp med at når Arduino’en skulle koble seg til databasen så satt den fast i en evig loop.
Rent teknisk vet vi ikke hvordan det ble forårsaket, men vi vet hvorfor. MySQL biblioteket til Arduino støtter ikke WiFi klienter som krypteres med SSL. Siden vi er nødt til å ha SSL kryptering for å kommunisere med API’et, så var eneste løsning å lage en egen klient for MySQL.
Dette gikk smertefritt, og vi fikk kommunisert med databasen. Dette inkluderte å hente data og sende data, og ingen nye problemer oppsto.