Fuzzing: - Kanskje alle utviklere burde teste egne applikasjoner for alle bytes?

Sikkerhetskonsulent Chris Dale foklarer hvordan du tester egen kode for sårbarhet.

- Kanskje alle utviklere burde teste egne applikasjoner for alle bytes og sikre at applikasjonen alltid svarer på en forutsigbar og grei måte? spør Chris Dale. 📸: Privat.
- Kanskje alle utviklere burde teste egne applikasjoner for alle bytes og sikre at applikasjonen alltid svarer på en forutsigbar og grei måte? spør Chris Dale. 📸: Privat. Vis mer

Stadig vekk introduserer utviklere nye feil og sårbarheter.

Og man må håpe at selskapet har en prosess for å oppdage sårbarheter før programvaren havner i produksjon, gjerne via en S-SDLC (Secure Software Development Life Cycle).

Likevel: Det er ikke alltid komfortabelt å overlate kildekoden til det neste steget av prosessen. Man skulle gjerne ha ønsket å teste sin egen kode for sårbarheter i forkant.

Men det krever vel mye detaljkunnskap om alle verdens sårbarheter?

Penetrasjonstesting-metodikk

Konsulenter innenfor offensive tjenester følger normalt spesifikke metoder for å avsløre alle typer sårbarheter i programvaren.

Ett eksempel er når penetrasjonstestere angriper en applikasjon. Da blir det første steget, og en av de viktigste jobbene en tester gjør, å avsløre alle tilgjengelige angrepsflater.

Her har utviklere selv en gigantisk fordel siden de som regel er kjent med hvilke scripts og funksjonaliteter som er tilgjengelig, mens en angriper utenfra må finne ut dette selv.

Her er noen av elementene penetrasjonstestere bruker for å finne tilgjengelige angrepsflater, som utviklere oftest slipper å tenke på:

  • Vi utforsker hele applikasjonen og trykker på alle lenker. Dette lar oss bli kjent med applikasjonen og vi kan kartlegge det meste av applikasjonens funksjonalitet.

  • Vi forventer at det finnes funksjonaliteter som det ikke er linket til eller som kan oppdages kun ved å trykke i applikasjonen. Vi gjetter derfor mye ved å bruke logikk og ordlister for å sjekke om det finnes script, parametere eller elementer som er tilgjengelig andre steder i applikasjonen.

Start å hacke

Når vi føler at vi har en god forståelse og at hele applikasjonen har blitt kartlagt, kan hackingen og penetrasjonstestingen starte. Herfra jobber teams på forskjellige måter, men River Security bruker en "opp-ned" pyramidemodell for å:

  • Fastslå nøye og forutsigbart avvik mot sårbarheter.
  • Få frem avvik og interessante momenter ved applikasjonen sin håndtering av data.

  • Bruke et team til å konkludere hypoteser og test-caser, samt sikre god kompetanseoverføring i casene.

Prosessen er illustrert her:

image: Fuzzing: - Kanskje alle utviklere burde teste egne applikasjoner for alle bytes?

Kan utviklere bruke penetrasjonstesting-metodikk til å teste egne kode?

Det er toppen av opp-ned pyramiden som er mest interessant for utviklere. Skriver du en applikasjon som tar inn data fra en bruker, nettverk eller andre steder, så bør du anta at dataen er skitten. Den bør derfor valideres og kontrolleres før dataen tas i bruk.

Toppen av pyramiden handler om "fuzzing", altså det å teste applikasjonen i forhold til hvordan den reagerer ved input skapt av automatikk. En meget god måte å "fuzze" på er å teste alle mulige bytes inn mot applikasjonen, og sjekke at applikasjonen responderer forutsigbart og riktig for hver input.

Bytes er typisk tallkjeden fra 00 til FF i heksadesimal, noe som enkelt kan konfigureres i lokale proxyer som for eksempel OWASP Zap eller Burp Suite.

«Skriver du en applikasjon som tar inn data fra en bruker, nettverk eller andre steder, så bør du anta at dataen er skitten.»

Se for deg en applikasjon som gjør et oppslag mot en database. Det forventes at applikasjonen oppfører seg helt greit og ryddig til tross for at brukeren skriver inn et spesialtegn i stedet for eksempel en vanlig bokstav.

Ser man på skjermbildet under så har det blitt valgt en input-parameter til en applikasjon i den lokale proxyen ZAP fra OWASP. Kontekstmenyen viser mulighet for å velge "Fuzz…":

image: Fuzzing: - Kanskje alle utviklere burde teste egne applikasjoner for alle bytes?

Fra denne menyen åpner det seg enkle muligheter for å teste applikasjonen for all slags input, som for eksempel 00-FF. Du kan velge å legge på tall, og du kan legge på en prosent-prefix foran tall.

Da blir det automatisk tolket av webapplikasjoner som det som kalles en URL-enkodet byte. Denne byten vil nå fram til applikasjonen, bli dekodet og du vil se hvordan applikasjonen reagerer.

Bruk Intruder

I Burp Suite er det også enkelt å teste alle mulige bytes inn mot applikasjonene vi utvikler. Man kan i funksjonen "Intruder" legge på paragraftegn rundt verdiene man ønsker å Fuzze slik som dette:

image: Fuzzing: - Kanskje alle utviklere burde teste egne applikasjoner for alle bytes?

Videre konfigurere man angrepet til å gå gjennom tall fra 00 til FF, samt legge på prosent som dette:

image: Fuzzing: - Kanskje alle utviklere burde teste egne applikasjoner for alle bytes?
image: Fuzzing: - Kanskje alle utviklere burde teste egne applikasjoner for alle bytes?

Når angrepet gjennomføres får man opp utfallet av 256 forskjellige bytes i en flott tabell, og man ser enkelt hvordan applikasjonen responderer. På bildet under så kan man enkelt se at to bytes, henholdsvis %27 og %5c, produserer et helt annet resultat enn andre bytes.

Man ser avviket enkelt når man sorterer på lengde. Applikasjonen oppfører seg normalt, helt til spesialtegnene ‘ (fnutt) og \ (back-slash) blir gitt inn, resultatet av å dekode %27 og %5c. En utvikler må da spørre:

Hvorfor klarer ikke applikasjonen å respondere normalt ved disse spesialtegnene?

Strenge input-regler

Det er en enkel test for å sikre om applikasjonen håndterer input på en god og forutsigbar måte. Du kan nå gå tilbake til koden din, sikre at spesialtegnene blir håndtert, og at applikasjonen er litt tryggere.

Det anbefales for øvrig ikke å lage blokkeringslister med uakseptable spesialtegn, men lister over hvilke tegn som er tillat. Ved å lage strenge input-regler for hvilke tillatte tegn som hvert script i applikasjonen tillater blir det ganske vanskelig å hacke den. Bruk «allow»-lister i stedet for «deny»lister der det er mulig.

Kanskje alle utviklere burde teste egne applikasjoner for alle bytes, og sikre at applikasjonen alltid svarer på en forutsigbar og grei måte?