list of entries

[all entries]

"free" as in "actually free"

some of my favorite sites

quantification of bitstring randomess

specialized POST account retrieval system

the parse interpreted algorithm language

recent updates

telnet server with sockets and multithreading

working with brainfuck


specialized POST account retrieval system

Since this entry was composed, Zero Hedge has implemented HTTPS on their website, which has currently disabled this program from functioning properly.


Because of the stigma that surrounds users who have recently joined Internet forums, it can often be easy to develop a high esteem within a given forum by merely using an older account.

In the case of Zero Hedge, a financial news website, many users created their accounts many years ago, and this is visible on the account pages for these users. It has been found that a program could be devised which creates a list of users based on their account chronology and attempts to gain access using a list of unsecure passwords.

I have developed an account retrieval system which exploits security vulnerabilities on the Zero Hedge website in order to garner login credentials for accounts that use unsecure passwords.

In observing Zero Hedge user account pages, it was found that the accounts are given specific identification numbers when they are created. When this number is appended to http://zerohedge.com/user/, a redirection to the page of that user account will occur.

For example, http://zerohedge.com/user/5 redirects to http://zerohedge.com/users/tyler-durden, which returns the following information in the head of the page:

<link rel="canonical" href="http://www.zerohedge.com/users/tyler-durden" />
<meta property="og:url" content="http://www.zerohedge.com/users/tyler-durden" />

The following was written in order to automate username collection, in which number is incremented to try each account in order of their creation:

response = requests.get("http://zerohedge.com/user/" + number).text

if "Page Not Found" not in response:
	entry.append(response[response.index("canonical") + 48:response.index("og:url") - 21])

	entry.append(response[response.index("<title>") + 7:response.index(" | Zero Hedge")])

By finding where in the response the username and title are located, these substrings can be appended to the user entry within the program.

In the user account pages, the username is consistently found forty-eight positions after canonical to twenty-one positions before og:url.

The display title is consistently found seven positions after <title> to the position immediately before | Zero Hedge.

However, attaining the usernames is the easier part of the effort. In order to gain the password for a given account, more effort must be made, and a directly more sophisticated program must be written to effectuate the necessary procedure.

Observing again the source of the website, this time specifically of the login page, the form for login POST submission, http://zerohedge.com/user/, was found. Similarly to the program used to find the usernames based on the page returned after the URL was requested, this program will merely parse the returned information after a POST request is made using each set of credentials attempted.

For each username found, each password contained in a specified list is attempted. If the page returns a certain string in its source, it can be determined whether the login attempt was successful, for example:

for item in [entry[1], entry[2]] + passwords:
	data = {"form_id": "user_login", "name": entry[1], "pass": item}

	response = requests.post("http://zerohedge.com/user/", data).text

After the request is made, the response that is received is examined to determine whether the login attempt was successful:

if "/user/password" not in response:
	output(entry + [item])

In this section, response denotes the source returned after the login POST request is made, entry denotes the known information—the username and display title of the user, and item denotes the password being attempted. output() denotes a tabulated output function.

As the program runs, the output generated will give the user credentials determined from the public user account page as well as the password that resulted in a successful login attempt, for example, if a list of user accounts is attempted, and if qwerty was the password for each of them:

Number  Username                        Title                           Password
0       example-user-1                  Example User 1                  qwerty
1       example-user-2                  Example User 2                  qwerty
2       example-user-3                  Example User 3                  qwerty
3       example-user-4                  Example User 4                  qwerty

The login form has no form of protection against robots. This allows for retrieval of accounts in immediate succession and without the necessity for performing a human action, like CAPTCHA.

Not every account will have a password found in a given password list, but many accounts will use unsecure passwords. This program will only try as many passwords as are contained in the password list in addition to the username itself and the display title as passwords. Usernames for which the password is not found will not be shown in the output.

Although the Zero Hedge front-end is wanting in some form of protection against robots, their back-end does have protection against denial-of-service attacks. To combat this, the program includes a mere pass statement when it encounters a request limit error, giving enough time for the server to begin accepting new requests.

This has the unintended side effect of skipping that particular user and password combination, making the account retrieval imperfect. A function for repeating skipped combinations has yet to be implemented.

I have incorporated multithreading in order to allow this program to send multiple requests at once, which has shown, in practice, to make it garner account credentials more quickly.

Other websites like this may have similar vulnerabilities, and the same concept represented in this project could be used in a program specialized for another website. This project helps illustrate the ease of garnering account credentials using an unornamented program.