Twitter uses an API for everything. Many people have seen the limitations of it, such as third party clients not being able to get favorites on Tweets or only 100,000 clients allowed per token. This API has many hidden methods and functions that most developers will never see, even though they are very easy to find. Official 1st party tokens have access to many methods you can find using an endpoint designed to show ratelimiting information. Today, I’m going to be talking about a very specific type of API request—registering new accounts.
All of the following information and tokens have been pulled from Twitter for Windows, which I decompiled with JetBrains dotPeek.
Update as of August 2015: With .NET Native code, it is no longer possible to decompile Windows apps with these tools and such ease.
Twitter uses OAuth for authenticating everything. There are hardcoded OAuth tokens for checking username availability and completing the registration. These tokens can be found in Twitter.OAuth.OAuthConstants
. They are encoded in bytes and offset by some number, which can very easily be undone with a simple program. The offset number does not seem to have a clear origin. My best guess for storing these tokens as offset byte arrays is so that people cannot just search the file for a matching string, but it does not seem to actually help much.
Here is where things start to get interesting. If you look at Twitter’s scheme for OAuth tokens, you can find the user ID at the start. For example, the signup access token is 537705597-lH08BZJKhd1iEgm0o3DYd0vcp8e7eOskzUjVNbSd
. This belongs to a user with the ID of 537705597
. Twitter internally uses an account named @cupb1rdtre3 to register all Twitter for Windows accounts. It is a locked account, but thanks to our access tokens, we can see what’s inside!
My favorite tool for sending raw requests to the Twitter API is called twurl, it is a free Twitter-published Ruby gem intended for debugging API calls. After manually adding these tokens to its configuration file, I can start sending requests authorized as it.
To see the account’s most recent Tweets, you can run something like twurl /1.1/statuses/user_timeline.json?user_id=537705597
. Using a lovely tool called jq, I can filter and pretty print this in my terminal window. We can filter this information down to just the Tweet text and created at time using twurl /1.1/statuses/user_timeline.json?user_id=537705597 | jq '.[] | {text: .text, created_at: .created_at}'
. Here’s a few Tweets from the account. If you want to see the rest, just run the command yourself.
{
"text": "hi I'm @batuhan_katirci and looking for internship in Turkey!",
"created_at": "Tue May 05 05:50:40 +0000 2015"
}
{
"text": "I will never understand this account - A dog",
"created_at": "Thu Apr 02 23:50:01 +0000 2015"
}
{
"text": "boop",
"created_at": "Tue Mar 17 21:45:32 +0000 2015"
}
{
"text": "Might want to fix your security...",
"created_at": "Mon Mar 16 22:09:52 +0000 2015"
}
Now that we have tokens that are authorized to run registration functions, we can check if usernames, email addresses, etc. are in use.
Again, I am using twurl to fetch things. After a quick look at Twitter.Services.SignupServices in Twitter-Win8.exe, we can easily identify the endpoint for checking availability. It is https://api.twitter.com/i/users/email_available.json
for email addresses, and https://api.twitter.com/i/users/username_available.json
for usernames. Each endpoint requires an email or username parameter, respectively.
Here is a sample request checking for my (already in use) email address.
$ twurl /i/users/email_available.json?email=example@ghc.li | jq '.'
{
"valid": false,
"msg": "Email has already been taken."
}
Using this endpoint, someone could create a tool that would allow people to see if a not found page on Twitter was because the account no longer existed, or if it was deactivated.
Now that we can check if usernames or email addresses have already been used, we can use an API endpoint to actually create a new account.
Again, looking at SignupServices, we can find the endpoint for creating a new account, https://api.twitter.com/1.1/account/create.json
. Unlike the other methods mentioned above, we need to send a POST request. To do this in twurl, we can add a -X POST to the command. However, because we are going to have to send form data to create the account, it becomes implied and we do not need this.
By looking at the Signup function we can determine which parameters are needed. The required fields are as follows:
Parameter | Description | Example |
---|---|---|
screen_name | Your Twitter handle, which must be unused. | GregCordover |
email | Your email address, which must be unused. | example@ghc.li |
password | The account password | a_cool_password |
name | A display name for the account | Greg Cordover |
If you do not include a screen_name
, you will be given an account name based on your name and random numbers.
There are other, optional parameters, and you can look through the code to see what they are and how they work.
An example of the request needed looks like this: twurl -d 'email=example2@ghc.li' -d 'screen_name=ademo12345' -d 'name=A Demo Account' -d 'password=myawesomepassword' /1.1/account/create.json
(yes, this is real information, you can log into this account!).
You now have the information needed to create your own Twitter accounts using their API with their tokens. Use this power for good, not evil. We certainly do not need any other spam accounts!