Ifølge Gary McGraw hviler programvaresikkerhet på tre pilarer:
- Anvendt risikostyring: Ta på deg den svarte hatten din for å avdekke alle mulige trusler. Utfør risikoanalyse på arkitekturnivå, dvs. trusselmodellering med mere. Risiko må spores og motvirkes kontinuerlig gjennom hele utviklingslivssyklusen.
- Trykkpunkter for programvaresikkerhet: Identifiser kjerneaktiviteter som bidrar til forbedret programvaresikkerhet, og sørg for at sikkerhet blir tatt hensyn til i hvert steg av programvareutviklingssyklusen. Microsoft sitt Tiltrodde databehandlingsinitiativ (Trustworthy Computing Initiative) fra 2002 er et eksempel, som resulterte i Microsoft SDL (og senere SDL Agile).
- Kunnskap og god praksis: Alle utviklere må ha et minimum av sikkerhetskunnskap, og kunne bruke sjekklister som OWASP Top 10.
Penetrasjonstesting
Artefakten vi forholder oss til i penetrasjonstesing er systemet i sitt tiltenkte miljø. Vi kan se på det som en “svarthatt-aktivitet” basert på en “hvithatt-tilnærming”, og det kan være veldig nyttig for å validere en risikoanalyse og plan for håndtering av risiko. Penetrasjonstesting kan gi en god forståelse av applikasjonen slik den framstår i et virkelig miljø. Penetrasjonstesting er et av praksisområdene i BSIMM.
Hva er penetrasjonstesting?
Oftest har man spesialiserte verktøy med en særegen tilnærming til å angripe et system (eller applikasjon) og lete etter sikkerhetssvakheter og -hull (CWE kontra CVE). Målet er å få (økt) tilgang til systemer og tilhørende data. Vevapplikasjoner har vært naturlige kandidater for penetrasjonstesting, men også andre systemer som utenforstående kan få tilgang til er aktuelle. Forskjellen fra vanlig testing er at her ser man ikke på forventet funksjonalitet (“når jeg trykker ‘A’ skal det komme ‘B’ på skjermen”); her tar man på seg sin metaforiske svarte hatt og tester for hva som ikke skal skje. Penetrasjonstesting drives av trusselmodellering og misbrukshistorier.
Penetrasjonstesting i dag
Selv om hendelser ofte kommer som en overraskelse på offeret, stammer de vanligvis fra bevisst misbruk på en eller annen måte. En grunn til overraskelsen er at det er lett å teste programvarefunksjonalitet, men veldig vanskelig å vise at en applikasjon er sikker nok når den utsettes for et angrep fra en ondsinnet aktør.
Penetrasjonstesting utføres på en utenfra-og-inn måte. Tradisjonelt har ikke driftere vært involvert i utviklingen, så penetrasjonstesting har heller ikke vært en del av utviklingssyklusen. I stedet har det vært den siste tingen man sjekker før man leverer, gjerne i produksjonsmiljøet.
En vesentlig begrensning er at det ofte blir en “for-lite-for-sent”-aktivitet på tampen, hvor det kan være dyrt å fikse sårbarhetene som avdekkes, og det hele er reaktivt og defensivt i stedet for å være proaktivt og dynamisk.
Hvis man driver penetrasjonstesting uten grunnleggende risikoanalyse og trusselmodellering i bunn står man i fare for å oppnå mest “innbilt sikkerhet”. Effektiv penetrasjonstesting forutsetter at man har mulighet til å se det store bildet; man må finne eventuelle operasjonelle forhold, identifisere konfigurasjonsrelaterte problemer, og forhold som har med avhengigheter å gjøre (system, undermoduler, sammenkobling).
Penetrasjonstesting av programvare
Nettverksbasert penetrasjonstesting av et system går gjennom en del steg:
- Planlegging: Analyse av systemet, fotavtrykk til komponenter og identifikasjon av enheter
- Rekognosering: Ping (ICMP ECHO Request) for å finne ut hvilke enheter som er på, nmap for å kartlegge tjenester som kjører, og generelt samle inn informasjon.
- Skanning: Bruk av sårbarhetsskanner, manuell skanning, forsøk på å gå i dybden
- Utnyttelse: Angrep, penetrering, kompromittering
- Skjuling av spor: Hvis hensikten av penetrasjonstesting også er å teste hvordan virksomheten håndterer hendelser, må man skjule seg for å kunne forbli på systemet etter omstart, og også slette relatertlogginformasjon.
Når man gjør penetrasjonstesting av programvare kan det lønne seg å justere stegene:
- Planlegging: Trusselmodellering og risikoanalyse, sikkerhetskrav, angrepshistorier
- Rekognosering: Arkitektur, sikkerhetskrav, samle informasjon
- Skanning: Sårbarhetsskanner, angriperhistorier, sikkerhetstesting
- Utnyttelse: Angrep, penetrasjon, kompromitter
- Skjuling av spor: Samling av tilbakemeldinger, kobling tilbake til utviklerne, måling og metrikker
Bruk av verktøy
Ved penetrasjonstesting er det aktuelt å bruke statiske analyseverktøy, fuzz-testing, og dynamiske analyseverktøy for å finne ut mest mulig om systemet. Det finnes egne verktøy for å injisere feil, og disassemblere og dekompilatorer kan også brukes. Det finnes verktøy som er åpen kildekode: Nessus, Metasploit og Kali/backtrack, mens andre er kommersielle: Immunity, WebInspect, Core Impact, IDA Pro.
Testing i dybden
Vi ønsker å teste for sikkerhetsrisiko, og integrere statiske og dynamiske analyseverktøy. Vi fokuserer på systemnivået, og ser på det integrerte programvaresystemet. Utrullingspraksis er ofte sentralt I penetrasjonstesting, og vi får mest ut av det dersom vi tilpasser penetrasjonstestingsverktøyene til resultatene av risikovurdering og trusselmodellering.
Integrasjon av tilbakemelding
En vanlig feil er at resultatene fra penetrasjonstesting i utilstrekkelig grad mates tilbake til utviklingsprosessen. Løsninger som i beste fall representerer lapping av hull med plaster (f.eks. ved å justere brannmurregler – ref. WannaCry og SMB-trafikk) kan nok fungere der og da, men bidrar i liten grad til å løse det underliggende problemet. For dette trenger man å utføre rotårsaksanalyse, finne ut av problemet, og deretter se etter liknende problemer. Deretter kan man identifisere en strategi for å håndtere problemet; denne kan omfatte både opplæring, endringer i biblioteker, og endret praksis.
Som ofte ellers, er automasjon gull verdt. Et automatisk testbatteri vil kunne ta en mengde lavthengende frukt, og vil la testerne bruke energien sin på mer utfordrende ting.
Det finnes forskjellig typer penetrasjonstesting. Den mest vanlige er testing av nettverkstjenester, hvor man gjerne starter på et nettverk og leter fram sårbare enkeltmaskiner, operativsystemer og tjenester. En klient-side-test prøver å finne og utnytte sårbarheter på klienter, som f.eks. i nettlesere. En annen favoritt er test av vevapplikasjoner i sitt naturlige habitat. Det er også mulig å teste ut muligheter fjernaksess; om det er noen tilkoblingspunkter i målmiljøet. Dette kan også omfatte gjetting av passord. Det hender fortsatt at enkeltpersoner setter opp uautoriserte trådløse nettverk; disse har ofte dårligere sikkerhet enn virksomhetens offisielle trådløsnett, og kan også gi tilgang til mye mer enn f.eks. et gjestenett. Mange penetrasjonstestere tester også ut virksomhetens sikkerhetskultur med forskjellige former for sosial manipulering, hvor man prøver å ta over brukerkonti eller å gi seg utfor å være den brukeren angrepet retter seg mot.
Utfordringer
Hva skiller god og dårlig penetrasjonstesting? Dette er ikke alltid så enkelt å se utenfra, men vi kan slå fast at hvis man ikke tester all attributtene til angrepsflaten, så er det en dårlig tilnærming. En god penetrasjonstest vil være omfattende, og se på trusselnivåer.
Vi kommer ikke bort fra at penetrasjonstesting forutsetter kunnskap og ferdigheter, og de som driver med dette på daglig basis er ofte sertifiserte i henhold til et eller annet regime (f.eks. SANS GIAC – men det finnes mange andre sertifiseringer). McGraw påpeker at fokuset på testen er viktig, men også hvordan man kommuniserer og følger opp. Hvis man ser på det som en logisk og analytisk prosess vil programvarearkitekter være gode kandidater til å få ytterligere opplæring for å bidra inn i penetrasjonstesting av programvare.
En angriper som skal oppnå et bestemt mål, trenger ofte ikke bekymre seg for bieffekter som medfører utilsiktet skade, men når man utfører penetrasjonstesting må man selvfølgelig unngå å påføre målet permanent skade på noe vis. Hvis vi beveger oss inn i den cyber-fysiske verden kan man for eksempel demonstrere at man er i stand til å manipulere uran-anriknings-sentrifuger uten at det oppdages av overvåkingssystemer, men man må unnlate å faktisk gjøre det slik at de blir ødelagt.
Man har alltid begrenset budsjett og lite tilgjengelig tid, så det er en evig kamp for å gjøre mye med lite. Den største synden er imidlertid å ikke adressere påvirkning på forretningsdriften – det er de reelle konsekvensene som må være styrende når man skal prioritere.
Oppsummering
Penetrasjonstesting er en utenfra-og-inn-tilnærming som ofte utføres som en del av prosessen med å rulle ut programvare. Vi får mest ut av den hvis den gjøres etter kodegjennomgang og trusselmodellering, og den kan egentlig gjøres fra starten av og gjennom hele programvareutviklingssyklusen. Penetrasjonstesting bør utføres med utgangspunktet i opplevd risiko. Det finnes standarder og regulativer som krever at det utføres penetrasjonstesting av programvare og systemer for etterlevelse. Til slutt minner vi om at en penetrasjonstesting i seg selv aldri vil fører til sikrere programvare – det er ikke før man mater resultatene tilbake til utviklingsprosessen at man kan forbedre programvaresikkerheten!