|
|
Message-ID: <BAY120-W16CD4A4D4FBF2CED909FE1B0B40@phx.gbl>
Date: Tue, 17 Feb 2009 06:24:09 +0000
From: P PO1434 <p2409@...mail.com>
To: <john-users@...ts.openwall.com>
Subject: RE: 2 known letters + wordlist word --> is new format
definition best way?
Thanks Alex - all working now. I got rid of the null terminated salt - as you said just not needed.
I also had to update the key with the most recent salt (previouslyit wasn't trying all the hashes
in conjunction with the candidate passwords.)
So...here it is: a basic MD5 crack when you know the first 'x' characters.
I'm sure there a bit of efficiency/tidying up in my code, but it should work as is.
OSC_fmt.c
/*
* MD5 where first 2 character are known and supplied
* by Pete. Test version only - handles the test conditions fine
* NOT HANDLING FILE INPUT AT THIS STAGE!
*
* This algorithm is often used in PHP - sort of a fake
* salt + plaintext which is MD5'd
*
* This code is really just a mod of raw_md5 which is
*
* Copyright (c) 2004 bartavelle
* bartavelle at bandecon.com
*
* by Justin
*
* Minor changes by David Luyer <david at luyer.net> to
* use a modified (faster) version of Solar Designer's
* md5 implementation.
*
* More improvement by
* Bal�zs Bucsay - earthquake at rycon.hu - http://www.rycon.hu/
* (2times faster, but it's only works up to 54characters)
*
* Credits to john!
*/
#include <string.h>
#include "arch.h"
#include "misc.h"
#include "common.h"
#include "formats.h"
#if ARCH_LITTLE_ENDIAN
#define MD5_out MD5_out_eq
#else
#define MD5_out MD5_bitswapped_out_eq
#endif
#define FORMAT_LABEL "osc-md5"
#define FORMAT_NAME "osc md5"
#define ALGORITHM_NAME "osc-md5"
#define BENCHMARK_COMMENT ""
#define BENCHMARK_LENGTH -1
#define PLAINTEXT_LENGTH 32
#define BINARY_SIZE 16
#define SALT_SIZE 2
#define MIN_KEYS_PER_CRYPT 1
#define MAX_KEYS_PER_CRYPT 64
#define MD5_BINARY_SIZE 16
#define MD5_HEX_SIZE (MD5_BINARY_SIZE * 2)
#define CIPHERTEXT_LENGTH (1 + 3 + 1 + 2 + 1 + MD5_HEX_SIZE)
// Our salt is the 2 characters we know that
// prefix the password
static char OSCSalt[SALT_SIZE];
extern ARCH_WORD_32 MD5_out[MAX_KEYS_PER_CRYPT];
extern char MD5_tmp[MAX_KEYS_PER_CRYPT][MD5_HEX_SIZE + 1];
typedef unsigned int MD5_u32plus;
static char saved_key[MAX_KEYS_PER_CRYPT][PLAINTEXT_LENGTH + 1 + 128 /* MD5 scratch space */];
int saved_key_len[MAX_KEYS_PER_CRYPT];
extern void MD5_Go_eq(unsigned char *data, unsigned int len, int index);
extern void MD5_Go2_eq(unsigned char *data, unsigned int len, int index);
// This struct primes up the fmt variable as an extern in john.c line 40
// the password in this case is 03ericsson - 03 provided, ericsson guessed AND
// a2justin - a2 supplied, justin is decode
// {"$OSC$a2$14f194bdf3a1c50d61e3427d0f77544c","justin"},
// {"$OSC$03$066ab82156b450503861270cf0c0aa68", "ericsson"},
// {"$OSC$99$545471039e2daea8d6c337ee6adffcee,william1},
//372788bad6617f2083f9c07695ee2229 :49eiffel
//066ab82156b450503861270cf0c0aa68: 03ericsson
static struct fmt_tests oscmd5_tests[] = {
{"$OSC$49$372788bad6617f2083f9c07695ee2229","eiffel"},
{NULL}
};
// No set up goes on here, just a check
static int oscmd5_valid(char *ciphertext)
{
// 0123456789012345678901234567890123456789
// $OSC$03$066ab82156b450503861270cf0c0aa68
// printf("%s %s%s","We are in OSC. Ciphertext is:",ciphertext,"\n");
if (!ciphertext)
return 0;
if (strncmp(ciphertext, "$OSC$", 5) != 0) {
// printf("%s %s %s","Initial 5 characters of ciphertext line was not $OSC$ but rather\n",ciphertext,"\n");
//return 0;
}
if (strlen(ciphertext) != CIPHERTEXT_LENGTH) {
// printf ("%s %u %s %s", "OSC ciphertext length invalid\n",strlen(ciphertext),ciphertext,"\n");
return 0;
}
if (ciphertext[7] != '$') {
// printf("%s","Character 7 must be a $ to split the 'salt' and the ciphertext\n");
return 0;
}
if (strspn(ciphertext+5+1+SALT_SIZE, itoa16) != MD5_HEX_SIZE) {
// printf("%s %u %s","OSC ciphertext key not valid size: must be",(unsigned int)MD5_HEX_SIZE,"\n");
return 0;
}
int i;
for (i = 8; i < CIPHERTEXT_LENGTH; i++){
if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) ||
(('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) )) {
printf("%s","OSC non-hex characters found in key\n");
return 0;
}
}
// All checks passed...continue
return 1;
}
// Convert ASCII salt to its internal representation
// Skip first 5 chars = $OSC$
static void *oscmd5_get_salt(char *ciphertext) {
printf("%s %s %s","Get salt: ",ciphertext+5,"\n");
return ciphertext+5;
}
/* Sets a salt for the crypt_all() method */
static void oscmd5_set_salt(void *salt) {
memcpy(OSCSalt,salt,SALT_SIZE);
}
// Set the suggested key up in saved_key by prefixing
// with the 2 known characters
static void oscmd5_set_key(char *key, int index) {
char x[PLAINTEXT_LENGTH+1];
memcpy(x,OSCSalt,SALT_SIZE);
memcpy(x+SALT_SIZE,key,strlen(key)+1);
strnzcpy(saved_key[index], x, PLAINTEXT_LENGTH+1);
saved_key_len[index] = strlen(saved_key[index]);
}
// Get the key stored in the saved_key array eg. ericsson from 03ericsson
static char *oscmd5_get_key(int index) {
saved_key[index][saved_key_len[index]] = '\0';
// Chop off the salt characters of saved_key to compare with the plaintext.
return saved_key[index]+SALT_SIZE;
}
static int oscmd5_cmp_one(void *binary, int index)
{
return (!(*((unsigned int*)binary) - (unsigned int)MD5_out[index]));
}
// Do a binary (number) check of the ciphertext eg. 06 6a b8 ... aa 68.
// Quit as soon as MD5 of password and key don't match
static int oscmd5_cmp_all(void *binary, int count)
{
unsigned int i;
for (i = 0; i < count; i++)
{
if (!(*((unsigned int*)binary) - *((unsigned int*)&MD5_out[i]))) return 1;
}
return 0;
}
// Compare ASCII hex keys
static int oscmd5_cmp_exact(char *source, int index)
{
// Creates a hash and compares to key
MD5_Go2_eq((unsigned char *)saved_key[index], saved_key_len[index], index);
// Do a straight byte for byte memory compare of the ascii hex variable to test, vs the MD5 calced one
// Move along to get the ciphertext
source+=5+SALT_SIZE+1;
return !memcmp(source,MD5_tmp[index], MD5_HEX_SIZE);
}
static void oscmd5_crypt_all(int count)
{
unsigned int i;
for (i = 0; i < count; i++)
{
// Update the salt with the latest
memcpy(saved_key[i],OSCSalt,SALT_SIZE);
MD5_Go_eq((unsigned char *)saved_key[i], saved_key_len[i], i);
}
}
int oscmd5_binary_hash_0(void *binary)
{
return *(ARCH_WORD_32 *)binary & 0xF;
}
int oscmd5_binary_hash_1(void *binary)
{
return *(ARCH_WORD_32 *)binary & 0xFF;
}
int oscmd5_binary_hash_2(void *binary)
{
return *(ARCH_WORD_32 *)binary & 0xFFF;
}
int oscmd5_get_hash_0(int index)
{
return MD5_out[index] & 0xF;
}
int oscmd5_get_hash_1(int index)
{
return MD5_out[index] & 0xFF;
}
int oscmd5_get_hash_2(int index)
{
return MD5_out[index] & 0xFFF;
}
// Convert the ASCII Hex representation to a real number
static void *oscmd5_binary(char *ciphertext)
{
static char realcipher[BINARY_SIZE];
int i;
// Move along to the actual ciphertext ie. after $OSC$xx$
ciphertext+= 5+SALT_SIZE+1;
for(i=0;i<BINARY_SIZE;i++)
{
realcipher[i] = atoi16[ARCH_INDEX(ciphertext[i*2])]*16 + atoi16[ARCH_INDEX(ciphertext[i*2+1])];
}
// realcipher must be binary value of actual password
return (void *)realcipher;
}
// Define our format - identifying the 'override' functions we will use
struct fmt_main fmt_OSC =
{
{
FORMAT_LABEL,
FORMAT_NAME,
ALGORITHM_NAME,
BENCHMARK_COMMENT,
BENCHMARK_LENGTH,
PLAINTEXT_LENGTH,
BINARY_SIZE,
SALT_SIZE,
MIN_KEYS_PER_CRYPT,
MAX_KEYS_PER_CRYPT,
FMT_CASE | FMT_8_BIT,
oscmd5_tests
}, {
fmt_default_init,
oscmd5_valid,
fmt_default_split,
oscmd5_binary,
oscmd5_get_salt, // Extract salt
{
oscmd5_binary_hash_0,
oscmd5_binary_hash_1,
oscmd5_binary_hash_2
},
fmt_default_salt_hash,
oscmd5_set_salt, // Put into global variable
oscmd5_set_key,
oscmd5_get_key,
fmt_default_clear_keys,
oscmd5_crypt_all, // Adds on salt
{
oscmd5_get_hash_0,
oscmd5_get_hash_1,
oscmd5_get_hash_2
},
oscmd5_cmp_all,
oscmd5_cmp_one,
oscmd5_cmp_exact
}
};
_________________________________________________________________
Are you a friend magnet? Play now to win prizes for you and your friends!
http://clk.atdmt.com/GBL/go/106906016/direct/01/?href=http://www.friendmagnet.com.au
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.