c7decrypt 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /coverage
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ - 1.9.2
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - rbx-18mode
9
+ - rbx-19mode
10
+ - ruby-head
11
+ - jruby-head
12
+ - 1.8.7
13
+ - ree
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,47 @@
1
+ # Contributing to C7Decrypt
2
+
3
+ Thanks for your interest in contributing to C7Decrypt.
4
+
5
+ If you could follow the following guidelines, you will make it much easier for
6
+ us to give feedback, help you find whatever problem you have and fix it.
7
+
8
+ ## Issues
9
+
10
+ If you have questions of any kind, or are unsure of how something works, please
11
+ [create an issue](https://github.com/claudijd/c7decrypt/issues/new).
12
+
13
+ Please try to answer the following questions in your issue:
14
+
15
+ - What did you do?
16
+ - What did you expect to happen?
17
+ - What happened instead?
18
+
19
+ If you have identified a bug, it would be very helpful if you could include a
20
+ way to replicate the bug. Ideally a failing test would be perfect, but even a
21
+ simple script demonstrating the error would suffice.
22
+
23
+ Feature requests are great and if submitted they will be considered for
24
+ inclusion, but sending a pull request is much more awesome.
25
+
26
+ ## Pull Requests
27
+
28
+ If you want your pull requests to be accepted, please follow the following guidelines:
29
+
30
+ - [**Add tests!**](http://rspec.info/) Your patch won't be accepted (or will be delayed) if it doesn't have tests.
31
+
32
+ - [**Document any change in behaviour**](http://yardoc.org/) Make sure the README and any other
33
+ relevant documentation are kept up-to-date.
34
+
35
+ - [**Create topic branches**](https://github.com/dchelimsky/rspec/wiki/Topic-Branches) Don't ask us to pull from your master branch.
36
+
37
+ - [**One pull request per feature**](https://help.github.com/articles/using-pull-requests) If you want to do more than one thing, send
38
+ multiple pull requests.
39
+
40
+ - [**Send coherent history**](http://stackoverflow.com/questions/6934752/git-combining-multiple-commits-before-pushing) Make sure each individual commit in your pull
41
+ request is meaningful. If you had to make multiple intermediate commits while
42
+ developing, please squash them before sending them to us.
43
+
44
+ - [**Follow coding conventions**](https://github.com/styleguide/ruby) The standard Ruby stuff, two spaces indent,
45
+ don't omit parens unless you have a good reason.
46
+
47
+ Thank you so much for contributing!
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rspec"
4
+ gem "rake"
5
+ gem 'simplecov', :require => false, :group => :test
6
+
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2012, Jonathan Claudius
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ * Neither the name of Jonathan Claudius nor the
13
+ names of its contributors may be used to endorse or promote products
14
+ derived from this software without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY JONTHAN CLAUDIUS ''AS IS'' AND ANY
17
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL JONATHAN CLAUDIUS BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ ![Cisco Logo](https://github.com/claudijd/c7decrypt/blob/master/images/cisco.jpeg?raw=true)
2
+
3
+ # C7Decrypt
4
+
5
+ [![Build Status](https://secure.travis-ci.org/claudijd/c7decrypt.png)](http://travis-ci.org/claudijd/c7decrypt)
6
+ [![Dependency Status](https://gemnasium.com/claudijd/c7decrypt.png)](https://gemnasium.com/claudijd/c7decrypt)
7
+ [![Code Climate](https://codeclimate.com/github/claudijd/c7decrypt.png)](https://codeclimate.com/github/claudijd/c7decrypt)
8
+
9
+ A Ruby-based implementation of a Cisco Type-7 Password Encryptor/Decryptor
10
+
11
+ ## Key Benefits
12
+
13
+ - **Written in Ruby** - First and only Cisco Type-7 implementation in Ruby that I know of.
14
+ - **Minimal/No Dependancies** - Uses native Ruby to do it's work, no heavy dependancies.
15
+ - **Not Just a Script** - Implementation is portable for use in another project or for automation of tasks.
16
+ - **Simple** - It is a small project so the interfaces are simple and easy to use.
17
+ - **Encrypt & Decrypt** - Supports both encryption (with seed control) and decryption operations.
18
+
19
+ ## Setup
20
+
21
+ To install, type
22
+
23
+ ```bash
24
+ gem install c7decrypt
25
+ ```
26
+
27
+ To use, just require
28
+
29
+ ```ruby
30
+ require 'c7decrypt'
31
+ ```
32
+
33
+ ## Example Usage(s)
34
+
35
+ Decrypt A Single Encrypted Password
36
+
37
+ ```ruby
38
+ >> C7Decrypt.decrypt("060506324F41")
39
+ => "cisco"
40
+ ```
41
+
42
+ Decrypt Array of Encrypted Passwords
43
+
44
+ ```ruby
45
+ >> encrypted_hashes = ["060506324F41", "0822455D0A16"]
46
+ => ["060506324F41", "0822455D0A16"]
47
+ >> C7Decrypt.decrypt_array(encrypted_hashes)
48
+ => ["cisco", "cisco"]
49
+ ```
50
+
51
+ Decrypt Encrypted Passwords from Config
52
+
53
+ ```ruby
54
+ >> C7Decrypt.decrypt_config("cisco_config.txt")
55
+ => ["cisco", "Password1", "admin"]
56
+ ```
57
+
58
+ Encrypt A Single Plaintext Password
59
+
60
+ ```ruby
61
+ >> C7Decrypt.encrypt("cisco")
62
+ => "02050D480809"
63
+ ```
64
+
65
+ Encrypt A Single Plaintext Password w/ Explicit Seed
66
+
67
+ ```ruby
68
+ >> C7Decrypt.encrypt("cisco", 6)
69
+ => "060506324F41"
70
+ ```
71
+
72
+ Encrypt An Array of Plaintext Passwords
73
+
74
+ ```ruby
75
+ >> passwords = ["cisco", "password"]
76
+ => ["cisco", "password"]
77
+ >> C7Decrypt.encrypt_array(passwords)
78
+ => ["02050D480809", "021605481811003348"]
79
+ ```
80
+
81
+ ## Rubies Supported
82
+
83
+ This project is integrated with [travis-ci](http://about.travis-ci.org/) and is regularly tested to work with the following rubies:
84
+
85
+ * [2.0.0](https://github.com/ruby/ruby/tree/ruby_2_0_0)
86
+ * [1.9.3](https://github.com/ruby/ruby/tree/ruby_1_9_3)
87
+ * [1.9.2](https://github.com/ruby/ruby/tree/ruby_1_9_2)
88
+ * 1.9.1 - Tested outside of Travis-CI
89
+ * [1.8.7](https://github.com/ruby/ruby/tree/ruby_1_8_7)
90
+ * 1.8.6 - Tested outside of Travis-CI
91
+ * [ruby-head](https://github.com/ruby/ruby)
92
+ * [jruby-head](http://jruby.org/)
93
+ * [jruby-19mode](http://jruby.org/)
94
+ * [jruby-18mode](http://jruby.org/)
95
+ * [rbx-19mode](http://rubini.us/)
96
+ * [rbx-18mode](http://rubini.us/)
97
+ * [ree](http://www.rubyenterpriseedition.com/)
98
+
99
+ To checkout the current build status for these rubies, click [here](https://travis-ci.org/#!/claudijd/c7decrypt).
100
+
101
+ ## Contributing
102
+
103
+ If you are interested in contributing to this project, please see [CONTRIBUTING.md](https://github.com/claudijd/c7decrypt/blob/master/CONTRIBUTING.md)
104
+
105
+ ## Credits
106
+
107
+ **Sources of Inspiration for C7Decrypt**
108
+
109
+ - [**Daren Matthew**](http://mccltd.net/blog/?p=1034) - For his blog post on the subject aggregating tools and sources that perform the decryption/decoding logic.
110
+ - [**m00nie**](http://www.m00nie.com/2011/09/cisco-type-7-password-decryption-and-encryption-with-perl/) - For the blog post on the subject, the source code of type7tool.pl and it's encryption techniques.
111
+
112
+ **Application(s) that use C7Decrypt**
113
+
114
+ - [**Marcus J Carey**](https://www.threatagent.com/c7) - For his web application implementation of this on the ThreatAgent website. Check it out and start decrypting Cisco type-7 passwords right now.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'rubygems/package_task'
5
+ require 'rspec'
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
8
+
9
+ $:.unshift File.join(File.dirname(__FILE__), "lib")
10
+
11
+ require 'c7decrypt'
12
+
13
+ task :default => :spec
14
+
15
+ desc "Run all specs in spec directory"
16
+ RSpec::Core::RakeTask.new(:spec)
17
+
18
+ def clean_up
19
+ Dir.glob("*.gem").each { |f| File.unlink(f) }
20
+ Dir.glob("*.lock").each { |f| File.unlink(f) }
21
+ end
22
+
23
+ desc "Build the gem"
24
+ task :build do
25
+ puts "[+] Building C7Decrypt version #{C7Decrypt::VERSION}"
26
+ puts `gem build c7decrypt.gemspec`
27
+ end
28
+
29
+ desc "Publish the gem"
30
+ task :publish do
31
+ puts "[+] Publishing C7Decrypt version #{C7Decrypt::VERSION}"
32
+ Dir.glob("*.gem").each { |f| puts `gem push #{f}`}
33
+ end
34
+
35
+ desc "Tag the release"
36
+ task :tag do
37
+ puts "[+] Tagging C7Decrypt version #{C7Decrypt::VERSION}"
38
+ `git tag #{C7Decrypt::VERSION}`
39
+ `git push --tags`
40
+ end
41
+
42
+ desc "Bump the Gemspec Version"
43
+ task :bump do
44
+ puts "[+] Bumping C7Decrypt version #{C7Decrypt::VERSION}"
45
+ `git commit -a -m "Bumped Gem version to #{C7Decrypt::VERSION}"`
46
+ `git push origin master`
47
+ end
48
+
49
+ desc "Perform an end-to-end release of the gem"
50
+ task :release do
51
+ clean_up() # Clean up before we start
52
+ Rake::Task[:build].execute
53
+ Rake::Task[:bump].execute
54
+ Rake::Task[:tag].execute
55
+ Rake::Task[:publish].execute
56
+ clean_up() # Clean up after we complete
57
+ end
data/c7decrypt.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ $: << "lib"
2
+ require 'c7decrypt/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'c7decrypt'
6
+ s.version = C7Decrypt::VERSION
7
+ s.authors = ["Jonathan Claudius"]
8
+ s.date = Date.today.to_s
9
+ s.email = 'claudijd@yahoo.com'
10
+ s.platform = Gem::Platform::RUBY
11
+ s.files = Dir.glob("lib/**/*") +
12
+ Dir.glob("spec/**/*") +
13
+ Dir.glob("examples/**/*") +
14
+ [".gitignore",
15
+ ".rspec",
16
+ ".travis.yml",
17
+ "CONTRIBUTING.md",
18
+ "Gemfile",
19
+ "LICENSE",
20
+ "README.md",
21
+ "Rakefile",
22
+ "c7decrypt.gemspec"]
23
+ s.require_paths = ["lib"]
24
+ s.summary = 'Ruby based Cisco Type 7 Password Decryptor'
25
+ s.description = 'A library for decoding Cisco Type 7 passwords'
26
+ s.homepage = 'http://rubygems.org/gems/c7decrypt'
27
+ end
@@ -0,0 +1,39 @@
1
+ require '../lib/c7decrypt'
2
+ require 'optparse'
3
+ require 'ostruct'
4
+
5
+ options = OpenStruct.new
6
+ options.string = nil
7
+ options.file = nil
8
+
9
+ OptionParser.new do |opts|
10
+ opts.banner = "Usage: cdecrypt.rb [options] [hash/file]"
11
+
12
+ opts.on("-s", "--string [HASH]", "A single encrypted hash string") do |v|
13
+ options.string = v
14
+ end
15
+
16
+ opts.on("-f", "--file [FILE]", "A file containing multiple hashes") do |v|
17
+ options.file = v
18
+ end
19
+
20
+ opts.on_tail("-h", "--help", "Show this message") do
21
+ puts ""
22
+ puts opts
23
+ puts ""
24
+ puts "Example: ruby cdecrypt.rb -s 04480E051A33490E"
25
+ puts "Example: ruby cdecrypt.rb -f ../spec/example_configs/simple_canned_example.txt"
26
+ puts ""
27
+ exit
28
+ end
29
+ end.parse!
30
+
31
+ if options.string
32
+ puts C7Decrypt.decrypt(options.string)
33
+ end
34
+
35
+ if options.file &&
36
+ File.exists?(options.file)
37
+
38
+ C7Decrypt.decrypt_config(options.file).each {|pw| puts pw }
39
+ end
@@ -0,0 +1,192 @@
1
+ module C7Decrypt
2
+ module Constants
3
+ # Vigenere translation table (these are our key values for decryption)
4
+ VT_TABLE = [
5
+ 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e,
6
+ 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44,
7
+ 0x48, 0x53, 0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36, 0x39,
8
+ 0x38, 0x33, 0x34, 0x6e, 0x63, 0x78, 0x76, 0x39, 0x38, 0x37, 0x33,
9
+ 0x32, 0x35, 0x34, 0x6b, 0x3b, 0x66, 0x67, 0x38, 0x37
10
+ ]
11
+
12
+ # Regexes for extracting hashes from configs
13
+ TYPE_7_REGEXES = [
14
+ /enable password 7 ([A-Z0-9]+)/,
15
+ /username [A-Z0-9]+ password 7 ([A-Z0-9]+)/,
16
+ /password 7 ([A-Z0-9]+)/
17
+ ]
18
+ end
19
+
20
+ class InvalidFirstCharacter < StandardError
21
+ end
22
+
23
+ class InvalidCharacter < StandardError
24
+ end
25
+
26
+ class OddNumberOfCharacters < StandardError
27
+ end
28
+
29
+ class InvalidEncryptionSeed < StandardError
30
+ end
31
+
32
+ # The Decryption Method for Cisco Type-7 Encrypted Strings
33
+ # @param [String] the Cisco Type-7 Encrypted String
34
+ # @raise [InvalidFirstCharacter,
35
+ # InvalidCharacter,
36
+ # OddNumberOfCharacters]
37
+ # @return [String] the Decrypted String
38
+ def self.decrypt(e_text)
39
+ check_type_7_errors(e_text)
40
+
41
+ d_text = ""
42
+ seed = nil
43
+
44
+ e_text.scan(/../).each_with_index do |char,i|
45
+ if i == 0
46
+ seed = char.to_i - 1
47
+ else
48
+ d_text += decrypt_char(char, i, seed)
49
+ end
50
+ end
51
+
52
+ return d_text
53
+ end
54
+
55
+ # The Encryption Method for Cisco Type-7 Encrypted Strings
56
+ # @param [String] the plaintext password
57
+ # @param [String] the seed for the encryption used
58
+ # @raise [InvalidEncryptionSeed,
59
+ # InvalidFirstCharacter,
60
+ # InvalidCharacter,
61
+ # OddNumberOfCharacters]
62
+ # @return [String] the encrypted password
63
+ def self.encrypt(d_text, seed = 2)
64
+ check_seed(seed)
65
+
66
+ e_text = sprintf("%02d", seed)
67
+
68
+ d_text.each_char.each_with_index do |d_char,i|
69
+ e_text += encrypt_char(d_char, i, seed)
70
+ end
71
+
72
+ check_type_7_errors(e_text)
73
+
74
+ return e_text
75
+ end
76
+
77
+ # The method for encrypting a single character
78
+ # @param [String] the plain text char
79
+ # @param [FixNum] the index of the char in plaintext string
80
+ # @param [FixNum] the seed used in the encryption process
81
+ # @return [String] the string of the encrypted char
82
+ def self.encrypt_char(char, i, seed)
83
+ sprintf("%02X", char.unpack('C')[0] ^ Constants::VT_TABLE[(i + seed) % 53])
84
+ end
85
+
86
+ # The method for decrypting a single character
87
+ # @param [String] the encrypted char
88
+ # @param [Integer] the index of the char pair in encrypted string
89
+ # @param [Integer] the seed used in the decryption process
90
+ # @return [String] the string of the decrypted char
91
+ def self.decrypt_char(char, i, seed)
92
+ (char.hex^Constants::VT_TABLE[(i + seed) % 53]).chr
93
+ end
94
+
95
+ # A helper method to decrypt an arracy of Cisco Type-7 Encrypted Strings
96
+ # @param [Array>String] an array of Cisco Type-7 Encrypted Strings
97
+ # @raise [InvalidFirstCharacter,
98
+ # InvalidCharacter,
99
+ # OddNumberOfCharacters]
100
+ # @return [Array>String] an array of Decrypted Strings
101
+ def self.decrypt_array(pw_array)
102
+ pw_array.collect {|pw| decrypt(pw)}
103
+ end
104
+
105
+ # A helper method to encrypt an arracy of passwords
106
+ # @param [Array>String] an array of plain-text passwords
107
+ # @raise [InvalidEncryptionSeed,
108
+ # InvalidFirstCharacter,
109
+ # InvalidCharacter,
110
+ # OddNumberOfCharacters]
111
+ # @return [Array>String] an array of encrypted passwords
112
+ def self.encrypt_array(pt_array, seed = 2)
113
+ pt_array.collect {|pw| encrypt(pw, seed)}
114
+ end
115
+
116
+ # This method scans a raw config file for type 7 passwords and
117
+ # decrypts them
118
+ # @param [String] a string of the config file path that contains
119
+ # Cisco Type-7 Encrypted Strings
120
+ # @raise [InvalidFirstCharacter,
121
+ # InvalidCharacter,
122
+ # OddNumberOfCharacters]
123
+ # @return [Array>String] an array of Decrypted Strings
124
+ def self.decrypt_config(file)
125
+ f = File.open(file, 'r').to_a
126
+ decrypt_array(f.collect {|line| type_7_matches(line)}.flatten)
127
+ end
128
+
129
+ # This method scans a config line for encrypted type-7 passwords and
130
+ # returns an array of results
131
+ # @param [String] a line with potential encrypted type-7 passwords
132
+ # @return [Array>String] an array of Cisco type-7 encrypted Strings
133
+ def self.type_7_matches(string)
134
+ Constants::TYPE_7_REGEXES.collect {|regex| string.scan(regex)}.flatten.uniq
135
+ end
136
+
137
+ # This method determines if an encrypted hash is corrupted/invalid
138
+ # and throw a specific exeception
139
+ # @param [String] the Cisco Type-7 Encrypted String
140
+ # @raise [InvalidFirstCharacter, InvalidCharacter, OddNumberOfCharacters]
141
+ # @return [Nil]
142
+ def self.check_type_7_errors(e_text)
143
+
144
+ valid_first_chars = (0..15).to_a.collect {|c| sprintf("%02d", c)}
145
+ first_char = e_text[0,2]
146
+
147
+ # Check for an invalid first character in the has
148
+ unless valid_first_chars.include? first_char
149
+ raise InvalidFirstCharacter,
150
+ "'#{e_text}' hash contains an invalid first chracter (only '00' - '15' allowed)"
151
+ end
152
+
153
+ # Check for an invalid character in the hash
154
+ unless e_text.match(/^[A-Z0-9]+$/)
155
+ raise InvalidCharacter,
156
+ "'#{e_text}' hash contains an invalid character (only upper-alpha numeric allowed)"
157
+ end
158
+
159
+ # Check for an odd number of characters in the hash
160
+ unless e_text.size % 2 == 0
161
+ raise OddNumberOfCharacters,
162
+ "'#{e_text}' hash contains odd length of chars (only even number of chars allowed)"
163
+ end
164
+
165
+ return nil
166
+
167
+ end
168
+
169
+ # This method determines if an encryption seed is valid or not
170
+ # and throw a specific exeception
171
+ # @param [FixNum] the seed used in the encryption process
172
+ # @raise [InvalidEncryptionSeed]
173
+ # @return [Nil]
174
+ def self.check_seed(seed)
175
+ if seed < 0 ||
176
+ seed > 15
177
+
178
+ raise InvalidEncryptionSeed,
179
+ "'#{seed.to_s}' seed is not a valid seed (only 0 - 15 allowed)"
180
+ end
181
+
182
+ return nil
183
+ end
184
+
185
+ #Definition of short-hand methods for the lazy
186
+ #alias :d :decrypt
187
+ #alias :e :encrypt
188
+ #alias :d_a :decrypt_array
189
+ #alias :e_a :encrypt_array
190
+ #alias :d_c :decrypt_config
191
+
192
+ end
@@ -0,0 +1,3 @@
1
+ module C7Decrypt
2
+ VERSION = '0.2.1'
3
+ end
@@ -0,0 +1,233 @@
1
+ require 'spec_helper'
2
+ require 'c7decrypt'
3
+
4
+ describe C7Decrypt do
5
+
6
+ before(:each) do
7
+ @known_values = [
8
+ {:pt => "cisco", :seed => 2, :ph => "02050D480809"},
9
+ {:pt => "cisco", :seed => 3, :ph => "030752180500"},
10
+ {:pt => "cisco", :seed => 4, :ph => "045802150C2E"},
11
+ {:pt => "cisco", :seed => 5, :ph => "05080F1C2243"},
12
+ {:pt => "cisco", :seed => 6, :ph => "060506324F41"},
13
+ {:pt => "cisco", :seed => 7, :ph => "070C285F4D06"},
14
+ {:pt => "cisco", :seed => 8, :ph => "0822455D0A16"},
15
+ {:pt => "cisco", :seed => 9, :ph => "094F471A1A0A"},
16
+ {:pt => "password", :seed => 9, :ph => "095C4F1A0A1218000F"},
17
+ {:pt => "password", :seed => 4, :ph => "044B0A151C36435C0D"}
18
+ ]
19
+ end
20
+
21
+ context "when decrypting single Cisco Type-7 hash using longhand" do
22
+ before(:each) do
23
+ @encrypted_hash = "060506324F41"
24
+ @decrypted_hash = C7Decrypt.decrypt(@encrypted_hash)
25
+ end
26
+
27
+ subject{@decrypted_hash}
28
+ its(:class) {should == ::String}
29
+ it {should == "cisco"}
30
+ end
31
+
32
+ context "when decrypting an array of Cisco Type-7 hashes" do
33
+ before(:each) do
34
+ @encrypted_hashes = [
35
+ "060506324F41",
36
+ "0822455D0A16"
37
+ ]
38
+ @decrypted_hashes = C7Decrypt.decrypt_array(@encrypted_hashes)
39
+ end
40
+
41
+ subject{@decrypted_hashes}
42
+ its(:class) {should == ::Array}
43
+ its(:first) {should == "cisco"}
44
+ its(:last) {should == "cisco"}
45
+ its(:size) {should == 2}
46
+ end
47
+
48
+ context "when decrypting Cisco Type-7 hashes from a config" do
49
+ before(:each) do
50
+ @config_file = "./spec/example_configs/simple_canned_example.txt"
51
+ @decrypted_hashes = C7Decrypt.decrypt_config(@config_file)
52
+ end
53
+
54
+ subject{@decrypted_hashes}
55
+ its(:class) {should == ::Array}
56
+ its(:size) {should == 5}
57
+ it {should == [
58
+ "cisco",
59
+ "cisco",
60
+ "cisco",
61
+ "cisco",
62
+ "cisco"
63
+ ]}
64
+ end
65
+
66
+ context "when decrypting known Cisco Type-7 known value matches" do
67
+ before(:each) do
68
+ @decrypted_hashes = C7Decrypt.decrypt_array(
69
+ @known_values.map {|known_value| known_value[:ph]}
70
+ )
71
+ end
72
+
73
+ subject{@decrypted_hashes}
74
+ its(:class) {should == ::Array}
75
+ its(:size) {should == @known_values.size}
76
+ it {should == @known_values.map {|known_value| known_value[:pt]}}
77
+ end
78
+
79
+ context "when decrypting Cisco Type-7 with a seed greater than 9" do
80
+ before(:each) do
81
+ @decrypt_hash = C7Decrypt.decrypt("15000E010723382727")
82
+ end
83
+
84
+ subject{@decrypt_hash}
85
+ its(:class) {should == ::String}
86
+ it {should == "remcisco"}
87
+ end
88
+
89
+ context "when matchings known Cisco Type-7 known config line matches" do
90
+ before(:each) do
91
+ @encrypted_hashes = []
92
+ @known_config_lines = {
93
+ "username test password 7 0822455D0A16" => "0822455D0A16",
94
+ "enable password 7 060506324F41" => "060506324F41",
95
+ "password 7 02050D480809" => "02050D480809"
96
+ }
97
+
98
+ @known_config_lines.keys.each do |k,v|
99
+ @encrypted_hashes << C7Decrypt.type_7_matches(k)
100
+ end
101
+ @encrypted_hashes.flatten!
102
+ end
103
+
104
+ subject{@encrypted_hashes}
105
+ its(:class) {should == ::Array}
106
+ its(:size) {should == @known_config_lines.size}
107
+ it {should == @known_config_lines.values}
108
+ end
109
+
110
+ context "when encrypting single Cisco Type-7 hash" do
111
+ before(:each) do
112
+ @plaintext_hash = "cisco"
113
+ @encrypted_hash = C7Decrypt.encrypt(@plaintext_hash)
114
+ end
115
+
116
+ subject{@encrypted_hash}
117
+ its(:class) {should == ::String}
118
+ it {should == "02050D480809"}
119
+ end
120
+
121
+ context "when encrypting single Cisco Type-7 hash with an alternate seed value" do
122
+ before(:each) do
123
+ @plaintext_hash = "cisco"
124
+ @seed = 3
125
+ @encrypted_hash = C7Decrypt.encrypt(@plaintext_hash, @seed)
126
+ end
127
+
128
+ subject{@encrypted_hash}
129
+ its(:class) {should == ::String}
130
+ it {should == "030752180500"}
131
+
132
+ it "should decrypt back to the original plaintext hash" do
133
+ C7Decrypt.decrypt(@encrypted_hash).should == @plaintext_hash
134
+ end
135
+ end
136
+
137
+ context "when encrypting multiple plaintext passwords with alternate seed values" do
138
+ before(:each) do
139
+ @plaintext_hash = "cisco"
140
+ @seeds = 0..15
141
+ @encrypted_hashes = @seeds.map {|seed| C7Decrypt.encrypt(@plaintext_hash, seed)}
142
+ end
143
+
144
+ subject{@encrypted_hashes}
145
+ its(:class) {should == ::Array}
146
+
147
+ it "should decrypt back to the original plaintext hashes" do
148
+ @encrypted_hashes.each do |encrypted_hash|
149
+ C7Decrypt.decrypt(encrypted_hash).should == @plaintext_hash
150
+ end
151
+ end
152
+ end
153
+
154
+ context "when encrypting known value matches individually" do
155
+ before(:each) do
156
+ @encrypted_hashes = []
157
+ @known_values.each do |known_value|
158
+ @encrypted_hashes << C7Decrypt.encrypt(known_value[:pt], known_value[:seed])
159
+ end
160
+ end
161
+
162
+ subject{@encrypted_hashes}
163
+ its(:class) {should == ::Array}
164
+ its(:size) {should == @known_values.size}
165
+ it {should == @known_values.map {|known_value| known_value[:ph]}}
166
+ end
167
+
168
+ context "when encrypting known value matches individually as an array" do
169
+ before(:each) do
170
+ @plaintext_passwords = @known_values.map {|known_value| known_value[:pt]}.uniq
171
+ @encrypted_passwords = C7Decrypt.encrypt_array(@plaintext_passwords)
172
+ end
173
+
174
+ subject{@encrypted_passwords}
175
+ its(:class) {should == ::Array}
176
+ its(:size) {should == @plaintext_passwords.size}
177
+ it {should == @plaintext_passwords.map {|plaintext_password| C7Decrypt.encrypt(plaintext_password)}}
178
+ end
179
+
180
+ context "when encrypting Cisco Type-7" do
181
+ before(:each) do
182
+ @plaintext_hash = "remcisco"
183
+ @encrypted_hash = C7Decrypt.encrypt(@plaintext_hash)
184
+ end
185
+
186
+ subject{@encrypted_hash}
187
+ its(:class) {should == ::String}
188
+ it {should == "02140156080F1C2243"}
189
+ end
190
+
191
+ context "when encrypting Cisco Type-7 with a seed of 15" do
192
+ before(:each) do
193
+ @plaintext_hash = "remcisco"
194
+ @seed = 15
195
+ @encrypted_hash = C7Decrypt.encrypt(@plaintext_hash, @seed)
196
+ end
197
+
198
+ subject{@encrypted_hash}
199
+ its(:class) {should == ::String}
200
+ it {should == "15000E010723382727"}
201
+ end
202
+
203
+ context "when trying to decrypt a hash with an invalid first character" do
204
+ it "should raise an InvalidFirstCharacter Exception" do
205
+ expect { C7Decrypt.decrypt("AA000E010723382727") }.to raise_error(C7Decrypt::InvalidFirstCharacter)
206
+ end
207
+ end
208
+
209
+ context "when trying to decrypt a hash with an invalid character" do
210
+ it "should raise an InvalidFirstCharacter Exception" do
211
+ expect { C7Decrypt.decrypt("06000**E010723382727") }.to raise_error(C7Decrypt::InvalidCharacter)
212
+ end
213
+ end
214
+
215
+ context "when trying to decrypt a hash with an odd number of characters" do
216
+ it "should raise an InvalidFirstCharacter Exception" do
217
+ expect { C7Decrypt.decrypt("06000E01723382727") }.to raise_error(C7Decrypt::OddNumberOfCharacters)
218
+ end
219
+ end
220
+
221
+ context "when trying to encrypt a hash with an invalid high encryption seed" do
222
+ it "should raise an InvalidFirstCharacter Exception" do
223
+ expect { C7Decrypt.encrypt("bananas", 16) }.to raise_error(C7Decrypt::InvalidEncryptionSeed)
224
+ end
225
+ end
226
+
227
+ context "when trying to encrypt a hash with an invalid low encryption seed" do
228
+ it "should raise an InvalidFirstCharacter Exception" do
229
+ expect { C7Decrypt.encrypt("bananas", -1) }.to raise_error(C7Decrypt::InvalidEncryptionSeed)
230
+ end
231
+ end
232
+
233
+ end
@@ -0,0 +1,13 @@
1
+ # Removed "7"
2
+ username password 0822455D0A16
3
+ # Removed password
4
+ username password 7
5
+ # changed password to pword
6
+ enable pword 7 060506324F41
7
+ # changed hash to something weird, but still expect this to "hit"
8
+ enable password 7 abc123
9
+ R3(config)#do show run | sec vty
10
+ line vty 0 4
11
+ # again changed hash to something weird, expect this to "hit" but it doesn't ...
12
+ password 7 /etc/passwd
13
+ login
File without changes
@@ -0,0 +1,8 @@
1
+ username test password 7 0822455D0A16
2
+ username test password 7 0822455D0A16
3
+ enable password 7 060506324F41
4
+ enable password 7 060506324F41
5
+ R3(config)#do show run | sec vty
6
+ line vty 0 4
7
+ password 7 02050D480809
8
+ login
@@ -0,0 +1,7 @@
1
+ begin
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+ rescue LoadError
5
+ warn "Couldn't load simplecov, so coverage reports will be generated"
6
+ warn "Run 'gem install simplecov' to get coverage reports"
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: c7decrypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-05 00:00:00.000000000 Z
12
+ date: 2013-05-28 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A library for decoding Cisco Type 7 passwords
15
15
  email: claudijd@yahoo.com
@@ -17,7 +17,24 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - lib/c7decrypt/c7decrypt.rb
21
+ - lib/c7decrypt/version.rb
20
22
  - lib/c7decrypt.rb
23
+ - spec/c7decrypt_spec.rb
24
+ - spec/example_configs/bad_canned_example.txt
25
+ - spec/example_configs/empty_example.txt
26
+ - spec/example_configs/simple_canned_example.txt
27
+ - spec/spec_helper.rb
28
+ - examples/cdecrypt.rb
29
+ - .gitignore
30
+ - .rspec
31
+ - .travis.yml
32
+ - CONTRIBUTING.md
33
+ - Gemfile
34
+ - LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - c7decrypt.gemspec
21
38
  homepage: http://rubygems.org/gems/c7decrypt
22
39
  licenses: []
23
40
  post_install_message:
@@ -30,9 +47,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
30
47
  - - ! '>='
31
48
  - !ruby/object:Gem::Version
32
49
  version: '0'
33
- segments:
34
- - 0
35
- hash: 4090891342571299322
36
50
  required_rubygems_version: !ruby/object:Gem::Requirement
37
51
  none: false
38
52
  requirements:
@@ -41,7 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
55
  version: '0'
42
56
  requirements: []
43
57
  rubyforge_project:
44
- rubygems_version: 1.8.25
58
+ rubygems_version: 1.8.23
45
59
  signing_key:
46
60
  specification_version: 3
47
61
  summary: Ruby based Cisco Type 7 Password Decryptor