Etikett: Attack Surface Management

  • Steg för steg: Så minskade jag attackytan på min domän

    Steg för steg: Så minskade jag attackytan på min domän

    Ett område inom cybersäkerhet som jag tycker är extra roligt är att analysera och minimera den externa attackytan.

    Med extern attackyta menas alla kontaktytor som går att nå från internet – från webbservrar och TLS-konfiguration till DNS och e-postinställningar. I den här artikeln går jag igenom hur man analyserar dessa ytor och identifierar svagheter i konfigurationen.

    Innehållsförteckning

    1. Hur går man tillväga?
    2. Ett oväntat prestandaproblem
    3. Analys av attackytan med Hardenize

    Hur går man tillväga?

    Det går förstås att göra allt manuellt med hjälp av nmap, dig, openssl och liknande verktyg – men då krävs det också att man vet vad man ska leta efter. Som tur är finns det färdiga tjänster som hjälper dig komma igång.

    Jag brukar ofta börja med Hardenize eftersom det är enkelt att använda och ger en väldigt tydlig överblick över de vanligaste säkerhetsparametrarna för en domän.

    På senare tid har jag dock börjat använda Internet.nl allt mer, och det har blivit något av en ny favorit. Internet.nl är ett initiativ inom ramen för Internet Standards Platform – ett samarbete mellan flera nederländska aktörer med målet att göra internet mer tillgängligt, säkrare och mer tillförlitligt för alla.

    Man kan tycka att dessa analyser mest hittar lågt hängande frukt som de flesta borde ha koll på. Men förvånansvärt ofta upptäcker jag att företag missar, eller saknar kunskap om, grundläggande skyddsåtgärder. För organisationer med mer komplexa miljöer kan det dessutom vara svårt att ha full koll på sin externa attackyta.

    Mindre företag har ofta en relativt statisk attackyta, och då kan dessa tjänster i kombination med manuella kontroller räcka långt. Vill man däremot arbeta systematiskt med External Attack Surface Management (EASM) och göra löpande analyser kan det vara värt att investera i en professionell lösning, som Bitsight, SecurityScorecard eller Qualys. Arbetar man mycket i Microsoft Azure kan Defender EASM också vara ett intressant alternativ.

    Vad skiljer då professionella lösningar mot de kostnadsfria alternativen?

    Professionella lösningar analyserar ofta attackytan bredare. Medan kostnadsfria alternativ främst granskar svagheter i specifika konfigurationer – till exempel DNS, webb och e-post – gör professionella lösningar en mer heltäckande kartläggning och skannar alla portar för att identifiera flera tjänster. De kan även inkludera funktioner som genomsöker webbapplikationer efter sårbar kod. Men överlag tycker jag att de kostnadsfria alternativen gör ett riktigt bra jobb.

    Det som de professionella alternativen framförallt kan hjälpa till med är att inventera den faktiska attackytan. Visst går det att lösa med lite detektivarbete genom att skanna IP-adresser, granska DNS-poster och söka efter utfärdade certifikat, men för större organisationer med komplexa miljöer kan detta snabbt bli en utmaning. Här kan ett automatiserat verktyg vara till stor hjälp.

    I den här artikeln tänkte jag dela med mig av hur jag brukar arbeta, med en kombination av kostnadsfria tjänster och manuella kontroller, och steg för steg visa hur jag förbättrar säkerheten för min domän learntodefend.se.


    Ett oväntat prestandaproblem

    Redan innan jag började titta på attackytan upplevde jag att min blogg var lite långsam. Visserligen kör jag ett enklare webbhotell hos Loopia, men det här kändes som något annat. Ganska snabbt konstaterade jag att bloggen svarade betydligt långsammare när jag anslöt mot toppdomänen learntodefend.se jämfört med subdomänen www.learntodefend.se.

    En omdirigering kan såklart innebära viss fördröjning, men i mitt fall kunde det skilja flera sekunder. Det visade det sig att anslutningar mot toppdomänen behövde gå hela vägen via webbservern, starta PHP och ladda WordPress innan de vidarebefordrades till www.learntodefend.se. Det är onödigt tungt, så istället ville jag hantera omdirigeringen direkt i webbservern. I mitt fall är det en Apache-server, och den enklaste lösningen var att konfigurera detta i en .htaccess-fil.

    Här stötte jag på problem. Jag började med att skriva omdirigeringen i två steg: först tvingade jag all trafik från HTTP till HTTPS och därefter vidarebefordrade jag anrop mot toppdomänen learntodefend.se till subdomänen www.learntodefend.se.

    <IfModule mod_rewrite.c>
      RewriteEngine On
    
      # 1) Tvinga HTTPS
      RewriteCond %{HTTPS} !=on
      RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
      # 2) Vidarebefordra till www
      RewriteCond %{HTTP_HOST} ^learntodefend\.se$ [NC]
      RewriteRule ^ https://www.learntodefend.se%{REQUEST_URI} [R=301,L]
    </IfModule>

    Det här funkade inte alls, och jag kunde inte ens komma åt bloggen längre. Efter lite detektivarbete verkar det som att Loopia terminerar TLS i en NGINX-proxy framför Apache-servern. Så för Apache är anropen alltid HTTP.

    När jag tvingade HTTP till HTTPS skapade jag en evighetsloop.

    Jag har inte verifierat detta med Loopia, men utifrån hur trafiken beter sig och vilka headers som skickas ser det ut att fungera på det sättet.

    Lösningen blev en enklare konfiguration som bara vidarebefordrar anrop mot toppdomänen learntodefend.se till subdomänen www.learntodefend.se.

    <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{HTTP_HOST} ^learntodefend\.se$ [NC]
      RewriteRule ^ https://www.learntodefend.se%{REQUEST_URI} [R=301,L]
    </IfModule>

    Analys av attackytan med Hardenize

    Därefter gjorde jag en analys med hjälp av Hardenize och gick igenom resultatet uppifrån och ner. Resultatet är indelat i kategorierna Domain Name System, Email och WWW.


    Domain Name System

    Denna kategori är indelad i fyra tester:

    • DNS Zone
    • DNS Records
    • DNSSEC
    • CAA

    DNS Zone & DNS Records

    De två första testerna, DNS Zone och DNS Record, gör en övergripande kontroll av att DNS är korrekt uppsatt och att det inte finns några uppenbart onödiga (”dangling”) DNS-poster. Det här är sällan några problem och brukar inte kräva några större åtgärder.


    DNSSEC

    För mig är DNSSEC en självklarhet, men det är fortfarande förvånansvärt många domäner som inte har detta aktiverat. Jag tror det finns en rädsla för att DNSSEC ska vara komplicerat att konfigurera, när det i många fall är ganska enkelt.

    DNSSEC är en teknik för att skydda DNS så att svaren inte kan bli manipulerade. Jag kommer inte gå in på detaljer, istället planerar jag att skriva en egen artikel om DNSSEC. Men kortfattat innebär det att man skapar ett nyckelpar, Zone-Signing Key (ZSK), där den privata delen är hemlig och signerar DNS-posterna. Den publika delen görs tillgänglig via en DNSKEY-post och används av klienter för att verifiera svaren.

    För att klienterna ska kunna lita på nycklarna skapas även en Key-Signing Key (KSK), som signerar den publika ZSK:n. En hash av KSK:n publiceras sedan som en DS-post i domänens föräldrazon (i mitt fall .se-zonen), vilket skapar en kedja som går att verifiera.

    I de flesta fall är DNSSEC enkelt att konfigurera. Ofta räcker det att logga in i DNS-verktyget och aktivera funktionen. Då får man tillbaka en DS-post som man ger till domänregistraren, som i sin tur publicerar den i föräldrazonen. Om man, som jag, använder DNS-servrar hos samma leverantör som även agerar registrar för domänen, brukar det oftast räcka att bara aktivera DNSSEC.

    ⚠️ Viktigt! Med det sagt gäller det att vara noggrann. Om någon av nycklarna blir fel bryts förtroendekedjan, och klienter slutar att lita på DNS-svaren.

    💡 Tips: Vill man analysera djupare eller felsöka DNSSEC är DNSViz och Zonemaster två väldigt bra verktyg.


    CAA

    Det sista testet, CAA, kontrollerar om domänen har CAA-poster i DNS som styr vilka certifikatutfärdare (CA) som får utfärda certifikat för domänen. Det är en enkel men effektiv funktion för att minska risken att certifikat blir utfärdade av misstag eller i bedrägligt syfte.

    ⬆️ Tillbaka till innehållsförteckningen


    Email

    Denna kategori är indelad i följande tester:

    • Mail servers
    • TLS
    • Certificates
    • MTA-STS
    • TLS-RPT
    • DANE
    • SPF
    • DMARC

    Mail servers

    Det första testet, Mail servers, kontrollerar att domänens MX-poster är korrekt konfigurerade och pekar på giltiga mejlservrar. Hardenize verifierar även att mejlservrarna svarar på SMTP och beter sig som förväntat.


    TLS & Certificates

    De efterföljande testerna, TLS och Certificates, granskar kryptering vid e-postkommunikation. Här kontrolleras bland annat om mejlservern stödjer TLS, vilka protokoll och ciphers som tillåts samt vilket certifikat som presenteras vid anslutning.

    I dag är rekommendationen att endast tillåta TLS 1.2 eller senare, och att använda moderna ciphersuites. Äldre protokoll och svaga algoritmer bör tas bort i takt med att de blir föråldrade. Använder man till exempel Microsoft 365 behöver man inte justera dessa inställningar själv, då tjänsten redan är konfigurerad med säkra standardvärden.


    MTA-STS

    Mail Transfer Agent Strict Transport Security (MTA-STS) är en funktion för att tala om för andra mejlservrar att e-post till din domän ska levereras via krypterad TLS. Funktionen liknar DANE och är enklare att sätta upp eftersom den till skillnad från DANE inte kräver DNSSEC.

    Tekniken är enkel och består av två delar:

    • En TXT-post i DNS, _mta-sts.dindomän.se, som signalerar att domänen stödjer MTA-STS och vilken version av policyn som används
    • En policyfil som är tillgänglig via HTTPS på adressen https://mta-sts.dindomän.se/.well-known/mta-sts.txt

    Policyfilen innehåller fyra rader:

    • version – alltid STSv1
    • mode – anger hur policyn ska tillämpas
      • none – policyn är inaktiv
      • testing – för att testa konfigurationen; tillåter okrypterade anslutningar men begär rapporter
      • enforce – instruerar avsändande mejlservrar att avvisa leveransen om det inte går att ansluta krypterat
    • mx – anger vilka mejlservrar som är godkända att ta emot e-post för domänen
    • max_age – hur länge policyn får cachas av avsändande servrar

    Min TXT-post för MTA-STS ser ut så här:

    _mta-sts.learntodefend.se. IN TXT "v=STSv1; id=202602100718"

    Om id-värdet blir ändrat vet avsändande servrar att de behöver hämta policyn på nytt.

    Min policy finns tillgänglig på https://mta-sts.learntodefend.se/.well-known/mta-sts.txt och ser ut så här:

    version: STSv1
    mode: enforce
    mx: learntodefend-se.mail.protection.outlook.com
    max_age: 86400

    ⚠️ Viktigt: MTA-STS innebär inte att din egen mejlserver automatiskt kräver kryptering. Policyn talar om för avsändande servrar att leverera e-post via TLS, men det är fortfarande upp till respektive server att stödja och följa MTA-STS.


    TLS-RPT

    TLS Reporting (TLS-RPT) används ofta tillsammans med MTA-STS och är viktigt för att få reda på när leveranser misslyckas på grund av problem med TLS. Med TLS-RPT kan avsändande mejlservrar skicka rapporter när de inte lyckas leverera e-post.

    TLS-RPT konfigureras genom en TXT-post, _smtp._tls.dindomän.se. I mitt fall ser posten ut så här:

    _smtp._tls.learntodefend.se. IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@ezj9gpjt.uriports.com"

    Jag använder URIports för att ta emot och sammanställa rapporterna. Det går såklart att skicka rapporterna till en vanlig brevlåda, men jag rekommenderar någon form av verktyg som kan hjälpa till att tolka och sammanställa datan.


    DANE

    DNS-based Authentication of Named Entities (DANE) har liknande funktion som MTA-STS, nämligen att säkerställa att e-post levereras via krypterad TLS.

    Till skillnad från MTA-STS, som publicerar en policy via HTTPS, så använder DANE istället TLSA-poster i DNS. Posterna publiceras under mejlserverns namn och anger vilket certifikat som är giltigt för servern.

    En annan viktigt skillnad är att DANE kräver DNSSEC för att andra mejlservrar ska kunna verifiera att de ansluter till rätt server med rätt certifikat.

    TLSA-posten för SMTP har följande format:

    Värdet består av tre siffror (”3 1 1” i detta exempel) och en hash. Siffrorna anger usage, selector och matching type:

    Usage – anger hur certifikatet ska valideras

    1. PKIX-TA (använd inte för SMTP)
    2. PKIX-EE (använd inte för SMTP)
    3. DANE-TA (pekar på CA/intermediate-certifikat)
    4. DANE-EE (pekar på servercertifikatet)

    Selector – anger vad som måste matcha

    1. Hela certifikatet
    2. Den publika nyckeln (rekommenderas)

    Matching type – anger hash-algoritm

    1. Ingen hash
    2. SHA-256 (rekommenderas)
    3. SHA-512 (mindre vanligt)

    Den vanligaste kombinationen för SMTP i dag är 3 1 1, vilket innebär att man publicerar en SHA-256-hash av servercertifikatets publika nyckel.

    Sista steget är att generera SHA-256-hashen. Detta görs enklast med verktygen openssl:

    openssl x509 -in /mejlserver.crt -noout -pubkey | openssl pkey -pubin -outform DER | openssl sha256

    💡 Tips: Vill du läsa mer on DANE och hur man konfigurerar detta rekommenderar jag Internet.nl:s DANE for SMTP how-to.

    Konfigurera DANE för Microsoft 365

    Om man som jag använder Microsoft 365 så pekar MX-posten på en Microsoft-domän, i mitt fall learntodefend-se.mail.protection.outlook.com.

    Eftersom jag varken hanterar mejlservern, dess certifikat eller domänen kan jag inte skapa TLSA-poster manuellt. I stället behöver DANE konfigureras via Exchange Online.

    Börja med att installera Exchange Online PowerShell-modulen och logga in som global administratör:

    Install-Module -Name ExchangeOnlineManagement
    Connect-ExchangeOnline

    Därefter aktiverar du DNSSEC med kommandot Enable-DnssecForVerifiedDomain. Kommandot returnerar en ny MX-domän som är konfigurerad för DNSSEC, och som du behöver lägga till i din DNS.

    Enable-DnssecForVerifiedDomain -DomainName learntodefend.se
    
    Domain           MxValue                            Result  ErrorData
    ------           -------                            ------  ---------
    learntodefend.se learntodefend-se.i-v1.mx.microsoft Success 

    När DNSSEC är konfigurerat kan du aktivera DANE för inkommande SMTP med kommandot Enable-SmtpDaneInbound:

    Enable-SmtpDaneInbound -DomainName learntodefend.se

    Kommandot kan ta några sekunder att slutföra. Därefter kan det dröja ytterligare 15–30 minuter innan TLSA-posten är skapad och publicerad.

    När allt är aktiverat brukar jag använda till exempel CheckTLS för att kontrollera att TLSA-posten är korrekt publicerad och att DANE-konfigurationen ser bra ut.


    SPF & DMARC

    Sender Policy Framework (SPF) och Domain-based Message Authentication, Reporting, and Conformance (DMARC) är tekniker som används för att minska risken för att någon skickar e-post i din domäns namn.

    SPF innebär att man lägger till en TXT-post i DNS som anger vilka servrar som är tillåtna att skicka e-post för domänen.

    v=spf1 ip4:40.92.0.0/15 -all

    I mitt fall använder jag Microsoft 365 och inkluderar deras färdiga SPF-post istället för att lista specifika IP-adresser:

    v=spf1 include:spf.protection.outlook.com -all

    DMARC används för att rapportera om någon försöker skicka e-post som bryter mot SPF eller DKIM. Precis som med SPF lägger man till en TXT-post i DNS som indikerar till vilken adress rapporterna ska skickas:

    v=DMARC1; p=reject; rua=mailto:dmarc@learntodefend.se;

    Om du vill läsa mer om hur SPF, DKIM och DMARC fungerar har jag skrivit en separat artikel här: https://www.learntodefend.se/skydda-dig-mot-falska-mejl-med-spf-dkim-och-dmarc.

    ⬆️ Tillbaka till innehållsförteckningen


    WWW

    Denna kategori är indelad i följande tester:

    • HTTP (80)
    • HTTPS (443)
    • TLS
    • Certificates
    • Cookies
    • HTML Content
    • Strict Transport Security
    • Content Security Policy
    • Subresource Integrity
    • Frame Options
    • XSS Protection
    • Content Type Options

    HTTP (80) & HTTPS (443)

    De första testerna, HTTP 80 och HTTPS (443), kontrollerar om domänens webserver är korrekt konfigurerad. Det innebär till exempel att servern svarar med rätt statuskoder, inte läcker onödig information och vidarebefordrar HTTP-trafik till HTTPS.


    TLS & Certificates

    De följande två testerna, TLS och Certificates, kontrollerar om webbservern stödjer TLS, vilka protokoll och ciphers som tillåts samt vilket certifikat som presenteras vid anslutning.

    I dag är rekommendationen att endast tillåta TLS 1.2 eller senare, och att använda moderna ciphersuites. Äldre protokoll och svaga algoritmer bör tas bort i takt med att de blir föråldrade.

    Om du vill analysera TLS och certifikat är Qualys SSL Labs ett bra verktyg.


    Cookies

    Detta test identifierar och presenterar de cookies som sätts av webbservern. Det kontrollerar till exempel att de är markerade som Secure, vilket innebär att de bara skickas över krypterade anslutningar.

    Testet granskar även andra attribut:

    AttributBeskrivning
    SecureCookien skickas bara över HTTPS
    HttpOnlyCookien kan inte läsas via JavaScript (skydd mot XSS)
    SameSiteStyr om cookien ska skickas med när anropet kommer från en annan webbplats (skydd mot CSRF).
    PathAnger vilken sökväg cookien gäller för
    Expires / Max-AgeAnger hur länge cookien är giltig

    HTTP Content

    Detta test kontrollerar att allt länkat innehåll, till exempel bilder, stylesheets och JavaScript-filer, hämtas via HTTPS. Om en krypterad webbplats laddar resurser över HTTP uppstår så kallat mixed content, vilket kan försvaga säkerheten.


    Strict Transport Security

    HTTP Strict Transport Security (HSTS) är en säkerhetsfunktion som talar om för webbläsare att alltid ansluta till webbplatsen via krypterad HTTPS.

    Webbservern konfigureras att skicka med en särskild header:

    Strict-Transport-Security: max-age=31536000; includeSubDomains

    Headern talar om för webbläsaren att inte försöka ansluta via HTTP under den angivna tidsperioden (max-age) och, om includeSubDomains används, även tillämpa regeln på alla subdomäner.

    HSTS skyddar mot så kallade nedgraderingsattacker, där en angripare försöker lura webbläsaren att ansluta till webbplatsen okrypterat.

    ⚠️ Viktigt: Webbläsaren sparar policyn första gången den ansluter till webbplatsen via HTTPS och tar emot HSTS-headern. Innan dess kan en angripare försöka genomföra en nedgraderingsattack.

    Tänk också på att policyn sparas i webbläsaren och normalt tas bort om man väljer att rensa all webbplatsdata.

    För att även skydda första besöket kan man använda HSTS preload. Jag kommer återkomma till detta i en kommande artikel, men vill du läsa mer redan nu finns information på https://hstspreload.org/.


    Content Security Policy

    Content Security Policy (CSP) är en HTTP-header som talar om för webbläsaren varifrån innehåll, till exempel bilder, stylesheets och Javascript, får laddas.

    Syftet är att minska risken för attacker som cross-site scripting (XSS) genom att begränsa vilka resurser som får köras eller laddas på sidan.

    Min CSP-header ser ut ungefär såhär:

    default-src 'self';
    script-src 'self' 'unsafe-inline';
    style-src 'self' 'unsafe-inline';
    img-src 'self' data: https://secure.gravatar.com https://*.w.org;
    font-src 'self' data: https://fonts.gstatic.com https://s0.wp.com;
    frame-ancestors 'self';
    report-uri https://ezj9gpjt.uriports.com/reports/report;

    Varje direktiv anger varifrån en viss typ av resurser får laddas. Till exempel innebär script-src 'self' 'unsafe-inline' att JavaScript får laddas från den egna domänen samt köras som inline-kod.

    Ett bra verktyg för att analysera och granska CSP är https://csp-evaluator.withgoogle.com.

    ⚠️ Viktigt: Helst vill man undvika unsafe-inline eftersom det kan användas för XSS-attacker. Men WordPress använder många inline-script och inline-styles som är svåra att lösa utan detta direktiv.


    Subresource Integrity

    Subresource Integrity (SRI) är en säkerhetsfunktion som gör det möjligt för webbläsaren att verifiera att en extern resurs inte har blivit manipulerad.

    Många webbplatser använder Content Delivery Networks (CDN) för att hämta externa resurser. Ett exempel kan se ut så här:

    <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>

    SRI fungerar genom att man lägger till en hash i <script>– eller <link>-taggen. När webbläsaren laddar resursen beräknar den själv en hash och jämför med den angivna. Om inte värdena matchar blockerar webbläsaren filen.

    <script 
      src="https://code.jquery.com/jquery-4.0.0.min.js"
      integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux1DPZWS9Vyhi3F7S3w7Dnk3a1JpN96"
      crossorigin="anonymous">
    </script>

    Om du vill läsa mer om SRI är en bra webbplats https://srihash.org/.


    Frame Options, XSS Protection & Content Type Options

    Dessa tester gäller säkerhets-headers som är rekommenderade att konfigurera på webbservern.

    X-Frame-Options används för att tala om för webbläsaren om din webbplats får visas inuti en <iframe>. Då kan angripare bädda in din webbplats i en skadlig sida och lura användare att klicka på något de inte ser – en attack som kallas clickjacking.

    Denna header kan konfigureras med något av följande värden:

    • DENY – sidan får aldrig bäddas in
    • SAMEORIGIN – får endast bäddas in från samma domän

    Precis som tidigare valde jag att konfigurerade detta i min .htaccess-fil:

    <IfModule mod_headers.c>
            Header always set X-Frame-Options "SAMEORIGIN"
    </IfModule>

    X-XSS-Protection är en header som tidigare användes för att aktivera webbläsarens inbyggda skydd mot vissa typer av XSS-attacker. Idag är denna funktion föråldrad och borttagen (eller inaktiverad) i moderna webbläsare.

    Hardenize föreslår att denna header ska sättas till ”0” för att inaktivera funktionen. Men den generella rekommendationen i dag är att inte använda headern alls, och i stället konfigurera CSP.

    Den sista header, X-Content-Type-Options, används för att förhindra så kallad MIME-sniffing.

    <IfModule mod_headers.c>
            Header always set X-Content-Type-Options "nosniff"
    </IfModule>

    Genom att sätta denna header talar man om för webbläsaren att strikt följa angiven Content-Type och inte försöka göra egna tolkningar.

    Detta är en enkel och rekommenderad säkerhetsåtgärd som bör vara aktiverad på alla webbplatser.

    ⬆️ Tillbaka till innehållsförteckningen


    Sammanfattning

    Genom att gå igenom dessa tester och åtgärda de brister som upptäcktes har jag nu uppnått “grönt” resultat på nästan samtliga tester hos både Hardenize och Internet.nl. Det enda undantaget är TLS Key Exchange Parameters, vilket jag inte kan påverka så länge jag använder webbhotellets färdigkonfigurerade miljö.

    Den här guiden visar hur relativt små justeringar kan göra stor skillnad för den externa attackytan. Och förhoppningsvis kan genomgången fungera som vägledning för dig som också vill stärka din säkerhet och få bättre kontroll över din attackyta.