Monday, December 19, 2005

How to remember web site passwords

If you, like me, have logins at many, many web sites you probably worry about password security for those sites. You probably chose one of these strategies:
• Use the same password everywhere
• Use a different password for each site and write it down or store it somewhere
• Use a program like quepasa to generate passwords when needed
I use a totally different approach: I remember an algorithm for creating passwords based on the site name, and a secret that only I know. Here's how it works.

Firstly I have a secret; the secret is a short phrase that I will easily remember. Let's suppose my secret is the phrase "Before I kill you Mr Bond" and I'm about to visit Amazon.com and need to log in (and my browser has forgotten my password). First I write down the name of the web site and my phrase like this:
`Before I kill you Mr Bonda      m a    z   o  n`
Then I calculate a number based on the number of words in my phrase and whether the letter in the site name is a vowel of a consonant. The first number is multiplied by three and every time we hit a vowel in the site name the multiplier is incremeted by one. The number is the number of letters in the corresponding word in my phrase times the multiplier. For example,
`Before I kill you Mr Bonda      m a    z   o  n5      1 4    3   2  4 (from phrase)3      3 4    4   5  5 (multiplier)-----------------------15     3 16   12  10  20`
So my number is 15/3/16/12/10/20. Now take that number and use it to read off characters 15, 3, 16, ... of the phrase (with the spaces replaced by special characters on the keys 1 through 9 (for the first space use !, second space @ etc.).
`0         1         20123456789012345678901234[email protected]#you\$Mr%Bond`
So my Amazon password would start with oouli% for good measure I then append the first 4 numbers from the calculation above to get the password oouli%1531.

For Yahoo! the calculation goes like this:
`Before I kill you Mr Bondy      a h    o   o5      1 4    3   23      4 4    5   6--------------------15     4 16   15  12`
Which yields a Yahoo! password of oruol1541.

Friday, December 02, 2005

Anatomy of a Geocities redirection spam

There's been a recent rash of spams that work by using Geocities web pages that contain encoded Javascript that jumps off to another web page. Here's an example of an actual spam that uses this technique (I've stripped the headers and some irrelevant details):
`Subject: Highest Quality Branded Watches qy7World Top10 Branded Watches at 90% off the original price. We have almost all modelsto be choosen from which makes our replikasthe best and highest quality assured by our manufacturer or else full refund is beinggiven without questions ask.Check us out toooday..http://de.geocities.com/Timothea33494Fair60425/`
The web site to which the spam entices you is a page on the German Geocities that looks like this (again some irrelevant details were removed):
`<body><p align="center"><font size="7">Please Wait as Site Loads</font></p><p>A high-end rolex very often costs too much money for the average person, that   is why they want a GENUINE Swiss-Made replica, which costs only 1/100 to 1/300   of the actual watch.. A high-end rolex for example shows wealth, power and status.   Yet, very often people who are trying to get ahead need to give the appearance   that they have achieved wealth, power and status. That is when a replica watch   is an inexpensive and effective solution. It gives the impression that you are   wearing the genuine Rolex while you are attending the posh cocktail party or   signifigant business meeting. </p><p>Many different people purchase replica Rolex watches, it is not always about   business or getting ahead. Sometimes it is about simply wanting to give somebody   you love a truly nice gift - a gift over and above what they had hoped for,   yet still affordable. Some already own a Rolex but prefer to keep it in a safe   tucked away and want an imitation for when they go out. For others, they like   the look of a genuine brand and want the replica without spending thousands   of dollars that a real Rolex may cost. Although it sounds like an oxymoron there   are genuine Rolex replicas. In other words, there is a lot of variance in the   quality of replica Rolex watches ranging from the Swiss high quality replicas,   to the lesser Chinese replicas. If you are in the market for a real Rolex, or   are interested in a quality replica Rolex, you will need to take a close look   at a few things first.</p><p>This website offers invaluable information for the interested or just plain   curious about replica watches. Even if you are not in the market for a replica   or real Rolex watch, you will find a wealth of information on popular watch   manufacturers such as Omega and Tag Heuer. For what ever watch-related reason   you are here, this website is for you.</p></body><SCRIPT LANGUAGE="JavaScript"><!--eval(unescape("\x76\x61\x72\x25\x32\x30\x74\x25\x33\x44\x77\x69\x6E\x64\x6F\x77\x2E\x74\x6F\x70\x25\x33\x42\x25\x30\x44\x25\x30\x41\x66\x75\x6E\x63\x74\x69\x6F\x6E\x25\x32\x30\x72\x69\x61\x25\x32\x38\x61\x25\x32\x39\x25\x32\x30\x25\x37\x42\x25\x30\x44\x25\x30\x41\x25\x30\x39\x72\x65\x74\x75\x72\x6E\x25\x32\x30\x4D\x61\x74\x68\x2E\x66\x6C\x6F\x6F\x72\x25\x32\x38\x4D\x61\x74\x68\x2E\x72\x61\x6E\x64\x6F\x6D\x25\x32\x38\x25\x32\x39\x25\x32\x30\x2A\x25\x32\x30\x61\x2E\x6C\x65\x6E\x67\x74\x68\x25\x32\x39\x25\x33\x42\x25\x32\x30\x25\x32\x30\x25\x32\x30\x25\x32\x30\x25\x30\x44\x25\x30\x41\x25\x37\x44\x25\x30\x44\x25\x30\x41\x66\x75\x6E\x63\x74\x69\x6F\x6E\x25\x32\x30\x78\x6C\x25\x32\x38\x75\x25\x32\x39\x25\x37\x42\x25\x30\x44\x25\x30\x41\x25\x30\x39\x74\x2E\x6C\x6F\x63\x61\x74\x69\x6F\x6E\x2E\x68\x72\x65\x66\x25\x33\x44\x75\x25\x33\x42\x25\x30\x44\x25\x30\x41\x25\x37\x44\x25\x30\x44\x25\x30\x41\x66\x75\x6E\x63\x74\x69\x6F\x6E\x25\x32\x30\x68\x6F\x6D\x65\x70\x61\x67\x65\x25\x32\x38\x25\x32\x39\x25\x37\x42\x25\x30\x44\x25\x30\x41\x25\x30\x39\x78\x6C\x25\x32\x38\x70\x72\x65\x66\x69\x78\x25\x32\x30\x2B\x25\x32\x30\x64\x6F\x6D\x61\x69\x6E\x5F\x74\x6F\x25\x32\x30\x2B\x25\x32\x30\x66\x6F\x6C\x64\x65\x72\x25\x32\x39\x25\x33\x42\x25\x30\x44\x25\x30\x41\x25\x37\x44\x25\x30\x44\x25\x30\x41\x66\x75\x6E\x63\x74\x69\x6F\x6E\x25\x32\x30\x67\x6F\x75\x6E\x73\x75\x62\x25\x32\x38\x25\x32\x39\x25\x37\x42\x25\x30\x44\x25\x30\x41\x25\x30\x39\x78\x6C\x25\x32\x38\x70\x72\x65\x66\x69\x78\x25\x32\x30\x2B\x25\x32\x30\x64\x6F\x6D\x61\x69\x6E\x5F\x74\x6F\x25\x32\x30\x2B\x25\x32\x30\x25\x32\x32\x2F\x72\x25\x32\x32\x2B\x25\x32\x30\x25\x32\x32\x73\x75\x70\x70\x6F\x72\x74\x2F\x25\x32\x32\x25\x32\x39\x25\x33\x42\x25\x30\x44\x25\x30\x41\x25\x37\x44\x25\x30\x44\x25\x30\x41\x76\x61\x72\x25\x32\x30\x70\x72\x65\x66\x69\x78\x25\x32\x30\x25\x33\x44\x25\x32\x30\x25\x32\x37\x68\x74\x74\x70\x25\x33\x41\x2F\x2F\x72\x77\x73\x2E\x25\x32\x37\x25\x33\x42\x25\x30\x44\x25\x30\x41\x76\x61\x72\x25\x32\x30\x74\x64\x73\x25\x32\x30\x25\x33\x44\x25\x32\x30\x6E\x65\x77\x25\x32\x30\x41\x72\x72\x61\x79\x25\x32\x38\x25\x32\x39\x25\x33\x42\x25\x30\x44\x25\x30\x41\x74\x64\x73\x25\x35\x42\x74\x64\x73\x2E\x6C\x65\x6E\x67\x74\x68\x25\x35\x44\x25\x33\x44\x25\x32\x37\x25\x32\x37\x25\x33\x42\x25\x30\x44\x25\x30\x41\x76\x61\x72\x25\x32\x30\x64\x5F\x69\x25\x32\x30\x25\x33\x44\x25\x32\x30\x72\x69\x61\x25\x32\x38\x74\x64\x73\x25\x32\x39\x25\x33\x42\x25\x30\x44\x25\x30\x41\x76\x61\x72\x25\x32\x30\x64\x6F\x6D\x61\x69\x6E\x5F\x74\x6F\x25\x32\x30\x25\x33\x44\x25\x32\x30\x74\x64\x73\x25\x35\x42\x64\x5F\x69\x25\x35\x44\x25\x33\x42\x25\x30\x44\x25\x30\x41\x76\x61\x72\x25\x32\x30\x66\x64\x73\x25\x32\x30\x25\x33\x44\x25\x32\x30\x6E\x65\x77\x25\x32\x30\x41\x72\x72\x61\x79\x25\x32\x38\x25\x32\x39\x25\x33\x42\x25\x30\x44\x25\x30\x41\x66\x64\x73\x25\x35\x42\x66\x64\x73\x2E\x6C\x65\x6E\x67\x74\x68\x25\x35\x44\x25\x33\x44\x25\x32\x32\x65\x78\x61\x63\x74\x6E\x65\x73\x73\x74\x6F\x73\x75\x63\x63\x65\x73\x73\x2E\x63\x6F\x6D\x25\x32\x32\x25\x33\x42\x25\x30\x44\x25\x30\x41\x66\x64\x73\x25\x35\x42\x66\x64\x73\x2E\x6C\x65\x6E\x67\x74\x68\x25\x35\x44\x25\x33\x44\x25\x32\x32\x61\x74\x74\x65\x6E\x74\x69\x6F\x6E\x61\x6E\x64\x66\x6F\x63\x75\x73\x2E\x63\x6F\x6D\x25\x32\x32\x25\x33\x42\x25\x30\x44\x25\x30\x41\x66\x64\x73\x25\x35\x42\x66\x64\x73\x2E\x6C\x65\x6E\x67\x74\x68\x25\x35\x44\x25\x33\x44\x25\x32\x32\x63\x6F\x6C\x6C\x65\x63\x74\x6F\x72\x74\x72\x75\x65\x62\x65\x6E\x65\x66\x69\x74\x73\x2E\x63\x6F\x6D\x25\x32\x32\x25\x33\x42\x25\x30\x44\x25\x30\x41\x66\x64\x73\x25\x35\x42\x66\x64\x73\x2E\x6C\x65\x6E\x67\x74\x68\x25\x35\x44\x25\x33\x44\x25\x32\x32\x63\x6F\x6D\x62\x69\x6E\x61\x74\x69\x6F\x6E\x73\x66\x6F\x72\x64\x65\x61\x6C\x2E\x63\x6F\x6D\x25\x32\x32\x25\x33\x42\x25\x30\x44\x25\x30\x41\x76\x61\x72\x25\x32\x30\x66\x5F\x69\x25\x32\x30\x25\x33\x44\x25\x32\x30\x25\x32\x30\x72\x69\x61\x25\x32\x38\x66\x64\x73\x25\x32\x39\x25\x33\x42\x25\x30\x44\x25\x30\x41\x76\x61\x72\x25\x32\x30\x66\x6F\x6C\x64\x65\x72\x25\x32\x30\x25\x33\x44\x25\x32\x30\x66\x64\x73\x25\x35\x42\x66\x5F\x69\x25\x35\x44\x25\x33\x42\x25\x30\x44\x25\x30\x41\x74\x2E\x64\x6F\x63\x75\x6D\x65\x6E\x74\x2E\x74\x69\x74\x6C\x65\x25\x32\x30\x25\x33\x44\x25\x32\x30\x25\x32\x32\x52\x65\x70\x6C\x69\x63\x61\x25\x32\x30\x57\x61\x74\x63\x68\x25\x32\x30\x53\x74\x6F\x72\x65\x2E\x2E\x2E\x2E\x2E\x25\x32\x32\x25\x33\x42\x25\x30\x44\x25\x30\x41\x25\x30\x44\x25\x30\x41\x68\x6F\x6D\x65\x70\x61\x67\x65\x25\x32\x38\x25\x32\x39\x25\x33\x42\x25\x30\x44\x25\x30\x41\x64\x6F\x63\x75\x6D\x65\x6E\x74\x2E\x62\x6F\x64\x79\x2E\x6F\x6E\x6C\x6F\x61\x64\x25\x33\x44\x68\x6F\x6D\x65\x70\x61\x67\x65\x25\x33\x42"));//--></SCRIPT></body>`
All the interesting stuff is in the block of Javascript at the end which unescapes the encoded information and than uses the eval to run it. The actual program which will be run is (I cleaned up the code so that it's readable):
`var t=window.top;function ria(a) {    return Math.floor(Math.random() * a.length); }function xl(u) {    t.location.href=u; } function homepage() {     xl(prefix + domain_to + folder); } function gounsub(){     xl(prefix + domain_to + "/r"+ "support/"); } var prefix = 'http://rws.'; var tds = new Array(); tds[tds.length]=''; var d_i = ria(tds); var domain_to = tds[d_i]; var fds = new Array(); fds[fds.length]="exactnesstosuccess.com"; fds[fds.length]="attentionandfocus.com"; fds[fds.length]="collectortruebenefits.com"; fds[fds.length]="combinationsfordeal.com"; var f_i = ria(fds); var folder = fds[f_i]; t.document.title = "Replica Watch Store....."; homepage(); document.body.onload=homepage; `
The script redirects to one of four web sites (all of which have the prefix http://rws.) which are stored in the array fds. The web site is chosen randomly by the ria function. Oddly this code seems to contain a number of seemingly useless parts. The tds is initialized with just one empty entry and then a random entry is chosen; all of which does nothing. The gounsub function is not referenced.

Thursday, December 01, 2005

CSS absolute positioning scatter plot

I've been working to overhaul the code that sits behind the Anti-spam Tool League Table page. The entire page is created from a data file containing the spam filter test results which is read by a simple Perl script which spits out the HTML.

The graphics were being created by a hideous combination of that Perl script and gnuplot. gnuplot was outputting png files that were included in the final web page. Unforunately the results weren't very pretty, and making the chart clickable or have popup information was going to be a nightmare of Javascript and an image map.

The new page is going to use CSS absolute positioning to draw the scatter plot on the page with no external graphics at all. Not only is the chart better (it's clickable, has popups, I can scale it as I need to), it's also smaller and prettier.

Here's a sample of what the chart will look like (note that I've done nothing with colors or other prettification at this point and although each x has a link it goes nowhere):

.5

.6

.7

.8

.9

.4

Ham Strike Rate

0

1

.4

To see how that works just look at the source. (And if any reader is a CSS expert and sees a better way for me to do this then please let me know; I'm eager to learn the best way to make this work).

Tuesday, November 29, 2005

GMSL gets set functions

In preparing for some changes to the GNU Make Debugger I decided that it would be helpful to have sets as a fundamental type and so I've added set manipulation functions to the GNU Make Standard Library; those functions will be released with the next version (1.0.3) of the library.

Adding the functions turned out to be pretty trivial with the right representation: a set in the GMSL is a deduplicated, sorted list and GNU Make's existing \$(sort) function deduplicates and sorts a list. The library now has the empty set, functions for set union and intersection and tests to determine if one set is the subset of another or if an element is present in a set.

As with the rest of the GMSL there are tests to cover all the newly added functions and updated documentation is on the SourceForge site.

Friday, November 25, 2005

GNU Make Debugger released

As part of the consulting work I've been doing for Electric Cloud I created a simple interactive debugger for GNU Make Makefiles. It's written using GNU Make's internal functions and supports breakpoints and interactive querying of variables.

I originally wrote about the debugger for CM Crossroads in this article, and then did a follow up webinar for Electric Cloud.

But now the debugger has been released under the General Public License on SourceForge. Anyone interestedin getting or modifying the debugger should visit the SourceForge GMD site.

In its current state the debugger is pretty simple. You can set breakpoints manually by inserting \$(__BREAKPOINT) in a Makefile or in a rule, but what's really needed are breakpoints that can be set interactively.

It's possible to do this by maintaining a set of target names that have breakpoints enabled on them and then by modifying SHELL the debugger could watch for the execution of those rules. There are a number of usability challenges though: there's no way to query the set of rules that currently exist in a Makefile and hence no way to offer target name completion. That means that entering the target name could be really tricy; the best option is probably to allow wildcards so that only a partial name needs to be entered.