PDA

View Full Version : $$$ for crypto weakness in a cool simple algorithm


Snatch
July 17th, 2002, 08:07
http://www.rkeene.org/projects/crack-me/prize.html

Check the algorithm out. Nice and simple. But looks tricky to reverse. You guys see any weaknesses?

Snatch

Kilby
July 17th, 2002, 12:34
It's nice to see that Roy Keene has been busy since being dropped by the Irish national team

Kilby...

mike
July 18th, 2002, 22:04
The first thing to try is attacking the RNG. He's using time(NULL), which limits the number of bits tremendously. Of course, he could have used dev/random, but it's worth a try.

Say he made the challenge this year; then the time has to be between 3C4899DD and 3D372B06, or 25 bits. We should obviously start at the near date & work backwards.

The encryption looks straightforward:
Code:

int cipher_sub_encrypt(const unsigned char *inblk, unsigned char *
outblk, int blksize, unsigned char *key) {
int i,mod;
static int keyoffset=0;

mod=(int) key[0];
for (i=0;i<blksize;i++) {
if (!(i%mod)) {
keyoffset=((keyoffset+1)&0xff);
}
outblk[I]=key[((((int) inblk[I])+keyoffset)&0xff)+1];
}
return(blksize);
}


key is a structure: 1 byte that controls how often keyoffset updates (call it u), followed by a static 256-byte permutation. That means that it's a simple substitutuin cipher (like the cryptograms in the newspaper) except that every u bytes, the cipher will change slightly-- if a,b,c -> q,r,z in the first u bytes, then b,c,d -> q,r,z in the second u bytes.

We can loop through the values for u and look at the statistics of the bytes in chunks of size u. We also have some known plaintext.

Kythen
July 19th, 2002, 04:08
Actually, attacking the srand()/rand() in this case is useless. If you look at the command sequence he gives you'll see:
"Key file: file003.key"

When the user enters the name of a key file, it just uses the file as the key rather than generating a random key. The code below does this.

fname=dact_ui_getuserinput("Key file: ",128,0);
fd=open(fname, O_RDONLY);
if (fd>=0) {
x=read(fd, &keybuf, sizeof(keybuf));
if (x==257) {
memcpy(key,keybuf,257); /* For backward compatability with DACT 0.8.1*/
}
else {
memcpy(key,ptrbuf=demime64(keybuf),257);
free(ptrbuf);
}
close(fd);
return(257);
}

I'm not sure where you'd find known plaintext, because the file is compressed before being encrypted. We also don't know which algorithm was used to compress the file. The algorithm byte is about all I can see at this time as being known (or easily guessed) plaintext. I'm going to check into it more though of course, so no hints yet please!

mike
July 19th, 2002, 04:35
OK, but where did the key come from? All I meant was that the key file may have been generated using rand. You're right, the file is compressed first; I haven't looked at the format enough to know what kind of headers, if any, are involved. I just guessed there would be.