1#!/usr/bin/perl
2
3package Cisco::Hash;
4
5use strict;
6use warnings;
7
8require Exporter;
9
10our $VERSION = sprintf "%d.%02d", q$Revision: 0.02 $ =~ m/ (\d+) \. (\d+) /xg;
11
12use vars qw[
13						@EXPORT_OK
14            @XLAT
15            $EXLAT
16           ];
17
18BEGIN {
19	*import    = \&Exporter::import;
20	@EXPORT_OK = qw(decrypt encrypt usage);
21}
22
23use Carp;
24
25@XLAT = (
26	0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f,
27	0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72,
28	0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53,
29	0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36,
30	0x39, 0x38, 0x33, 0x34, 0x6e, 0x63, 0x78, 0x76,
31	0x39, 0x38, 0x37, 0x33, 0x32, 0x35, 0x34, 0x6b,
32	0x3b, 0x66, 0x67, 0x38, 0x37
33);
34
35$EXLAT = scalar@XLAT;
36
37sub decrypt {
38	my $e = shift;
39
40	$e = uc $e;
41
42	die "ERROR: The encrypted string has an odd length but must have an even. Call usage for help."
43		if length $e & 1;
44
45	die "ERROR: Invalid character detected. Ensure you only paste the enrcypted password. Call usage for help."
46		if $e !~ /^[\dA-F]+$/i;
47
48	my $d;
49	my ($eh, $et) = ($e =~ /(..)(.+)/o);
50
51	for(my $i = 0; $i < length $et ; $i += 2) {
52		$d .= sprintf "%c", hex( substr $et, $i, 2 )^$XLAT[ $eh++ % $EXLAT ];
53	}
54	return $d;
55}
56
57sub encrypt {
58	my ($d, $of) = @_;
59
60	die "ERROR: Insufficient number of Arguments. Call usage for help."
61		if @_ != 2;
62
63	die "ERROR: The offset you provided is not supported. Call usage for help."
64		if $of < 0 || $of > 52;
65
66	my $e .= sprintf "%02d", $of;
67
68	for(my $i = 0; $i < length $d; $i++) {
69		$e .= sprintf "%02x", unpack( 'C', substr $d, $i, 1 )^$XLAT[ $of++ % $EXLAT ];
70	}
71	return uc $e;
72}
73
74sub usage {
75	die <<EOF
76
77decrypt(<encrypted_hash>)
78
79	Paste the encrypted hash without any preceeding information
80
81	Exmaple:
82	use Cisco::Hash qw(decrypt);
83	decrypt('1511021F0725'); # Will return 'cisco'
84
85encrypt(<passphrase>, <offset>)
86
87	You can define any passphrase you like to encrpyt into a encrypted hash.
88	Altough it seems that Cisco devices strip of all characters above the
89	224th position.
90
91	The offset describes at which position of the translate mask encryption
92	should be startet. Due to the length of the mask (which is 53) allowed
93	values are 0 to 52 (decimal).
94
95	Example:
96	use Cisco::Hash qw(encrypt);
97	encrypt('cisco', 15); # will return '1511021F0725'
98
99THIS SOFTWARE IS NEITHER INTENDED FOR MALICIOUS USE NOR FOR THE USE
100IN ANY OTHER ILLEGAL PURPOSES.
101
102EOF
103}
104
1051;
106
107__END__
108
109=head1 NAME
110
111Cisco::Hash - De- and encrypts Cisco type 7 hashes
112
113=head1 SYNOPSIS
114
115use Cisco::Hash qw(decrypt encrypt usage);
116
117print encrypt('cisco', 15);          # will produce 1511021F0725
118
119print decrypt('1511021F0725');       # will produce cisco
120print decrypt(encrypt('cisco', 15)); # as will this too
121
122usage; # prints information about the module
123
124=head1 DESCRIPTION
125
126This Module decrypts all kind of Cisco encrypted hashes also referred
127to as type 7 passwords. Further you can encrypt any given string into
128a encrypted hash that will be accepted by any Cisco device as an
129encrypted type 7 password.
130
131=head1 METHODS
132
133=over 4
134
135=item decrypt(encrypted_hash)
136
137Paste the encrypted hash without any preceding information.
138
139Exmaple:
140C<decrypt('1511021F0725'); # Will return 'cisco'>
141
142=item encrypt(passphrase, offset)
143
144You can define any passphrase you like to encrpyt into a encrypted hash.
145Altough it seems that Cisco devices strip of all characters above the
146224th position.
147
148The offset describes at which position of the translate mask encryption
149should be startet. Due to the length of the mask (which is 53) allowed
150values are 0 to 52 (decimal).
151
152Example:
153C<encrypt('cisco', 15); # will return '1511021F0725'>
154
155=item usage
156
157Usage will give hints on how to use the methods provided by this
158module.
159
160=back
161
162=head1 AUTHOR
163
164LORD INFERNALE C<infernale@cpan.org>
165
166=head1 COPYRIGHT AND LICENSE
167
168THIS SOFTWARE IS NEITHER INTENDED FOR MALICIOUS USE NOR FOR THE USE
169IN ANY OTHER ILLEGAL PURPOSES.
170
171Credits for orginal code and description hobbit@avian.org,
172SPHiXe, .mudge et al. and for John Bashinski <jbash@CISCO.COM> for
173Cisco IOS password encryption facts.
174
175Copyright (c) 2008 LORD INFERNALE.  All rights reserved.
176
177This program is free software; you can redistribute it and/or
178modify it under the same terms as Perl itself.
179
180=cut
181