Monday, June 21, 2010

Spammers using Twitter's Update Status API

Submitted by Ryan Barnett 06/21/2010

I was reviewing the logs over at our WASC Distributed Open Proxy Honeypot Project and I noticed some interesting traffic. It looks as though Spammers are using the Twitter API to post their messages to their fake accounts. While the news of Spammers doing this is not new, the WASC honeypots are able to take a different vantage point and correlate account data.

Here is one example Spam posting transaction:

Request Headers
POST HTTP/1.1Authorization: Basic Sm9oblRNYWxtOm5rdGpjcjEyMw==
Accept-Encoding: gzip
User-Agent: twitter4j /2.0.8
X-Twitter-Client-Version: 2.0.8
Content-Type: application/x-www-form-urlencoded
Content-Length: 161
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Proxy-Connection: keep-alive

Request Body
status=%40ldegelund+why+not+offer+work-from-home+projects++to+your+readers+by+th \ \

Notice the Authorization request header as the Twitter API requires basic authentication. The decoded user credentials are (format is username:password):
Now, looking at this one transaction in isolation doesn't yield much interesting data. What is interesting, however, is that I then did a search for all transactions to Twitter's API for June 21, 2010 and I found many more transactions all from different client IP addresses. I extracted out all of the unique Authorization headers and decoded them:
Notice anything interesting? They all have the exact same password. Since the password isn't one of the typical dictionary ones where it may be possible to have some users actually use the same password, we can only conclude that all of the accounts are controlled by the same person(s).

Recommendation for web sites
When new accounts are being created, check the new password against some form of hash tracking list to see how many users have that same password. If the password is widely used, then it can either be denied or placed on some form of fraud watch list.

If you check out the twitter pages of these fake accounts, you will see that they all have profile pictures of women (even though some of the account names seem male). This may be an attempt to try and disarm readers and entice them to click on the job/tool related links.

I checked out one of the links. The first URL shortener resolved to a second URL shortener and then onto the final site - DoNanza
$ wget
--2010-06-21 14:18:45--
Connecting to||:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: [following]
--2010-06-21 14:18:45--
Resolving,,, ...
Connecting to||:80... connected.
HTTP request sent, awaiting response... 301 Moved
Location: [following]
--2010-06-21 14:18:45--
Connecting to||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `publishers?utm_source=twitter&utm_medium=pbl&utm_campaign=cpb'

[ <=> ] 11,236 --.-K/s in 0.1s

2010-06-21 14:18:46 (99.4 KB/s) - `publishers?utm_source=twitter&utm_medium=pbl&utm_campaign=cpb' saved [11236]
It seems as though the purpose of these Spam links/accounts is to do some affiliate or click schemes.


Unknown said...

Comparing salted values after the fact is impossible if you salt your hashes per record. I certainly think it's a good idea; just slightly difficult to implement.

Unknown said...

What would you specify as a threshold for different user accounts with the same password? I know that Twitter blacklists some passwords, but do they have any complexity requirements? I think that this would cause an awful lot of false positives, especially since most of the users that are signing up for these websites are using the weakest password they can get away with based on the site's password complexity requirements, if any.

Unknown said...

Hey Ryan, I like the idea of performing some form of analysis on the stored password hashes to determine if there are many accounts sharing the same passwords however couldn't denying the creation of the account reveal something pretty important to an attacker? Lots of other accounts use the same password. :-) I guess it all depends on how you present the error though. Interesting idea.