tags that are to be handled by the
functions. They are typically placed underneath the picture of the "friend" and passes the specific friendID of the the friend to the OnlineNow
functions. An example of such a tag is as follows:
The ID of these tags follows the format of 'UserDataNodeN' - where the value of N increases in sequential order from 0 to (the number of tags - 1).
At the end of the HTML the OnlineNow mechanism is called which finds all the tags, parses out all the UserIDs specified in the class property and
passes them to an iframe which calls on a web-application that returns a true/false value specifying whether that FriendID is found to be
"online now". The flow of code proceeds to then find all of these friendIDs that were found to be online and set the DIV tag's innerHTML to display
an image that shows the user is online within the browser display.
The OnlineNow Vulnerability:
There is a script injection vulnerability within this mechanism specifically found during the searching and parsing of the
tags. I
will be extensively referencing the function _OnlineNowNodeParser_locateNodes() found in OnlineNowNodeParser.js. A copy of the function will be
placed here for such reference:
function _OnlineNowNodeParser_locateNodes()
{
var CurrentNode = null;
var i = 0;
while ((CurrentNode = document.getElementById("UserDataNode" + i)) != null)
{
NodeIndex = this.NodeArray.length;
this.NodeArray[NodeIndex] = new Object();
this.NodeArray[NodeIndex].NodeID = CurrentNode.id;
var Attributes = CurrentNode.className.split(";");
for (var AttributeIterator = 0; AttributeIterator < Attributes.length; AttributeIterator++)
{
var Name = Attributes[AttributeIterator].split("=")[0];
var Value = Attributes[AttributeIterator].split("=")[1];
if (Name != "" && Value != "") eval("this.NodeArray[" + NodeIndex + "]." + Name + "=\"" + Value + "\";");
}
i++;
}
}
What is going on here is the function initiates a loop starting from i = 0 which checks for the existence of an element with an ID with the format
"UserDataNode" + i. It then splits the semicolon delimited class property and extracts a Name and Value combination from the format Name=Value (i.e.
class="DataPoint=OnlineNow;UserID=17601323;" will create two Name and Value variable combinations Datapoint & OnlineNow and UserID & 17601323).
These variables are then passed to an eval() function which creates the property of the object this.NodeArray[i].Name and sets it to the Value
(i.e. eval('this.NodeArray[0].DataPoint="OnlineNow";'); There is no sanitization of the variables 'Name' and 'Value' passed to the eval() function
within the locateNodes() function beyond that of semicolon and equal sign which is consequence of the way the delimitation works. Most importantly -
one can pass quotes to the eval function and due to the nature of javascript one can execute arbitrary functions. To show how this can be done in
exploit consider the following tag:
This will generate a call to the eval() function in the following manner:
eval('this.NodeArray[0].UserID="17601323"+String.fromCharCode(59)+"";')
Which one can easily see will set this.NodeArray[0].UserID to the value of 17601323; (the function String.fromCharCode(59) returns a semicolon). The
function specified is not limited to string-type functions, it would be valid javascript being any function; however, without semicolons nor quotes
there is not a terrible amount one can do without any trick. It follows then that one can call on an additional eval() function which uses the
String.fromCharCode() function to generate filtered characters. The following shows a line of javascript that does exactly this.
The function - String.fromCharCode(118,97,114,32,119,61,51,59,97,108,101,114,116,40,119,41,59) returns the string "var w=3;alert(w);"
By compounding this with eval() as so:
eval(String.fromCharCode(118,97,114,32,119,61,51,59,97,108,101,114,116,40,119,41,59));
A variable 'w' will be defined with value 3 and a messagebox will display it's value. The following tag - when passed to our locateNodes() function -
will execute the aforementioned line of code:
The string generated by fromCharCode(); can be any script the exploiter specifies. It is composed only of numbers and commas so no filters affect it.
Our exploit is almost complete. One last obstacle remains in order to exploit this script injection vulnerability. The web-application filters of Myspace
filter specific tags and words to hamper the possibility of script injection (for example the