c7decrypt 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|