Trafikanalys — varför okrypterade protokoll inte håller
Observera
Starta Wireshark i Kali och börja fånga trafik på labbgränssnittet. Logga in på en testapplikation i labbet över vanlig HTTP. Stoppa fångsten och använd filtret:
http.request.method == "POST"
Vad koden gör — förklaring rad för rad
Detta är inte kod utan ett filter du skriver i Wiresharks sökfält. Det döljer all trafik utom den du vill titta på.
- http.request.method
- Pekar ut en viss egenskap hos ett nätverkspaket: vilken sorts HTTP-begäran det är.
- == "POST"
- Två likhetstecken betyder "är lika med". POST är den sorts begäran som skickas när du fyller i ett formulär — alltså en inloggning.
Öppna paketet och expandera HTML Form URL Encoded. Dina inloggningsuppgifter står där i klartext.
Gör sedan om samma sak mot en tjänst som använder HTTPS, och filtrera på tls. Du ser att en anslutning sker, du ser serverns certifikat i handskakningen, men innehållet är obegripligt.
Analysera grundorsaken
HTTP, FTP, Telnet och äldre SMTP skickar allt innehåll som läsbar text. Vem som helst som kan läsa trafiken på vägen — någon på samma wifi, en komprometterad router, en nätverksoperatör — ser allt. Problemet är inte en bugg, utan en designegenskap hos protokoll som utformades innan kryptering var standard.
Fundera på var i kedjan trafiken faktiskt passerar: klient → accesspunkt → router → internetleverantör → ett antal mellanliggande nät → server. Varje steg är en plats där trafiken kan läsas.
Bygg försvaret
1. Tvinga TLS på webbservern. Omdirigera all HTTP till HTTPS. Exempel för nginx:
server {
listen 80;
server_name exempel.se;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name exempel.se;
ssl_certificate /etc/letsencrypt/live/exempel.se/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exempel.se/privkey.pem;
# Tillåt endast moderna protokollversioner
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
}
Vad koden gör — förklaring rad för rad
En nginx-konfigurationsfil. Det här är inte ett program som körs rad för rad utan en inställningsfil som webbservern läser när den startar. Blocket säger: ta emot vanlig HTTP och skicka genast vidare besökaren till HTTPS.
- server { ... }
- Ett block med inställningar för en webbplats. Klammerparenteserna håller ihop det som hör till samma block.
- listen 80;
- Port 80 är den port vanlig, okrypterad HTTP använder. Här säger servern att den lyssnar där.
- return 301 https://$host$request_uri;
- 301 betyder "flyttad permanent". Servern svarar aldrig på frågan — den skickar besökaren till samma adress fast med https. $host och $request_uri är platshållare som fylls i med webbplatsens namn och sidan besökaren bad om.
- listen 443 ssl;
- Port 443 är HTTPS-porten. ssl slår på krypteringen.
- ssl_certificate
- Sökvägen till webbplatsens certifikat, den fil som bevisar för besökarens webbläsare att servern är den den utger sig för att vara.
- ssl_protocols TLSv1.2 TLSv1.3;
- Tillåter bara de två moderna versionerna av krypteringsprotokollet. Äldre versioner har kända svagheter och utesluts här.
2. Lägg till HSTS. HTTP Strict Transport Security talar om för webbläsaren att den aldrig ska försöka nå sajten över HTTP igen, vilket stänger luckan vid allra första anslutningen efter en omdirigering:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Vad koden gör — förklaring rad för rad
En enda rad som läggs till i nginx-konfigurationen. Den skickar med ett extra meddelande i varje svar, där servern instruerar webbläsaren att aldrig mer försöka nå sajten över okrypterad HTTP.
- add_header
- Lägger till en rad extra information i svaret till webbläsaren. Besökaren ser den inte, men webbläsaren läser den.
- max-age=31536000
- Hur länge webbläsaren ska komma ihåg detta, räknat i sekunder. 31 536 000 sekunder är ett år.
- includeSubDomains
- Regeln gäller även alla underdomäner, till exempel blogg.exempel.se.
- always
- Skicka med huvudet i alla svar, även felsvar. Utan det utelämnas det ibland.
3. Märk kakor korrekt. En sessionskaka utan Secure kan läcka över HTTP även om sajten i övrigt använder HTTPS:
Set-Cookie: session=...; Secure; HttpOnly; SameSite=Lax
Vad koden gör — förklaring rad för rad
Så här ser det ut när en server ger webbläsaren en kaka. En kaka är en liten textbit som webbläsaren sparar och skickar tillbaka vid varje besök — det är så sajten kommer ihåg att du är inloggad. Orden efter semikolonen är regler för hur kakan får hanteras.
- session=...
- Själva värdet. I verkligheten en lång slumpmässig sträng som identifierar just din inloggning.
- Secure
- Kakan får bara skickas över HTTPS. Utan denna kan den läcka ut i klartext.
- HttpOnly
- JavaScript på sidan får inte läsa kakan. Det begränsar skadan om någon lyckas köra kod på sidan.
- SameSite=Lax
- Kakan skickas inte med när en annan webbplats gör anrop till din. Skyddar mot att någon lurar din inloggade webbläsare att utföra handlingar.
Secure = skickas bara över HTTPS. HttpOnly = kan inte läsas av JavaScript (relevant i Lab 4). SameSite = begränsar att kakan skickas med vid anrop från andra sajter.
Verifiera
Fånga trafiken igen efter ändringen och bekräfta att inloggningen nu sker över TLS. Kontrollera också att omdirigeringen fungerar:
curl -I http://exempel.se
# Förväntat: HTTP/1.1 301 Moved Permanently + Location: https://...
Vad koden gör — förklaring rad för rad
Ett terminalkommando som kontrollerar att omdirigeringen fungerar. Du ber servern om startsidan över vanlig HTTP och tittar på vad den svarar.
- curl
- Ett verktyg som hämtar en webbadress från kommandoraden, ungefär som en webbläsare utan fönster.
- -I
- Stort i. Betyder "hämta bara svarshuvudena, inte själva sidan". Det är huvudena vi vill se.
- http://
- Observera att vi medvetet frågar över okrypterad HTTP — det är just den vägen vi testar.
Dokumentera
Skriv ett fynd enligt mallen: Rubrik, Allvarlighetsgrad, Beskrivning, Bevis (skärmbild från Wireshark med lösenordet maskerat), Rekommendation. Maskera alltid känsliga uppgifter i rapportbevis — det är standard i riktiga uppdrag.
Reflektionsfrågor: Varför räcker det inte att bara "erbjuda" HTTPS utan att tvinga det? Vad är det specifika problem som HSTS löser och som en 301-omdirigering inte löser?
Kunskapskontroll
Välj ett svar per fråga. Du får återkoppling direkt, och avsnittet markeras som klart när alla frågor är besvarade.
1Du fångar en HTTP-inloggning i Wireshark och filtrerar på POST-anrop. Var finns lösenordet?
2Vilket problem löser HSTS som en vanlig 301-omdirigering inte löser?
3Vad gör flaggan `Secure` på en kaka?
Traffic analysis — why plaintext protocols fail
Observe
Start Wireshark in Kali and begin capturing on the lab interface. Log in to a test application over plain HTTP. Stop the capture and apply the filter:
http.request.method == "POST"
What this code does — line by line
This is not code but a filter you type into Wireshark's search bar. It hides all traffic except what you want to look at.
- http.request.method
- Points at a particular property of a network packet: which kind of HTTP request it is.
- == "POST"
- Two equals signs mean "is equal to". POST is the kind of request sent when you submit a form — a login, for instance.
Open the packet and expand HTML Form URL Encoded. Your credentials are sitting there in plaintext.
Now repeat the exercise against a service using HTTPS and filter on tls. You see a connection being established, you see the server certificate in the handshake — but the content is unreadable.
Analyze the root cause
HTTP, FTP, Telnet and legacy SMTP send everything as readable text. Anyone able to read the traffic along the path — someone on the same wifi, a compromised router, a network operator — sees all of it. This is not a bug but a design property of protocols created before encryption was standard.
Think about where the traffic actually travels: client → access point → router → ISP → several intermediate networks → server. Every hop is a place the traffic can be read.
Build the defense
1. Enforce TLS at the web server. Redirect all HTTP to HTTPS. Example for nginx:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Allow only modern protocol versions
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
}
What this code does — line by line
An nginx configuration file. This is not a program that runs line by line but a settings file the web server reads at startup. The block says: accept plain HTTP and immediately send the visitor on to HTTPS.
- server { ... }
- A block of settings for one website. The curly braces hold together everything belonging to that block.
- listen 80;
- Port 80 is the port plain, unencrypted HTTP uses. Here the server says it is listening there.
- return 301 https://$host$request_uri;
- 301 means "moved permanently". The server never answers the question — it sends the visitor to the same address but with https. $host and $request_uri are placeholders filled in with the site's name and the page the visitor asked for.
- listen 443 ssl;
- Port 443 is the HTTPS port. ssl switches on the encryption.
- ssl_certificate
- The path to the site's certificate, the file proving to the visitor's browser that the server is who it claims to be.
- ssl_protocols TLSv1.2 TLSv1.3;
- Permits only the two modern versions of the encryption protocol. Older versions have known weaknesses and are excluded here.
2. Add HSTS. HTTP Strict Transport Security tells the browser never to attempt the site over HTTP again, closing the gap on that very first connection before a redirect takes effect:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
What this code does — line by line
A single line added to the nginx configuration. It attaches an extra message to every response, instructing the browser never again to try reaching the site over unencrypted HTTP.
- add_header
- Adds a line of extra information to the response sent to the browser. The visitor never sees it, but the browser reads it.
- max-age=31536000
- How long the browser should remember this, counted in seconds. 31,536,000 seconds is one year.
- includeSubDomains
- The rule covers every subdomain too, for example blog.example.com.
- always
- Send the header on every response, including error responses. Without it, it is sometimes omitted.
3. Flag cookies correctly. A session cookie without Secure can leak over HTTP even if the site otherwise uses HTTPS:
Set-Cookie: session=...; Secure; HttpOnly; SameSite=Lax
What this code does — line by line
This is what it looks like when a server hands the browser a cookie. A cookie is a small piece of text the browser stores and sends back on each visit — it is how the site remembers you are logged in. The words after the semicolons are rules for how the cookie may be handled.
- session=...
- The value itself. In reality a long random string identifying your particular login.
- Secure
- The cookie may only be sent over HTTPS. Without this it can leak in the clear.
- HttpOnly
- JavaScript on the page may not read the cookie. That limits the damage if someone manages to run code on the page.
- SameSite=Lax
- The cookie is not sent when another website makes requests to yours. Protects against someone tricking your logged-in browser into performing actions.
Secure = only sent over HTTPS. HttpOnly = not readable by JavaScript (relevant in Lab 4). SameSite = limits the cookie being sent on cross-site requests.
Verify
Capture the traffic again after the change and confirm the login now happens over TLS. Also confirm the redirect works:
curl -I http://example.com
# Expected: HTTP/1.1 301 Moved Permanently + Location: https://...
What this code does — line by line
A terminal command checking that the redirect works. You ask the server for the home page over plain HTTP and look at what it answers.
- curl
- A tool that fetches a web address from the command line, rather like a browser without a window.
- -I
- Capital i. Means "fetch only the response headers, not the page itself". The headers are what we want to see.
- http://
- Note that we deliberately ask over unencrypted HTTP — that is precisely the path being tested.
Document
Write the finding using the template: Title, Severity, Description, Evidence (Wireshark screenshot with the password redacted), Recommendation. Always redact sensitive values in report evidence — this is standard practice in real engagements.
Reflection: Why is "offering" HTTPS without enforcing it insufficient? What specific problem does HSTS solve that a 301 redirect does not?
Knowledge check
Pick one answer per question. You get feedback immediately, and the unit is marked complete once every question is answered.
1You capture an HTTP login in Wireshark and filter on POST requests. Where is the password?
2What problem does HSTS solve that a plain 301 redirect does not?
3What does the `Secure` flag on a cookie do?