Grenprædiktoren er en kritisk komponent i moderne CPU-arkitekturer designet til at forbedre ydeevnen ved at spekulere i retningen af greninstruktioner (f.eks. if-else-udsagn), før de løses. Denne spekulation gør det muligt for CPU'en at forudhente og udføre instruktioner langs den forudsagte sti, og derved reducere den opfattede latens og forbedre den samlede gennemstrømning. Denne ydeevneoptimering introducerer dog potentielle sårbarheder, der kan udnyttes i CPU-timingangreb, især i forbindelse med lækage af følsom information.
Branch-forudsigelse fungerer ved at vedligeholde en historie med filialresultater og bruge denne historie til at forudsige fremtidige filialer. Når en greninstruktion stødes på, bruger forudsigeren disse historiske data til at gætte, om grenen vil blive taget eller ej. Hvis forudsigelsen er korrekt, fortsætter CPU'en eksekveringen uden afbrydelse. Hvis den er forkert, skal CPU'en rulle tilbage og udføre den korrekte sti, hvilket medfører en ydeevnestraf. Denne straf, selvom den er lille, kan måles og udnyttes af angribere.
Angribere kan manipulere grenprædiktoren for at skabe en målbar timingforskel mellem korrekt og forkert forudsagte grene. Denne forskel kan bruges til at udlede et programs eksekveringssti, som igen kan afsløre følsom information. Et af de mest kendte eksempler på et sådant angreb er Spectre-sårbarheden, som udnytter spekulativ eksekvering og brancheforudsigelse for at få adgang til uautoriserede hukommelsesplaceringer.
I et typisk Spectre-angreb træner angriberen først grenprædiktoren til at følge et bestemt mønster. Denne træningsfase involverer at udføre en sekvens af greninstruktioner, der betinger forudsigeren til at foretage en bestemt forudsigelse. Når prædiktoren er trænet, udfører angriberen et offerkodesegment, der inkluderer en gren, der er afhængig af hemmelige data. Hvis forudsigeren laver en forkert forudsigelse baseret på angriberens træning, vil CPU'en spekulativt udføre instruktioner, der tilgår hukommelse baseret på de hemmelige data. Selvom disse spekulative instruktioner til sidst kasseres, efterlader de spor i CPU'ens cache.
Angriberen kan derefter måle adgangstiderne til forskellige hukommelsesplaceringer for at bestemme, hvilke data der er spekulativt tilgået. Denne teknik, kendt som et cache-timing-angreb, gør det muligt for angriberen at udlede de hemmelige data baseret på de observerede tidsforskelle. De vigtigste trin i et sådant angreb er:
1. Træning af Branch Predictor: Angriberen kører en kontrolleret sekvens af instruktioner, der påvirker grenprædiktorens tilstand. For eksempel, gentagne gange eksekvering af en greninstruktion med et konsistent resultat (f.eks. altid taget), betinger forudsigeren til at forvente dette resultat i fremtidige henrettelser.
2. Udløser spekulativ henrettelse: Angriberen kører offerkoden med en greninstruktion afhængig af hemmelige data. På grund af angriberens forudgående træning udfører grenprædiktoren spekulativt den forkerte sti, hvilket involverer adgang til hukommelse baseret på hemmelige data.
3. Måling af cache-adgangstider: Efter den spekulative eksekvering måler angriberen den tid, det tager at få adgang til bestemte hukommelsesplaceringer. Hurtigere adgangstider indikerer, at dataene er til stede i cachen, hvilket antyder, at de blev tilgået spekulativt. Ved at analysere disse timings kan angriberen udlede de hemmelige data.
For at illustrere dette med et konkret eksempel, overvej et scenarie, hvor de hemmelige data bestemmer indekset for en matrixadgang inden for en gren. Angriberen træner først grenprædiktoren til at antage en bestemt grenretning. Når offerkoden kører, udfører grenprædiktoren spekulativt array-adgangen baseret på den trænede retning. Hvis spekulationerne involverer adgang til et bestemt array-element, indlæses den tilsvarende cache-linje. Angriberen kan derefter udføre en række tidsindstillede hukommelsesadgange for at bestemme, hvilke cachelinjer der er indlæst, og derved udlede det hemmelige indeks.
At afbøde sådanne angreb involverer flere strategier. Hardwarebaserede løsninger omfatter forbedring af isolationen mellem spekulative og ikke-spekulative eksekveringsstier og sikring af, at spekulativ eksekvering ikke påvirker delte ressourcer som cachen. Softwarebaserede løsninger involverer teknikker som f.eks. indsættelse af "hegn"-instruktioner for at forhindre spekulativ eksekvering forbi bestemte punkter i koden, eller brug af konstant-tidsprogrammeringspraksis for at sikre, at eksekveringstiden ikke afhænger af hemmelige data.
Kompleksiteten og sofistikeringen af brancheprædiktorbaserede timingangreb understreger behovet for løbende forskning og udvikling inden for både hardware- og softwaresikkerhed. Efterhånden som CPU-arkitekturer fortsætter med at udvikle sig, skal strategierne til beskyttelse mod disse og andre former for sidekanalangreb også gøres.
Andre seneste spørgsmål og svar vedr CPU timing angreb:
- Hvad er nogle af de udfordringer og afvejninger, der er involveret i implementering af hardware- og softwarebegrænsninger mod timingangreb, mens systemets ydeevne bevares?
- Hvordan kan konstant-tidsprogrammering hjælpe med at mindske risikoen for timing af angreb i kryptografiske algoritmer?
- Hvad er spekulativ eksekvering, og hvordan bidrager det til moderne processorers sårbarhed over for timing af angreb som Spectre?
- Hvordan udnytter timingangreb variationer i eksekveringstid til at udlede følsomme oplysninger fra et system?
- Hvad er et tidsangreb?