Line 0
Link Here
|
|
|
1 |
//////////////////////////////////////////////////////////////// |
2 |
// MySQL password cracker - v1.0 - 16.1.2003 |
3 |
// |
4 |
// by Andrew Hintz <http://guh.nu> drew@overt.org |
5 |
// |
6 |
// This production has been brought to you by |
7 |
// 4tphi <http://4tphi.net> and violating <http://violating.us> |
8 |
// |
9 |
// This file is an add-on to John the Ripper <http://www.openwall.com/john/> |
10 |
// |
11 |
// Part of this code is based on the MySQL brute password cracker |
12 |
// mysqlpassword.c by Chris Given |
13 |
// This program executes about 75% faster than mysqlpassword.c |
14 |
// John the ripper also performs sophisticated password guessing. |
15 |
// |
16 |
// John the Ripper will expect the MySQL password file to be |
17 |
// in the following format (without the leading // ): |
18 |
// dumb_user:5d2e19393cc5ef67 |
19 |
// another_luser:28ff8d49159ffbaf |
20 |
|
21 |
#include <string.h> |
22 |
#include <stdio.h> |
23 |
#include <stdlib.h> |
24 |
#include <math.h> |
25 |
|
26 |
// johntr includes |
27 |
#include "arch.h" |
28 |
#include "misc.h" |
29 |
#include "formats.h" |
30 |
#include "common.h" |
31 |
|
32 |
//johntr defines |
33 |
#define FORMAT_LABEL "mysql" |
34 |
#define FORMAT_NAME "mysql" |
35 |
#define ALGORITHM_NAME "mysql" |
36 |
|
37 |
#define BENCHMARK_COMMENT "" |
38 |
#define BENCHMARK_LENGTH -1 |
39 |
|
40 |
// Increase the PLAINTEXT_LENGTH value for longer passwords. |
41 |
// You can also set it to 8 when using MySQL systems that truncate |
42 |
// the password to only 8 characters. |
43 |
#define PLAINTEXT_LENGTH 32 |
44 |
|
45 |
#define CIPHERTEXT_LENGTH 16 |
46 |
|
47 |
#define BINARY_SIZE 16 |
48 |
#define SALT_SIZE 0 |
49 |
|
50 |
#define MIN_KEYS_PER_CRYPT 1 |
51 |
#define MAX_KEYS_PER_CRYPT 1 |
52 |
|
53 |
|
54 |
//used for mysql scramble function |
55 |
struct rand_struct { |
56 |
unsigned long seed1,seed2,max_value; |
57 |
double max_value_dbl; |
58 |
}; |
59 |
|
60 |
|
61 |
void make_scrambled_password(char *,const char *); |
62 |
char *scramble(char *,const char *,const char *, int); |
63 |
|
64 |
//test cases |
65 |
static struct fmt_tests mysql_tests[] = { |
66 |
{"30f098972cc8924d", "http://guh.nu"}, |
67 |
{"3fc56f6037218993", "Andrew Hintz"}, |
68 |
{"697a7de87c5390b2", "drew"}, |
69 |
{"1eb71cf460712b3e", "http://4tphi.net"}, |
70 |
{"28ff8d49159ffbaf", "http://violating.us"}, |
71 |
{"5d2e19393cc5ef67", "password"}, |
72 |
{NULL} |
73 |
}; |
74 |
|
75 |
|
76 |
//stores the ciphertext for value currently being tested |
77 |
static char crypt_key[BINARY_SIZE+1]; |
78 |
|
79 |
//used by set_key |
80 |
static char saved_key[PLAINTEXT_LENGTH + 1]; |
81 |
|
82 |
static int mysql_valid(char *ciphertext) { //returns 0 for invalid ciphertexts |
83 |
|
84 |
int i; //used as counter in loop |
85 |
|
86 |
//ciphertext is 16 characters |
87 |
if (strlen(ciphertext) != 16) return 0; |
88 |
|
89 |
//ciphertext is ASCII representation of hex digits |
90 |
for (i = 0; i < 16; i++){ |
91 |
if (!( ((48 <= ciphertext[i])&&(ciphertext[i] <= 57)) || |
92 |
((97 <= ciphertext[i])&&(ciphertext[i] <= 102)) )) |
93 |
return 0; |
94 |
} |
95 |
|
96 |
return 1; |
97 |
} |
98 |
|
99 |
static void mysql_set_salt(void *salt) { } |
100 |
|
101 |
static void mysql_set_key(char *key, int index) { |
102 |
strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1); |
103 |
} |
104 |
|
105 |
static char *mysql_get_key(int index) { |
106 |
return saved_key; |
107 |
} |
108 |
|
109 |
static int mysql_cmp_all(void *binary, int index) { //also is mysql_cmp_one |
110 |
return !memcmp(binary, crypt_key, BINARY_SIZE); |
111 |
} |
112 |
|
113 |
static int mysql_cmp_exact(char *source, int count){ |
114 |
return (1); // mysql_cmp_all fallthrough? |
115 |
} |
116 |
|
117 |
static void mysql_crypt_all(int count) { |
118 |
// get plaintext input in saved_key put it into ciphertext crypt_key |
119 |
make_scrambled_password(crypt_key,saved_key); |
120 |
} |
121 |
|
122 |
//////////////////////////////////////////////////////////////// |
123 |
//begin mysql code |
124 |
// This code was copied from mysqlpassword.c by Chris Given |
125 |
// He probably copied it from password.c in the MySQL source |
126 |
// The code is GPLed |
127 |
|
128 |
void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2) { |
129 |
rand_st->max_value= 0x3FFFFFFFL; |
130 |
rand_st->max_value_dbl=(double) rand_st->max_value; |
131 |
rand_st->seed1=seed1%rand_st->max_value ; |
132 |
rand_st->seed2=seed2%rand_st->max_value; |
133 |
} |
134 |
static void old_randominit(struct rand_struct *rand_st,ulong seed1) { |
135 |
rand_st->max_value= 0x01FFFFFFL; |
136 |
rand_st->max_value_dbl=(double) rand_st->max_value; |
137 |
seed1%=rand_st->max_value; |
138 |
rand_st->seed1=seed1 ; rand_st->seed2=seed1/2; |
139 |
} |
140 |
double rnd(struct rand_struct *rand_st) { |
141 |
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % |
142 |
rand_st->max_value; |
143 |
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % |
144 |
rand_st->max_value; |
145 |
return(((double) rand_st->seed1)/rand_st->max_value_dbl); |
146 |
} |
147 |
void hash_password(ulong *result, const char *password) { |
148 |
register ulong nr=1345345333L, add=7, nr2=0x12345671L; |
149 |
ulong tmp; |
150 |
for (; *password ; password++) { |
151 |
if (*password == ' ' || *password == '\t') |
152 |
continue; |
153 |
tmp= (ulong) (unsigned char) *password; |
154 |
nr^= (((nr & 63)+add)*tmp)+ (nr << 8); |
155 |
nr2+=(nr2 << 8) ^ nr; |
156 |
add+=tmp; |
157 |
} |
158 |
result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit |
159 |
(str2int) */; |
160 |
result[1]=nr2 & (((ulong) 1L << 31) -1L); |
161 |
return; |
162 |
} |
163 |
void make_scrambled_password(char *to,const char *password) { |
164 |
ulong hash_res[2]; |
165 |
hash_password(hash_res,password); |
166 |
sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]); |
167 |
} |
168 |
static inline uint char_val(char X) { |
169 |
return (uint) (X >= '0' && X <= '9' ? X-'0' : X >= 'A' && X <= 'Z' ? |
170 |
X-'A'+10 : X-'a'+10); |
171 |
} |
172 |
char *scramble(char *to,const char *message,const char *password, int |
173 |
old_ver) { |
174 |
struct rand_struct rand_st; |
175 |
ulong hash_pass[2],hash_message[2]; |
176 |
if(password && password[0]) { |
177 |
char *to_start=to; |
178 |
hash_password(hash_pass,password); |
179 |
hash_password(hash_message,message); |
180 |
if (old_ver) |
181 |
old_randominit(&rand_st,hash_pass[0] ^ |
182 |
hash_message[0]); |
183 |
else |
184 |
randominit(&rand_st,hash_pass[0] ^ hash_message[0], |
185 |
hash_pass[1] ^ hash_message[1]); |
186 |
while (*message++) |
187 |
*to++= (char) (floor(rnd(&rand_st)*31)+64); |
188 |
if (!old_ver) { |
189 |
char extra=(char) (floor(rnd(&rand_st)*31)); |
190 |
while(to_start != to) |
191 |
*(to_start++)^=extra; |
192 |
} |
193 |
} |
194 |
*to=0; |
195 |
return to; |
196 |
} |
197 |
|
198 |
//end mysql code |
199 |
//////////////////////////////////////////////////////////////// |
200 |
|
201 |
struct fmt_main fmt_MYSQL = { |
202 |
{ |
203 |
FORMAT_LABEL, |
204 |
FORMAT_NAME, |
205 |
ALGORITHM_NAME, |
206 |
BENCHMARK_COMMENT, |
207 |
BENCHMARK_LENGTH, |
208 |
PLAINTEXT_LENGTH, |
209 |
BINARY_SIZE, |
210 |
SALT_SIZE, |
211 |
MIN_KEYS_PER_CRYPT, |
212 |
MAX_KEYS_PER_CRYPT, |
213 |
FMT_CASE | FMT_8_BIT, |
214 |
mysql_tests |
215 |
}, { |
216 |
fmt_default_init, |
217 |
mysql_valid, |
218 |
fmt_default_split, |
219 |
fmt_default_binary, |
220 |
fmt_default_salt, |
221 |
{ |
222 |
fmt_default_binary_hash, |
223 |
fmt_default_binary_hash, |
224 |
fmt_default_binary_hash |
225 |
}, |
226 |
fmt_default_salt_hash, |
227 |
mysql_set_salt, |
228 |
mysql_set_key, |
229 |
mysql_get_key, |
230 |
//fmt_default_clear_keys, |
231 |
mysql_crypt_all, |
232 |
{ |
233 |
fmt_default_get_hash, |
234 |
fmt_default_get_hash, |
235 |
fmt_default_get_hash |
236 |
}, |
237 |
mysql_cmp_all, |
238 |
mysql_cmp_all, //should it be the same as cmp_all or same as cmp_exact? |
239 |
mysql_cmp_exact //fallthrough |
240 |
} |
241 |
}; |