Jag har ett fåtal gånger sett hur personer misstolkat hur CSRF fungerar och vad som är möjligt. Så därför tänkte jag skriva en guide som kommer ta igenom hur CSRF fungerar, hur man detekterar sårbarheten och allmän analys utav patchar och exploits.
CSRF(Cross-site request forgery)(även XSRF) är en sårbarhet som påverkar webbläsaren och en hemsidas konfiguration. Denna sårbarhet har funnits ända sedan tidigt 2000-tal men har under senare tid blivit mer populär, dels för att den har potential att göra skada men även för att den är enkel att hitta med rätt verktyg och metoder.
Beskrivning
Sårbarheten ligger som sagt dels i webbläsarens arkitektur; hur den hanterar auktorisering. Men även i en hemsidas kod; hur den tillåter att man postar utifrån en domäns ursprung.
CSRF är alltså en teknik som låter mig skicka data från en domän till en annan utan vidare auktorisering från användaren. Just auktoriseringen ligger ju i webbläsaren i form utav session cookies och cookies.
GET
Om vi skapar ett enkelt HTML-dokument med följande kod:
Och testar i vår webbläsare så kommer vi se katten och det är eftersom vi har tillstånd att få se bilden. Man kan påstå att en förfrågan skulle se ut på liknande sett:
Så vad skulle hända om samma dokument pekar på en URL som gör någonting annat, och där användaren är inloggad på sidan, dvs att webbläsaren har giltiga cookies.
Ovanstående rad kod gör samma sak som innan, men taggen försöker inte visa en bild, utan den försöker besöka en adress, och om den försöker besöka en adress som faktiskt fungerar så kommer det ju fungera, men ingen bild kommer visas i detta fall.
GET är intressant eftersom webbläsaren hämtar en URL, och i denna ser ni postfield med värden. to och value är de variabler som behövs fyllas i. Om vi redan skapar en URL med de parametrar som vi vill ha så räcker det endast med att en användare är inloggad på en hemsida för att köpet ska gå igenom.
POST
Motsatsen till GET är POST vilket innebär att man skickar data. Man besöker fortfarande en adress, men postfield finns inte längre i URL.
Detektion
Nu vet ni skillnaden mellan POST och GET och de kan göra samma sak, dvs göra så en server förstår vad vi vill. Att detektera en potentiell GET-förfrågan som är sårbar mot CSRF är enkelt, allt du behöver göra är att kolla i adressfältet i webbläsaren. Skulle du se variabler som ser ut att faktiskt göra något innehållande värden så har du hittat en CSRF.
Låt oss säga att facebook har en sårbar GET:
www.facebook.se/message.php?to=234627834834&message=push eax!!&do=send
to, message och do är allting vi behöver för att skicka ett meddelande. Så allt du behöver göra är att skicka en GET-förfrågan till denna URL så kommer man skicka push eax!! till användaren 234627834834. Och variabeln do är ju send. Som ni ser så är det väldigt enkelt att detektera en sårbar GET.
För att skriva en exploit till detta så skapar man enkelt en HTML-rad innehållande denna URL. Skulle sedan en användare vara inloggad på facebook och göra en förfrågan mot denna URL så kommer meddelandet att skickas. Det smidigaste är så klart att lägga denna HTML-kod i ett email och så fort användaren öppnar mailet så görs GET-förfrågan mot facebook och därmed skickar meddelandet.
För att kolla din POST-data så rekommenderar jag ett Plug-in till Firefox med namnet Live HTTP Header vilket låter dig se den data du skickar, samt skicka om den.
Låt oss säga att vi har en sårbar POST:
http://s18.postimg.org/xacss1kax/face.png
Som ni ser på bilden är exakt samma variabler som i ovanstående GET-förfrågan, men denna gång hittar vi datan i POST-fältet. Skulle jag nu trycka på knappen "Replay" så kommer detta meddelande skickas och detta är eftersom inga tokens används, men jag ska förklara det mer lite senare.
Att skapa en exploit för att skicka POST-data är nästan lika enkelt, men vi behöver Javascript.
Skulle ni spara ovanstående HTML-kod i ett dokuemt och öppna i en webbläsare så kommer alltså to=234627834834&message=push eax!!&do=send att skickas till www.facebook.se/message.php.
Åtgärd
Att åtgärda CSRF är enkelt, men något de flesta inte orkar med. Generellt sätt är det bättre att använda POST istället för GET, men skulle det behövas GET så fungerar det att använda sessions vilket kommer förhindra CSRF
När det kommer till GET så behöver man ange en session som är giltig. Utan denna session så får du helt enkelt ett error och kommer inte nå sidan.
POST kan vara lite annorlunda. Man kan först och främst sätta SAMEORIGIN i headern vilket innebär att man inte får tillstånd att skicka förfrågan utifrån domänens ursprung, t.ex från sida.se till facebook.se.
Flashback har den metoden att generera ett unikt stoken(Session Token) som läggs i POST-datan när du ska skicka datan. Detta stoken kontrolleras om det är samma i källkoden som i POST-datan. Jag har nämnt just detta här.
Men som ni vet så ligger inte allt ansvar på hemsidans kodare utan även användaren. RequestPolicy, NoScript och CsFire är exempel på plug-in som förhindrar att du blir drabbad utav CSRF-buggar.
Att inte använda "Håll mig inloggad" kan stoppa attacker då auktorisering kommer krävas vid en CSRF-attack.
Sammanfattning och vidareläsning
Du måste vara inloggad på en hemsida för att denna attack ska fungera. Du måste även besöka en länk.
Läs mer om CSRF:
http://en.wikipedia.org/wiki/Cross-site_request_forgery
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html
(FB) Hacka routerns firmware
(FB) Hacka routerns firmware
(FB) Hacka routerns firmware
CSRF(Cross-site request forgery)(även XSRF) är en sårbarhet som påverkar webbläsaren och en hemsidas konfiguration. Denna sårbarhet har funnits ända sedan tidigt 2000-tal men har under senare tid blivit mer populär, dels för att den har potential att göra skada men även för att den är enkel att hitta med rätt verktyg och metoder.
Beskrivning
Sårbarheten ligger som sagt dels i webbläsarens arkitektur; hur den hanterar auktorisering. Men även i en hemsidas kod; hur den tillåter att man postar utifrån en domäns ursprung.
CSRF är alltså en teknik som låter mig skicka data från en domän till en annan utan vidare auktorisering från användaren. Just auktoriseringen ligger ju i webbläsaren i form utav session cookies och cookies.
GET
Om vi skapar ett enkelt HTML-dokument med följande kod:
HTML-kod:
<img src="http://i.imgur.com/vc8wWNJ.jpg" />
Och testar i vår webbläsare så kommer vi se katten och det är eftersom vi har tillstånd att få se bilden. Man kan påstå att en förfrågan skulle se ut på liknande sett:
Kod:
GET /vc8wWNJ.jpg HTTP/1.1
Cookie: authenticated
Så vad skulle hända om samma dokument pekar på en URL som gör någonting annat, och där användaren är inloggad på sidan, dvs att webbläsaren har giltiga cookies.
HTML-kod:
<img src="http://site.com/buy.php?to=hacker@hx.se&value=700$" />
Ovanstående rad kod gör samma sak som innan, men taggen försöker inte visa en bild, utan den försöker besöka en adress, och om den försöker besöka en adress som faktiskt fungerar så kommer det ju fungera, men ingen bild kommer visas i detta fall.
Kod:
GET /buy.php?to=hacker@hx.se&value=700$ HTTP/1.1
Cookie: authenticated
GET är intressant eftersom webbläsaren hämtar en URL, och i denna ser ni postfield med värden. to och value är de variabler som behövs fyllas i. Om vi redan skapar en URL med de parametrar som vi vill ha så räcker det endast med att en användare är inloggad på en hemsida för att köpet ska gå igenom.
POST
Motsatsen till GET är POST vilket innebär att man skickar data. Man besöker fortfarande en adress, men postfield finns inte längre i URL.
Kod:
Så skulle vår header se ut om vi tryckte på "Genomför köp" t.ex. Just denna POST-data ser man inte, den sker i bakgrunden. Ni ser ju att vi besökte endast buy.php men våra variabler och värden var i POST-datan.
GET /buy.php HTTP/1.1
POST-DATA: to=hacker@hx.se&value=700$
Cookie: authenticated
Detektion
Nu vet ni skillnaden mellan POST och GET och de kan göra samma sak, dvs göra så en server förstår vad vi vill. Att detektera en potentiell GET-förfrågan som är sårbar mot CSRF är enkelt, allt du behöver göra är att kolla i adressfältet i webbläsaren. Skulle du se variabler som ser ut att faktiskt göra något innehållande värden så har du hittat en CSRF.
Låt oss säga att facebook har en sårbar GET:
www.facebook.se/message.php?to=234627834834&message=push eax!!&do=send
to, message och do är allting vi behöver för att skicka ett meddelande. Så allt du behöver göra är att skicka en GET-förfrågan till denna URL så kommer man skicka push eax!! till användaren 234627834834. Och variabeln do är ju send. Som ni ser så är det väldigt enkelt att detektera en sårbar GET.
För att skriva en exploit till detta så skapar man enkelt en HTML-rad innehållande denna URL. Skulle sedan en användare vara inloggad på facebook och göra en förfrågan mot denna URL så kommer meddelandet att skickas. Det smidigaste är så klart att lägga denna HTML-kod i ett email och så fort användaren öppnar mailet så görs GET-förfrågan mot facebook och därmed skickar meddelandet.
För att kolla din POST-data så rekommenderar jag ett Plug-in till Firefox med namnet Live HTTP Header vilket låter dig se den data du skickar, samt skicka om den.
Låt oss säga att vi har en sårbar POST:
http://s18.postimg.org/xacss1kax/face.png
Som ni ser på bilden är exakt samma variabler som i ovanstående GET-förfrågan, men denna gång hittar vi datan i POST-fältet. Skulle jag nu trycka på knappen "Replay" så kommer detta meddelande skickas och detta är eftersom inga tokens används, men jag ska förklara det mer lite senare.
Att skapa en exploit för att skicka POST-data är nästan lika enkelt, men vi behöver Javascript.
HTML-kod:
<form name="csrf" ENCTYPE="text/plain" action="www.facebook.se/message.php" method="POST"> <input type="hidden" name='to=234627834834&message=push eax!!&do=send'> </FORM> <script>document.csrf.submit();</script>
Skulle ni spara ovanstående HTML-kod i ett dokuemt och öppna i en webbläsare så kommer alltså to=234627834834&message=push eax!!&do=send att skickas till www.facebook.se/message.php.
Åtgärd
Att åtgärda CSRF är enkelt, men något de flesta inte orkar med. Generellt sätt är det bättre att använda POST istället för GET, men skulle det behövas GET så fungerar det att använda sessions vilket kommer förhindra CSRF
När det kommer till GET så behöver man ange en session som är giltig. Utan denna session så får du helt enkelt ett error och kommer inte nå sidan.
Kod:
www.facebook.se/message.php?&to=234627834834&session=8237492730428340237420348273042834ng&message=push eax!!&do=send
POST kan vara lite annorlunda. Man kan först och främst sätta SAMEORIGIN i headern vilket innebär att man inte får tillstånd att skicka förfrågan utifrån domänens ursprung, t.ex från sida.se till facebook.se.
Flashback har den metoden att generera ett unikt stoken(Session Token) som läggs i POST-datan när du ska skicka datan. Detta stoken kontrolleras om det är samma i källkoden som i POST-datan. Jag har nämnt just detta här.
Men som ni vet så ligger inte allt ansvar på hemsidans kodare utan även användaren. RequestPolicy, NoScript och CsFire är exempel på plug-in som förhindrar att du blir drabbad utav CSRF-buggar.
Att inte använda "Håll mig inloggad" kan stoppa attacker då auktorisering kommer krävas vid en CSRF-attack.
Sammanfattning och vidareläsning
Du måste vara inloggad på en hemsida för att denna attack ska fungera. Du måste även besöka en länk.
Läs mer om CSRF:
http://en.wikipedia.org/wiki/Cross-site_request_forgery
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html
(FB) Hacka routerns firmware
(FB) Hacka routerns firmware
(FB) Hacka routerns firmware
__________________
Senast redigerad av .Chloe 2013-12-11 kl. 19:27.
Senast redigerad av .Chloe 2013-12-11 kl. 19:27.