LabbCybersäkerhet · Etisk hackning
0/0
Laboration

Avlyssnande proxy — hur en proxy ser din trafik

Mål: Förstå proxykonceptet, som ligger till grund för i stort sett all webbapplikationstestning, och känna till vilka försvar som finns mot avlyssning i mellanled.

Observera konceptet

En proxy är en mellanhand. I stället för att din klient pratar direkt med servern, går trafiken via proxyn, som vidarebefordrar den. Servern ser proxyns adress som avsändare, inte din.

  Klient                Proxyserver              Målserver
10.10.1.4   ───────▶   192.168.4.2    ───────▶   exempel.se
                       (ser och kan
                        ändra allt
                        som passerar)
Vad koden gör — förklaring rad för rad

Inte kod, utan en ritning. Den visar var en proxy sitter: all trafik mellan dig och målservern passerar genom den, vilket är varför den kan läsa och ändra allt som går förbi.

Klient
Din dator, med sin adress i nätet.
Proxyserver
Mellanhanden. Målservern ser proxyns adress som avsändare, inte din.
───▶
Pilarna visar trafikens riktning. Observera att det inte finns någon pil direkt från klient till målserver.

Detta är inte i sig något skadligt — proxyservrar används dagligen för caching, filtrering, lastbalansering och företagsbrandväggar. Men samma egenskap som gör en proxy användbar, nämligen att allt passerar genom den, gör den också till en position där trafik kan läsas och ändras.

Vid auktoriserad webbapplikationstestning används en avlyssnande proxy (Burp Suite eller OWASP ZAP) medvetet: testaren placerar den mellan sin egen webbläsare och applikationen för att kunna se exakt vad applikationen skickar och tar emot. Det är så man upptäcker att en applikation litar på data som egentligen kommer från klienten och därmed kan manipuleras.

Praktiskt moment

Konfigurera OWASP ZAP eller Burp Suite Community i din labbmiljö och ställ in webbläsaren att gå via proxyn. Installera proxyns CA-certifikat i webbläsaren så att även HTTPS-trafik kan visas.

Surfa till din labbapplikation och studera i proxyns historik:

  • Vilka fält skickas som webbläsaren inte visar? (dolda formulärfält, kakor, headers)
  • Vilka värden skickas som applikationen rimligen borde bestämma själv på serversidan? (priser, roller, användar-ID:n, rabatter)

Det sista är kärnan: allt som kommer från klienten är data som användaren kontrollerar, oavsett om gränssnittet ser låst ut.

Bygg försvaret

Två olika försvarsfrågor hör hemma här.

1. Mot proxyavlyssning i transporten: TLS (Lab 1) gör att en passiv mellanhand inte kan läsa innehållet. För att en proxy ska kunna läsa HTTPS måste dess certifikat vara betrott av klienten — vilket är precis varför du var tvungen att installera ZAP:s certifikat manuellt. Certificate pinning i mobilappar tar detta ett steg längre: appen accepterar bara ett specifikt, förväntat certifikat och vägrar ansluta även om operativsystemet litar på ett annat.

2. Mot manipulerad klientdata — det viktigare försvaret: Applikationen får aldrig lita på värden som kommer från klienten. Mönstret ser ut så här:

# Sårbart: priset kommer från klienten
def checkout(request):
    pris = request.POST["pris"]          # användaren kan sätta vad som helst
    debitera(request.user, pris)

# Säkert: klienten anger VAD, servern avgör HUR MYCKET
def checkout(request):
    produkt_id = request.POST["produkt_id"]
    produkt = Produkt.objects.get(id=produkt_id)
    debitera(request.user, produkt.pris)  # priset hämtas på serversidan
Vad koden gör — förklaring rad för rad

Två versioner av samma funktion i Python — först den sårbara, sedan den säkra. Skillnaden är var priset kommer ifrån. Det är kursens viktigaste princip i sex rader kod.

def checkout(request):
def betyder "definiera en funktion". En funktion är ett namngivet recept som kan köras när som helst. Här heter receptet checkout och tar emot ett anrop från en besökare, kallat request.
request.POST["pris"]
Hämtar fältet som hette pris ur det besökaren skickade in. Problemet: besökaren bestämmer helt vad som står där.
# Sårbart / # Säkert
Kommentarer. Raden med # körs inte, den förklarar bara.
Produkt.objects.get(id=produkt_id)
Slår upp produkten i databasen utifrån dess id-nummer. Nu är det databasen som talar om vad produkten är.
debitera(request.user, produkt.pris)
Drar beloppet — men nu från produkt.pris, hämtat ur databasen, i stället för från det belopp besökaren skickade.

Samma princip gäller roller (is_admin får aldrig komma från ett formulärfält), rabatter, lagersaldon och behörigheter.

Verifiera och dokumentera

Gå igenom din egen eller en exempelapplikations anrop och gör en lista över varje fält som skickas från klienten. För varje fält: bestämmer servern detta värde själv, eller litar den på klienten? Fält i den andra kategorin är kandidater för granskning.

Reflektionsfrågor: Varför kan en avlyssnande proxy visa HTTPS-trafik i ditt labb, men inte mot en godtycklig sajt på internet? Vad säger det om vem man måste lita på i en certifikatkedja?


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.

1Varför måste du installera proxyns CA-certifikat i webbläsaren för att kunna se HTTPS-trafik?

2Vad är det viktigaste försvaret mot att en användare manipulerar data som skickas från klienten?

3Ett dolt formulärfält i HTML är ur säkerhetssynpunkt: