2008-06-06, 10:30
#1
Hur man hackar emocore.se (XSS)
Märk väl att denna text endast är skriven i utbildningssyfte - jag uppmanar inte någon att hacka emocore.se eller någon annan sida. Jag kan inte heller garantera att dessa metoder fortfarande fungerar, då Joakim (användarnamnet på sidans skapare) arbetar hårt och aktivt för att hålla sidan i bra skick och är snabb med att täppa till säkerhetshål. Bra jobbat, Joakim!
Inledning:
emocore.se är en så kallad community där varje användare har en egen sida med möjlighet att ladda upp bild på sig själv, skriva en presentation och så vidare. I sin presentation har man möjlighet att själv skriva in texter och en del HTML-kod, men det finns flera filter för att minska säkerhetsproblemen med detta.
< och > filtreras inte per automatik bort, då de används i de HTML-taggar som sidan tillåter i presentationer. Vissa HTML-taggar ersätts med annan kod eller text för att inte utgöra några säkerhetsproblem. T. ex. <script som ersätts med <script och <iframe som ersätts med <iframe .
Vidare har många DHTML-objekt så kallade händelsehanterare, eller (eng.) event handlers, t. ex. "onload", "onmouseover", och så vidare. Jag förutsätter i fortsättningen att du som läsare är någorlunda bekant med hur dessa fungerar.
Det är i praktiken nästan omöjligt att täppa till alla säkerhetshål som uppstår när man över huvud taget tillåter enskilda användare att interagera med sidan och dess innehåll - vilket dessutom är själva poängen med en community.
Ber i förväg om ursäkt för slarv, snurrighet, eventuella fel osv. Jag har skrivit allt detta i efterhand och har fått tänka tillbaka ganska mycket, skriva om skript så att ni hänger med i utvecklingen och så vidare.
Hacket - tillvägagångssätt:
Jag började med att registrera en användare, surfa runt på sidan och bekanta mig med den lite. Detta är grundläggande och bör i de flesta fall vara första steget när man vill hacka en sida eller hitta dess säkerhetsbrister - bekanta dig med sidan och hur den bearbetar data, så kan du (med erfarenhet nog) lista ut många av de inre mekanismer som pågår.
I presentationen var jag fri att skriva in precis vad jag ville, till och med tecken som inte går att visa i vanlig text. Dessa sparades precis som de skrevs in i presentationen, men filtret tog bort och ersatte vissa strängar när presentationen visades. Jag började med att skriva in några olika HTML-taggar, lite olika HTML-relaterade tecken och så vidare, för att se hur filtret arbetade. < och > släpptes igenom, men vissa HTML-taggar eller tecken ersattes med annan text. Jag fortsatte med att fylla presentationen med alla DHTML-händelser jag kunde komma på:
onactivate
onblur
onclick
onfinish
onfocus
onkeydown
onload
onmouseover
onmouseup
+ ett helt gäng till.
Jag sparade det hela och besökte min egen presentation. Vad hade filtret gjort? Det hade lagt in ett mellanslag mellan "on" och namnet på händelsen i många fall. "onload" blev "on load", "onblur" blev "on blur", "onclick" blev "on click" och så vidare. Nästan alla de vanliga händelserna som går att utnyttja vid en XSS-attack filtrerades och skrevs om. Filtret hade dessutom bearbetat strängarna oavsett om de låg i HTML-taggar eller inte; det räckte alltså med att bara skriva "onload" var som helst i presentationen så ändrades det till "on load". Detta säger en del om hur simpelt filtret är, och får mig att tro att det i själva verket bara utgörs av en bunt funktioner som ersätter strängar med andra - dvs inte alls någon mer avancerad form av pattern matching.
T. ex. skulle filtret kunna se ut så här:
Men! "onfinish" rördes inte!
När inträffar onfinish då? Jo, onfinish inträffar när texten i en <marquee> slutat rulla. När den har loopat klart alltså. Vad gör filtret med <marquee>, tro? Tas det bort?
Jag skrev in <marquee>text</marquee> i presentationskoden, sparade och besökte min egen presentation. Alldeles riktigt rullade texten om och om igen över skärmen. Här hade jag en säkerhetsbrist; en möjlighet att köra Java-skript hos alla som besökte min presentation. Eller?
Jag testade; skrev in <marquee loop=1 onfinish="alert('du är bäst');"></marquee> i presentationskoden, sparade och besökte min egen presentation. Alldeles riktigt kom nu en fin meddelanderuta upp med texten "du är bäst". Jag svarade bara med att klicka "ok" - jag är ju trots allt ganska van att få höra detta. Notera för övrigt "loop=1", det är viktigt för att marquee:n ska sluta loopa. Man ställer alltså på det viset in hur många gånger den ska rulla innan onfinish körs. Utan loop-attributet slutar den aldrig, loop=1 så rullar den en gång, loop=10 så rullar den 10 gånger och så vidare. Om den får loopa för evigt (så som den normalt gör, utan loop-attributet) så inträffar aldrig onfinish. Vi låter den loopa en gång, sen inträffar onfinish och skriptet körs.
Ok, nu började det roliga. Vad ville jag göra? Jag ville inte förstöra sidans funktion - det är onödigt och elakt. Men jag ville ändå göra ett spännande och busigt hack, som på sin höjd kunde vara irriterande för andra.
Hmm, vad sägs om ett skript som kopierar sig själv till alla andra som besöker min presentation. Och som kopierar sig vidare till alla andra som besöker mina besökares presentationer. En så kallad "worm" - programkod som sprider sig själv vidare. Det låter som en kul idé. Men hallå, den måste ju göra något mer? Den kan inte bara sprida sig hejdlöst?
Ok, jag fick en idé. Kanske en tramsig och barnslig idé, men samtidigt var jag försiktig med att inte göra något som kunde förstöra sidans funktionalitet. Vad sägs om att skriptet efter ett visst datum och en viss tid byter namn på användaren (inte användarnamn, utan "riktigt namn") till "Göran Persson". Och att det byter e-mail på alla användare till en jag registrerat, om jag nu händelsevis skulle få för mig att jag har glömt lösenordet till alla infekterade användare på sidan. Funktionen för att återställa sitt lösenord kräver på emocore.se bara e-mail, så om alla har samma kan jag bara skriva in mailen jag registrerat och glatt se på när lösenorden rullar in.
Det kör vi på! Så får det bli! Let's börja!
Märk väl att denna text endast är skriven i utbildningssyfte - jag uppmanar inte någon att hacka emocore.se eller någon annan sida. Jag kan inte heller garantera att dessa metoder fortfarande fungerar, då Joakim (användarnamnet på sidans skapare) arbetar hårt och aktivt för att hålla sidan i bra skick och är snabb med att täppa till säkerhetshål. Bra jobbat, Joakim!
Inledning:
emocore.se är en så kallad community där varje användare har en egen sida med möjlighet att ladda upp bild på sig själv, skriva en presentation och så vidare. I sin presentation har man möjlighet att själv skriva in texter och en del HTML-kod, men det finns flera filter för att minska säkerhetsproblemen med detta.
< och > filtreras inte per automatik bort, då de används i de HTML-taggar som sidan tillåter i presentationer. Vissa HTML-taggar ersätts med annan kod eller text för att inte utgöra några säkerhetsproblem. T. ex. <script som ersätts med <script och <iframe som ersätts med <iframe .
Vidare har många DHTML-objekt så kallade händelsehanterare, eller (eng.) event handlers, t. ex. "onload", "onmouseover", och så vidare. Jag förutsätter i fortsättningen att du som läsare är någorlunda bekant med hur dessa fungerar.
Det är i praktiken nästan omöjligt att täppa till alla säkerhetshål som uppstår när man över huvud taget tillåter enskilda användare att interagera med sidan och dess innehåll - vilket dessutom är själva poängen med en community.
Ber i förväg om ursäkt för slarv, snurrighet, eventuella fel osv. Jag har skrivit allt detta i efterhand och har fått tänka tillbaka ganska mycket, skriva om skript så att ni hänger med i utvecklingen och så vidare.
Hacket - tillvägagångssätt:
Jag började med att registrera en användare, surfa runt på sidan och bekanta mig med den lite. Detta är grundläggande och bör i de flesta fall vara första steget när man vill hacka en sida eller hitta dess säkerhetsbrister - bekanta dig med sidan och hur den bearbetar data, så kan du (med erfarenhet nog) lista ut många av de inre mekanismer som pågår.
I presentationen var jag fri att skriva in precis vad jag ville, till och med tecken som inte går att visa i vanlig text. Dessa sparades precis som de skrevs in i presentationen, men filtret tog bort och ersatte vissa strängar när presentationen visades. Jag började med att skriva in några olika HTML-taggar, lite olika HTML-relaterade tecken och så vidare, för att se hur filtret arbetade. < och > släpptes igenom, men vissa HTML-taggar eller tecken ersattes med annan text. Jag fortsatte med att fylla presentationen med alla DHTML-händelser jag kunde komma på:
onactivate
onblur
onclick
onfinish
onfocus
onkeydown
onload
onmouseover
onmouseup
+ ett helt gäng till.
Jag sparade det hela och besökte min egen presentation. Vad hade filtret gjort? Det hade lagt in ett mellanslag mellan "on" och namnet på händelsen i många fall. "onload" blev "on load", "onblur" blev "on blur", "onclick" blev "on click" och så vidare. Nästan alla de vanliga händelserna som går att utnyttja vid en XSS-attack filtrerades och skrevs om. Filtret hade dessutom bearbetat strängarna oavsett om de låg i HTML-taggar eller inte; det räckte alltså med att bara skriva "onload" var som helst i presentationen så ändrades det till "on load". Detta säger en del om hur simpelt filtret är, och får mig att tro att det i själva verket bara utgörs av en bunt funktioner som ersätter strängar med andra - dvs inte alls någon mer avancerad form av pattern matching.
T. ex. skulle filtret kunna se ut så här:
Kod:
<?php
$pres_code = str_replace("onclick, "on click", $pres_code);
$pres_code = str_replace("onload", "on load", $pres_code);
// osv...
?>
Men! "onfinish" rördes inte!
När inträffar onfinish då? Jo, onfinish inträffar när texten i en <marquee> slutat rulla. När den har loopat klart alltså. Vad gör filtret med <marquee>, tro? Tas det bort?
Jag skrev in <marquee>text</marquee> i presentationskoden, sparade och besökte min egen presentation. Alldeles riktigt rullade texten om och om igen över skärmen. Här hade jag en säkerhetsbrist; en möjlighet att köra Java-skript hos alla som besökte min presentation. Eller?
Jag testade; skrev in <marquee loop=1 onfinish="alert('du är bäst');"></marquee> i presentationskoden, sparade och besökte min egen presentation. Alldeles riktigt kom nu en fin meddelanderuta upp med texten "du är bäst". Jag svarade bara med att klicka "ok" - jag är ju trots allt ganska van att få höra detta. Notera för övrigt "loop=1", det är viktigt för att marquee:n ska sluta loopa. Man ställer alltså på det viset in hur många gånger den ska rulla innan onfinish körs. Utan loop-attributet slutar den aldrig, loop=1 så rullar den en gång, loop=10 så rullar den 10 gånger och så vidare. Om den får loopa för evigt (så som den normalt gör, utan loop-attributet) så inträffar aldrig onfinish. Vi låter den loopa en gång, sen inträffar onfinish och skriptet körs.
Ok, nu började det roliga. Vad ville jag göra? Jag ville inte förstöra sidans funktion - det är onödigt och elakt. Men jag ville ändå göra ett spännande och busigt hack, som på sin höjd kunde vara irriterande för andra.
Hmm, vad sägs om ett skript som kopierar sig själv till alla andra som besöker min presentation. Och som kopierar sig vidare till alla andra som besöker mina besökares presentationer. En så kallad "worm" - programkod som sprider sig själv vidare. Det låter som en kul idé. Men hallå, den måste ju göra något mer? Den kan inte bara sprida sig hejdlöst?
Ok, jag fick en idé. Kanske en tramsig och barnslig idé, men samtidigt var jag försiktig med att inte göra något som kunde förstöra sidans funktionalitet. Vad sägs om att skriptet efter ett visst datum och en viss tid byter namn på användaren (inte användarnamn, utan "riktigt namn") till "Göran Persson". Och att det byter e-mail på alla användare till en jag registrerat, om jag nu händelsevis skulle få för mig att jag har glömt lösenordet till alla infekterade användare på sidan. Funktionen för att återställa sitt lösenord kräver på emocore.se bara e-mail, så om alla har samma kan jag bara skriva in mailen jag registrerat och glatt se på när lösenorden rullar in.
Det kör vi på! Så får det bli! Let's börja!