Skip to content

Commit f1c21dd

Browse files
committed
first commit
1 parent 21275b7 commit f1c21dd

File tree

2 files changed

+382
-0
lines changed

2 files changed

+382
-0
lines changed

cisco7crack.c

+311
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
#if 0
2+
gcc -Wall -W -ansi -pedantic -O2 cisco7crack.c -o cisco7crack || exit 1
3+
echo successfully compiled
4+
exit
5+
#endif /* Compile with: sh ./cisco7crack.c */
6+
7+
/* CISCO7CRACK.C ver. 2.3.4 - San Oct 19, 2002
8+
* (C) 2002 by Davide Madrisan <[email protected]>
9+
*
10+
* This program is free software; you can redistribute it and/or modify it under
11+
* the terms of the GNU General Public License as published by the Free Software
12+
* Foundation; either version 2 of the License, or (at your option) any later
13+
* version.
14+
*
15+
* This program is distributed in the hope that it will be useful, but WITHOUT
16+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17+
* FOR A PARTICULAR PURPOSE.
18+
* See the GNU General Public License for more details.
19+
*
20+
* Enjoy cracking the Cisco pesky passwords...
21+
* (like 'enable password 7 104D000A0618')
22+
*
23+
* Passwords can be up to twenty-five mixed-case characters.
24+
* In the "encrypted" representation, the first two bytes of the long string are
25+
* a random decimal offset between 0 and 15 into a magic block of characters,
26+
* and the remaining bytes are ascii-hex representations of the password bytes
27+
* xored against the character-block bytes from the given offset on down,
28+
* modulus the character-block length.
29+
* The character block is "dsfd;kfoA,.iyewrkldJKDHSUB".
30+
*
31+
* compiled successfully with gcc version 2.95.3
32+
* (gcc -Wall -W -Wstrict-prototypes -ansi -pedantic -O2 \
33+
* -o cisco7crack cisco7crack.c)
34+
*
35+
* indented with the gnu-indent tool
36+
* (indent -kr -i5 -nut cisco7crack.c)
37+
*/
38+
39+
#include <ctype.h>
40+
#include <fcntl.h>
41+
#include <stdarg.h>
42+
#include <stdio.h>
43+
#include <stdlib.h>
44+
#include <string.h>
45+
#include <time.h>
46+
#include <unistd.h>
47+
#include "cisco7crack.h"
48+
49+
50+
void usage(void)
51+
{
52+
static const char *usage_msg[] = {
53+
"*** " PROGRAM " " VERSION,
54+
" copyright (c) 2002 by " AUTHOR,
55+
" the GNU GPLv2 applies to this program and code",
56+
"",
57+
"usage:",
58+
" " PROGRAM " [-q] -c [-{a|#<0..15>}] <plaintext>",
59+
" " PROGRAM " [-q] [-d] <ciphertext>",
60+
" " PROGRAM " [-h]",
61+
"",
62+
"flags: means:",
63+
" -c crypt <plaintext>",
64+
" -a display all the ways to crypt <plaintext>",
65+
" -#<n> display the n-th way to crypt <plaintext>",
66+
" -d decrypt <ciphertext> (default option)",
67+
" -q cause " PROGRAM " to be really quiet",
68+
" -h display this brief usage summary",
69+
"",
70+
"examples are:",
71+
" " PROGRAM " -c#3 '@l1c3&b0b'",
72+
" " PROGRAM " -c#3 -q n0v3rb0s3",
73+
" " PROGRAM " 082F1C5A1A490D43000F5E033F78373B",
74+
"",
75+
" a=`" PROGRAM " -cq b@shscr1pt` # (bash shell)",
76+
" [ $? -eq 0 ] && echo \"crypt: $a\" || echo \"error!\"",
77+
"",
78+
"enjoy cracking the Cisco IOS pesky passwords...",
79+
"for bugs and suggestions, please contact me by e-mail",
80+
""
81+
};
82+
unsigned int i, u_lines = sizeof(usage_msg) / sizeof(*usage_msg);
83+
84+
for (i = 0; i < u_lines; i++)
85+
fprintf(stderr, "%s\n", usage_msg[i]);
86+
exit(ERR_USAGE);
87+
}
88+
89+
int decrypt_str(const char *passwd)
90+
{
91+
char crypted[MAX_ENCRYPTED_LEN], *ptr1, *ptr2;
92+
unsigned int arglen, cryptlen, pairs, i, index = 0;
93+
94+
if ((arglen = strlen(passwd)) > MAX_ENCRYPTED_LEN - 1)
95+
cfprintf(stderr, "WARNING: crypted string too long! "
96+
"(last %d chars flushed)\n",
97+
arglen - MAX_ENCRYPTED_LEN + 1);
98+
/* 'strncpy' used to avoid buffer overflow... */
99+
strncpy(crypted, passwd, MAX_ENCRYPTED_LEN);
100+
/* even if strlen(passwd) > MAXSTRLEN,
101+
* crypt[] must be a null terminated string
102+
*/
103+
crypted[MAX_ENCRYPTED_LEN - 1] = 0;
104+
pairs = (cryptlen = strlen(crypted)) / 2;
105+
106+
cfprintf(stdout, "%-17s: %s\n", "Encrypted string", crypted);
107+
cfprintf(stdout, "%-17s: ", "Plain string");
108+
109+
ptr1 = strchr(dec, crypted[0]);
110+
ptr2 = strchr(dec, crypted[1]);
111+
if (!ptr1 || !ptr2) {
112+
/* 'crypted' should begin with two decimal digits */
113+
cfprintf(stderr,
114+
"ERROR: illegal 1st pair of digits in crypted string\n");
115+
return ERR_INPUT_ILLEGAL_CHAR;
116+
}
117+
index = (ptr1 - dec) * 10 + (ptr2 - dec);
118+
119+
for (i = 1; i < pairs; i++) {
120+
ptr1 = strchr(hex, crypted[i * 2]);
121+
ptr2 = strchr(hex, crypted[i * 2 + 1]);
122+
if (!ptr1 || !ptr2) {
123+
cfprintf(stderr,
124+
"[?] ERROR: bad pair of hex digits (pair: %d)\n",
125+
i + 1);
126+
return ERR_INPUT_ILLEGAL_CHAR;
127+
}
128+
printf("%c",
129+
(((ptr1 - hex) << 4) + (ptr2 - hex)) ^ magic[index++]);
130+
index %= magic_size;
131+
}
132+
printf("\n");
133+
134+
/* encrypted strings with odd number of digits are illegal */
135+
if (cryptlen % 2) {
136+
cfprintf(stderr,
137+
"WARNING: input truncated! (odd number of letters)\n");
138+
return ERR_INPUT_ODD_DIGITS;
139+
}
140+
return ERR_NONE;
141+
}
142+
143+
int crypt_str(const char *str2crypt, int xor_offset)
144+
{
145+
register unsigned int i, j;
146+
unsigned int first, last, index, str2cryptlen = strlen(str2crypt);
147+
bool too_long_input;
148+
149+
if ((too_long_input = (str2cryptlen > MAX_PLAIN_LEN))) {
150+
str2cryptlen = min(str2cryptlen, MAX_PLAIN_LEN);
151+
cfprintf(stderr, "WARNING: overly long password truncated after "
152+
"%d characters\n", MAX_PLAIN_LEN);
153+
cfprintf(stdout, "%-17s: ", "Plain string");
154+
for (i = 0; i < MAX_PLAIN_LEN; i++)
155+
printf("%c", str2crypt[i]);
156+
printf("\n");
157+
} else
158+
cfprintf(stdout, "%-17s: %s\n", "Plain string", str2crypt);
159+
160+
/* user ask for a random offset in magic[] */
161+
if (xor_offset == OFFSET_RANDOM)
162+
first = last = get_entropy();
163+
/* list all the crypted strings that IOS can generate */
164+
else if (xor_offset == OFFSET_ALL) {
165+
first = 0;
166+
last = MAX_XOR_OFFSET;
167+
}
168+
/* the user has specified an initial offset in magic[] */
169+
else
170+
first = last = xor_offset;
171+
172+
cfprintf(stdout, "%-17s: ", "Encrypted string");
173+
174+
/* from 'first' to 'last' way to crypt the 'str2crypt' */
175+
for (j = first; j <= last; j++) {
176+
/* mod just to make the code more robust */
177+
index = j % magic_size;
178+
if (j != first)
179+
cfprintf(stdout, "%-19s", "");
180+
printf("%02d", index);
181+
/* from first to last char allowed in 'str2crypt' */
182+
for (i = 0; i < str2cryptlen; i++) {
183+
printf("%02X", str2crypt[i] ^ magic[index++]);
184+
index %= magic_size; /* mod : same as above */
185+
}
186+
printf("\n");
187+
}
188+
return too_long_input ? ERR_INPUT_TOO_LONG : ERR_NONE;
189+
}
190+
191+
unsigned int get_entropy(void)
192+
{
193+
#ifdef LINUX
194+
int devurandom;
195+
#endif
196+
unsigned int entropy;
197+
198+
#ifdef LINUX
199+
/* if your Linux system does not have /dev/random created already,
200+
it can be created with the following commands:
201+
mknod -m 644 /dev/urandom c 1 9
202+
chown root:root /dev/urandom
203+
*/
204+
devurandom = open("/dev/urandom", O_RDONLY | O_NONBLOCK);
205+
if (devurandom != -1) {
206+
read(devurandom, &entropy, sizeof(entropy));
207+
close(devurandom);
208+
} else {
209+
/* rand() function call is not a very good source of randomness */
210+
cfprintf
211+
(stderr,
212+
"WARNING: couldn't open /dev/urandom, falling back to rand()\n");
213+
#endif
214+
srand((unsigned int) time(NULL));
215+
/* to use higher-order bits of pseudo-random number... */
216+
entropy =
217+
(unsigned int) (1. * rand() * MAX_XOR_OFFSET / RAND_MAX);
218+
#ifdef LINUX
219+
}
220+
#endif
221+
return entropy;
222+
}
223+
224+
void cfprintf(FILE * stream, const char *fmt, ...)
225+
{ /* conditional printf */
226+
va_list argptr;
227+
int cnt;
228+
229+
if (opt.quiet) /* no output message required */
230+
return;
231+
232+
va_start(argptr, fmt);
233+
fflush(stdout); /* to avoid some visualisation problems */
234+
cnt = vfprintf(stream, fmt, argptr);
235+
va_end(argptr);
236+
}
237+
238+
#ifdef HEX_LOWER_SUPPORT
239+
char *strtoupper(char *str)
240+
{
241+
char *saved = str;
242+
243+
while ((*str++ = toupper(*str)));
244+
return saved;
245+
}
246+
#endif
247+
248+
int main(int argc, char **argv)
249+
{
250+
unsigned int c;
251+
opt.crypt = opt.decrypt = opt.quiet = false;
252+
opt.xor_offset = OFFSET_RANDOM; /* random initial offset in magic[] */
253+
254+
/* command line input parser */
255+
while (--argc > 0 && **++argv == '-') {
256+
/* catch user errors like : cisco7crack - -c#3 @l1c3 */
257+
if (!*(*argv + 1))
258+
usage();
259+
while ((c = *++*argv)) /* process multiple options like -sc#8 */
260+
switch (c) {
261+
case 'c': /* crypt */
262+
if (opt.decrypt) /* decrypt option already selected */
263+
usage();
264+
opt.crypt = true;
265+
break;
266+
case 'a': /* display all the ways to crypt the input passwd */
267+
if (opt.decrypt || opt.xor_offset != OFFSET_RANDOM)
268+
usage();
269+
opt.xor_offset = OFFSET_ALL; /* all the offsets */
270+
break;
271+
case '#': /* user-defined initial offset in magic[] */
272+
if (opt.decrypt || opt.xor_offset != OFFSET_RANDOM)
273+
usage();
274+
opt.xor_offset = atoi(*argv + 1);
275+
if (opt.xor_offset < 0
276+
|| opt.xor_offset > MAX_XOR_OFFSET)
277+
usage();
278+
/* skip digits already parsed by atoi() */
279+
while (isdigit(*(++*argv + 1)));
280+
break;
281+
case 'd': /* decrypt */
282+
if (opt.crypt)
283+
usage();
284+
opt.decrypt = true;
285+
break;
286+
case 'q': /* minimize the program output */
287+
opt.quiet = true;
288+
break;
289+
case 'h': /* help */
290+
default: /* unknown option */
291+
usage();
292+
}
293+
}
294+
295+
if (argc != 1)
296+
usage(); /* usage error (too many arguments entered) */
297+
298+
if (!opt.crypt && !opt.decrypt) { /* make decrypt the default actions */
299+
if (opt.xor_offset != OFFSET_RANDOM)
300+
usage();
301+
opt.decrypt = true;
302+
}
303+
304+
return opt.decrypt ?
305+
#ifdef HEX_LOWER_SUPPORT
306+
decrypt_str(strtoupper(*argv))
307+
#else
308+
decrypt_str(*argv)
309+
#endif
310+
: crypt_str(*argv, opt.xor_offset);
311+
}

cisco7crack.h

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* Header file for CISCO7CRACK.C - Sat Oct 19, 2002
2+
* (C) 2002 by Davide Madrisan <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify it under
5+
* the terms of the GNU General Public License as published by the Free Software
6+
* Foundation; either version 2 of the License, or (at your option) any later
7+
* version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11+
* FOR A PARTICULAR PURPOSE.
12+
* See the GNU General Public License for more details.
13+
*/
14+
15+
16+
/* IOS cuts passwords with length > `MAX_PLAIN_LEN' (25 in IOS 12.0(7)T)
17+
* Note that some passwords, like OSPF authentication keys, are even shorter */
18+
#define MAX_PLAIN_LEN 25
19+
/* NOTE: if you increment this value you can generate passwords that are _not_
20+
* IOS-compliant */
21+
#define MAX_XOR_OFFSET 15
22+
23+
/* next directive is intended to support (at least) routers C761
24+
with IOS(?) c760-in.r.NET3 4.2(3). They use lowercase letters in 'hex'
25+
(i.e. 0123456789abcdef)
26+
thanks to Fabrizio Pedracini for the info */
27+
/* #define HEX_LOWER_SUPPORT */
28+
29+
#define MAX_ENCRYPTED_LEN (2+(2*MAX_PLAIN_LEN)+1)
30+
#define min(x,y) ((x) < (y) ? (x) : (y))
31+
32+
/* return codes of this program ([no] errors, warnings) */
33+
#define ERR_NONE 0x00
34+
#define ERR_USAGE 0x01
35+
#define ERR_INPUT_ILLEGAL_CHAR 0x02
36+
#define ERR_INPUT_ODD_DIGITS 0x04
37+
#define ERR_INPUT_TOO_LONG 0x08
38+
39+
#define OFFSET_RANDOM -1
40+
#define OFFSET_ALL -2
41+
42+
#define PROGRAM "cisco7crack"
43+
#define AUTHOR "Davide Madrisan <[email protected]>"
44+
#define VERSION "v2.3.4 - San Oct 19, 2002"
45+
46+
47+
static const char *dec = "0123456789", *hex = "0123456789ABCDEF";
48+
static const char magic[] = {
49+
0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f,
50+
0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72,
51+
0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53, 0x55, 0x42
52+
}; /* "dsfd;kfoA,.iyewrkldJKDHSUB" */
53+
const unsigned int magic_size = sizeof(magic) / sizeof(magic[0]);
54+
55+
typedef enum e_bool { false = 0, true } bool;
56+
typedef struct s_options { /* arguments passed on command line */
57+
bool crypt;
58+
bool decrypt;
59+
bool quiet;
60+
int xor_offset;
61+
} options_list;
62+
options_list opt;
63+
64+
void usage(void);
65+
int decrypt_str(const char *passwd);
66+
int crypt_str(const char *str2crypt, int xor_offset);
67+
unsigned int get_entropy(void);
68+
void cfprintf(FILE * stream, const char *fmt, ...);
69+
#ifdef HEX_LOWER_SUPPORT
70+
char *strtoupper(char *str);
71+
#endif

0 commit comments

Comments
 (0)