c7decrypt 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/c7decrypt.rb +85 -17
- metadata +1 -1
data/lib/c7decrypt.rb
CHANGED
@@ -1,11 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# Author: Jonathan Claudius (Twitter/GitHub: @claudijd)
|
4
|
-
#
|
5
|
-
# This code is based on Daren Matthew's cdecrypt.pl found here:
|
6
|
-
# http://mccltd.net/blog/?p=1034 ("Deobfuscating Cisco Type 7 Passwords")
|
7
|
-
|
8
|
-
#Class Implementation
|
1
|
+
require_relative 'exceptions'
|
2
|
+
|
9
3
|
class C7Decrypt
|
10
4
|
|
11
5
|
# Vigenere translation table (these are our key values for decryption)
|
@@ -19,15 +13,20 @@ class C7Decrypt
|
|
19
13
|
|
20
14
|
# Regexes for extracting hashes from configs
|
21
15
|
TYPE_7_REGEXES = [
|
22
|
-
/enable password 7 ([
|
23
|
-
/username [
|
24
|
-
/password 7 ([
|
16
|
+
/enable password 7 ([A-Z0-9]+)/,
|
17
|
+
/username [A-Z0-9]+ password 7 ([A-Z0-9]+)/,
|
18
|
+
/password 7 ([A-Z0-9]+)/
|
25
19
|
]
|
26
20
|
|
27
21
|
# The Decryption Method for Cisco Type-7 Encrypted Strings
|
28
22
|
# @param [String] the Cisco Type-7 Encrypted String
|
23
|
+
# @raise [InvalidFirstCharacter,
|
24
|
+
# InvalidCharacter,
|
25
|
+
# OddNumberOfCharacters]
|
29
26
|
# @return [String] the Decrypted String
|
30
27
|
def decrypt(e_text)
|
28
|
+
check_type_7_errors(e_text)
|
29
|
+
|
31
30
|
d_text = ""
|
32
31
|
seed = nil
|
33
32
|
|
@@ -44,22 +43,30 @@ class C7Decrypt
|
|
44
43
|
|
45
44
|
# The Encryption Method for Cisco Type-7 Encrypted Strings
|
46
45
|
# @param [String] the plaintext password
|
47
|
-
# @param [String] the seed for the encryption used
|
46
|
+
# @param [String] the seed for the encryption used
|
47
|
+
# @raise [InvalidEncryptionSeed,
|
48
|
+
# InvalidFirstCharacter,
|
49
|
+
# InvalidCharacter,
|
50
|
+
# OddNumberOfCharacters]
|
48
51
|
# @return [String] the encrypted password
|
49
52
|
def encrypt(d_text, seed = 2)
|
53
|
+
check_seed(seed)
|
54
|
+
|
50
55
|
e_text = sprintf("%02d", seed)
|
51
56
|
|
52
57
|
d_text.each_char.each_with_index do |d_char,i|
|
53
58
|
e_text += encrypt_char(d_char, i, seed)
|
54
59
|
end
|
55
60
|
|
61
|
+
check_type_7_errors(e_text)
|
62
|
+
|
56
63
|
return e_text
|
57
64
|
end
|
58
65
|
|
59
66
|
# The method for encrypting a single character
|
60
67
|
# @param [String] the plain text char
|
61
|
-
# @param [
|
62
|
-
# @param [
|
68
|
+
# @param [FixNum] the index of the char in plaintext string
|
69
|
+
# @param [FixNum] the seed used in the encryption process
|
63
70
|
# @return [String] the string of the encrypted char
|
64
71
|
def encrypt_char(char, i, seed)
|
65
72
|
sprintf("%02X", char.unpack('C')[0] ^ VT_TABLE[(i + seed) % 53])
|
@@ -76,6 +83,9 @@ class C7Decrypt
|
|
76
83
|
|
77
84
|
# A helper method to decrypt an arracy of Cisco Type-7 Encrypted Strings
|
78
85
|
# @param [Array>String] an array of Cisco Type-7 Encrypted Strings
|
86
|
+
# @raise [InvalidFirstCharacter,
|
87
|
+
# InvalidCharacter,
|
88
|
+
# OddNumberOfCharacters]
|
79
89
|
# @return [Array>String] an array of Decrypted Strings
|
80
90
|
def decrypt_array(pw_array)
|
81
91
|
pw_array.collect {|pw| decrypt(pw)}
|
@@ -83,26 +93,84 @@ class C7Decrypt
|
|
83
93
|
|
84
94
|
# A helper method to encrypt an arracy of passwords
|
85
95
|
# @param [Array>String] an array of plain-text passwords
|
96
|
+
# @raise [InvalidEncryptionSeed,
|
97
|
+
# InvalidFirstCharacter,
|
98
|
+
# InvalidCharacter,
|
99
|
+
# OddNumberOfCharacters]
|
86
100
|
# @return [Array>String] an array of encrypted passwords
|
87
101
|
def encrypt_array(pt_array, seed = 2)
|
88
102
|
pt_array.collect {|pw| encrypt(pw, seed)}
|
89
103
|
end
|
90
104
|
|
91
|
-
# This method scans a raw config file for type 7 passwords and
|
92
|
-
#
|
105
|
+
# This method scans a raw config file for type 7 passwords and
|
106
|
+
# decrypts them
|
107
|
+
# @param [String] a string of the config file path that contains
|
108
|
+
# Cisco Type-7 Encrypted Strings
|
109
|
+
# @raise [InvalidFirstCharacter,
|
110
|
+
# InvalidCharacter,
|
111
|
+
# OddNumberOfCharacters]
|
93
112
|
# @return [Array>String] an array of Decrypted Strings
|
94
113
|
def decrypt_config(file)
|
95
114
|
f = File.open(file, 'r').to_a
|
96
115
|
decrypt_array(f.collect {|line| type_7_matches(line)}.flatten)
|
97
116
|
end
|
98
117
|
|
99
|
-
# This method scans a config line for encrypted type-7 passwords and
|
118
|
+
# This method scans a config line for encrypted type-7 passwords and
|
119
|
+
# returns an array of results
|
100
120
|
# @param [String] a line with potential encrypted type-7 passwords
|
101
121
|
# @return [Array>String] an array of Cisco type-7 encrypted Strings
|
102
122
|
def type_7_matches(string)
|
103
123
|
TYPE_7_REGEXES.collect {|regex| string.scan(regex)}.flatten.uniq
|
104
124
|
end
|
105
125
|
|
126
|
+
# This method determines if an encrypted hash is corrupted/invalid
|
127
|
+
# and throw a specific exeception
|
128
|
+
# @param [String] the Cisco Type-7 Encrypted String
|
129
|
+
# @raise [InvalidFirstCharacter, InvalidCharacter, OddNumberOfCharacters]
|
130
|
+
# @return [Nil]
|
131
|
+
def check_type_7_errors(e_text)
|
132
|
+
|
133
|
+
valid_first_chars = (0..15).to_a.collect {|c| sprintf("%02d", c)}
|
134
|
+
first_char = e_text[0,2]
|
135
|
+
|
136
|
+
# Check for an invalid first character in the has
|
137
|
+
unless valid_first_chars.include? first_char
|
138
|
+
raise InvalidFirstCharacter,
|
139
|
+
"'#{e_text}' hash contains an invalid first chracter (only '00' - '15' allowed)"
|
140
|
+
end
|
141
|
+
|
142
|
+
# Check for an invalid character in the hash
|
143
|
+
unless e_text.match(/^[A-Z0-9]+$/)
|
144
|
+
raise InvalidCharacter,
|
145
|
+
"'#{e_text}' hash contains an invalid character (only upper-alpha numeric allowed)"
|
146
|
+
end
|
147
|
+
|
148
|
+
# Check for an odd number of characters in the hash
|
149
|
+
unless e_text.size % 2 == 0
|
150
|
+
raise OddNumberOfCharacters,
|
151
|
+
"'#{e_text}' hash contains odd length of chars (only even number of chars allowed)"
|
152
|
+
end
|
153
|
+
|
154
|
+
return nil
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
# This method determines if an encryption seed is valid or not
|
159
|
+
# and throw a specific exeception
|
160
|
+
# @param [FixNum] the seed used in the encryption process
|
161
|
+
# @raise [InvalidEncryptionSeed]
|
162
|
+
# @return [Nil]
|
163
|
+
def check_seed(seed)
|
164
|
+
if seed < 0 ||
|
165
|
+
seed > 15
|
166
|
+
|
167
|
+
raise InvalidEncryptionSeed,
|
168
|
+
"'#{seed.to_s}' seed is not a valid seed (only 0 - 15 allowed)"
|
169
|
+
end
|
170
|
+
|
171
|
+
return nil
|
172
|
+
end
|
173
|
+
|
106
174
|
#Definition of short-hand methods for the lazy
|
107
175
|
alias :d :decrypt
|
108
176
|
alias :e :encrypt
|