router_crypt 0.3.0

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.
@@ -0,0 +1 @@
1
+ gems/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ group :test do
2
+ gem 'rspec'
3
+ end
@@ -0,0 +1,17 @@
1
+ GEM
2
+ specs:
3
+ diff-lcs (1.2.1)
4
+ rspec (2.13.0)
5
+ rspec-core (~> 2.13.0)
6
+ rspec-expectations (~> 2.13.0)
7
+ rspec-mocks (~> 2.13.0)
8
+ rspec-core (2.13.0)
9
+ rspec-expectations (2.13.0)
10
+ diff-lcs (>= 1.1.3, < 2.0)
11
+ rspec-mocks (2.13.0)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ rspec
@@ -0,0 +1,36 @@
1
+ router_crypt
2
+ ============
3
+
4
+ About
5
+ -----
6
+ Ruby library and executable to (de)crypt various router vendors (JunOS, IOS, NXOS) password. As of now, only decrypt is implemented
7
+
8
+
9
+ Installation
10
+ ------------
11
+ gem install router_crypt
12
+
13
+
14
+ CLI usage
15
+ ---------
16
+ rtrcrypt [encrypted password]
17
+
18
+
19
+ Library usage
20
+ -------------
21
+ require 'router_crypt'
22
+
23
+ RouterCrypt::IOS.decrypt ios_pw
24
+ RouterCrypt::NXOS.decrypt nxos_pw
25
+ RouterCrypt::JunOS.decrypt junos_pw
26
+
27
+
28
+ Thanks
29
+ ------
30
+ I've ripped the JunOS algo from CPAN Crypt::Juniper by Kevin Brintnall. IOS algo
31
+ source is unknown I've ported it long time ago from anonymous perl source.
32
+
33
+
34
+ License
35
+ -------
36
+ Public domain, copyleft, whatnot
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby20
2
+
3
+ require 'router_crypt'
4
+
5
+ begin
6
+ p RouterCrypt::CLI.run
7
+ rescue => e
8
+ warn "ERROR: #{e}"
9
+ end
@@ -0,0 +1,16 @@
1
+ class RouterCrypt::CLI
2
+ class << self
3
+ def run
4
+ pw = ARGV[0].dup or raise ArgumentError, 'no password given'
5
+ case pw
6
+ when /^\$9\$/
7
+ RouterCrypt::JunOS.decrypt pw
8
+ when /^[\dA-F]+$/
9
+ RouterCrypt::IOS.decrypt pw
10
+ else
11
+ #presume it's NXOS, no clear way to separate garbage and NXOS PW
12
+ RouterCrypt::NXOS.decrypt pw
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ class RouterCrypt::IOS
2
+ KEY = 'dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncxv9873254k;fg87'.unpack("C*")
3
+ end
@@ -0,0 +1,15 @@
1
+ class RouterCrypt::IOS
2
+ class << self
3
+ # Decrypts IOS type 7 passwords. Original is from unknown perl source
4
+ #
5
+ # @param [String] the encrypted string
6
+ # @return [String] the unencrypted string
7
+ def decrypt e_pw
8
+ index = e_pw.slice!(0..1).to_i-1
9
+ e_pw.scan(/../).inject("") do |d_pw, byte|
10
+ index += 1 % KEY.size
11
+ d_pw + (byte.hex ^ KEY[index]).chr
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ class RouterCrypt::JunOS
2
+ class InvalidPW < StandardError; end
3
+
4
+ ENCODE = [
5
+ [ 1, 4, 32 ],
6
+ [ 1, 16, 32 ],
7
+ [ 1, 8, 32 ],
8
+ [ 1, 64 ],
9
+ [ 1, 32 ],
10
+ [ 1, 4, 16, 128 ],
11
+ [ 1, 32, 64 ],
12
+ ]
13
+ EXTRA = {}
14
+ KEY = %w( QzF3n6/9CAtpu0O B1IREhcSyrleKvMW8LXx 7N-dVbwsY2g4oaJZGUDj iHkq.mPf5T )
15
+ KEYCHAR = KEY.join.each_char.to_a
16
+ KEY.each_with_index do |key, index|
17
+ key.each_char { |c| EXTRA[c] = 3-index }
18
+ end
19
+
20
+ class << self
21
+
22
+ private
23
+
24
+ def nibble str, len
25
+ nib, str[0..len-1] = str[0..len-1], ''
26
+ nib.size == len or raise InvalidPW, 'Insufficent amont of characters'
27
+ nib
28
+ end
29
+
30
+ def gap c1, c2
31
+ (KEYCHAR.index(c1) - KEYCHAR.index(c2)) % KEYCHAR.size - 1
32
+ end
33
+
34
+ def gap_decode gaps, dec
35
+ gaps.size == dec.size or raise InvalidPW, 'gaps and dec are unequal size'
36
+ (gaps.each_with_index.inject(0) { |num, (e, index)| num + e * dec[index] } % 256).chr
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,27 @@
1
+ class RouterCrypt::JunOS
2
+ class << self
3
+ # Decrypts JunOS $9$ style passwords. This is reimplementation of CPAN
4
+ # Crypt::Juniper (by Kevin Brintnall, <kbrint at rufus.net>) ''juniper_decrypt' function
5
+ #
6
+ # @param [String] the encrypted string, with or without $9$ in front of it
7
+ # @return [String] the unencrypted string
8
+ def decrypt e_pw
9
+ e_pw = e_pw[3..-1] if e_pw['$9$']
10
+ d_pw = ''
11
+ prev = nibble e_pw, 1
12
+ nibble e_pw, EXTRA[prev]
13
+
14
+ while e_pw.size > 0
15
+ decode = ENCODE[d_pw.size % ENCODE.size]
16
+ gaps = nibble(e_pw, decode.size).each_char.map do |e|
17
+ g = gap e, prev
18
+ prev = e
19
+ g
20
+ end
21
+ d_pw += gap_decode gaps, decode
22
+ end
23
+
24
+ d_pw
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ class RouterCrypt::NXOS
2
+ KEY = 'dwefsavfsdkfqweqyrmfvsfwthdwefsavfsdkfqweqyrmfvsfwthdwefsavfsdk'.unpack('C*')
3
+ ALPHA = ('a'..'z').to_a
4
+ end
@@ -0,0 +1,15 @@
1
+ class RouterCrypt::NXOS
2
+ class << self
3
+ # Decrypts NXOS type 7 passwords, original research
4
+ #
5
+ # @param [String] the unencrypted string
6
+ # @return [String] the decrypted string
7
+ def decrypt e_pw
8
+ index = -1
9
+ e_pw.each_char.inject("") do |d_pw, chr|
10
+ index += 1
11
+ d_pw + (ALPHA.include?(chr) ? ALPHA[chr.ord - KEY[index]] : chr)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ class RouterCrypt
2
+ end
3
+
4
+ require 'junos/common'
5
+ require 'junos/decrypt'
6
+ require 'ios/common'
7
+ require 'ios/decrypt'
8
+ require 'nxos/common'
9
+ require 'nxos/decrypt'
10
+ require 'cli/cli'
@@ -0,0 +1,36 @@
1
+ begin
2
+ require 'bundler'
3
+ require 'rspec/core/rake_task'
4
+ Bundler.setup
5
+ rescue LoadError
6
+ warn 'missing dependencies'
7
+ exit 42
8
+ end
9
+
10
+
11
+ gemspec = eval(File.read(Dir['*.gemspec'].first))
12
+
13
+ desc 'Validate the gemspec'
14
+ task :gemspec do
15
+ gemspec.validate
16
+ end
17
+
18
+ RSpec::Core::RakeTask.new(:spec)
19
+
20
+
21
+ desc "Build gem locally"
22
+ task :build => %i(spec gemspec) do
23
+ system "gem build #{gemspec.name}.gemspec"
24
+ FileUtils.mkdir_p "gems"
25
+ FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", "gems"
26
+ end
27
+
28
+ desc "Install gem locally"
29
+ task :install => :build do
30
+ system "sudo sh -c \'umask 022; gem20 install gems/#{gemspec.name}-#{gemspec.version}\'"
31
+ end
32
+
33
+ desc "Clean automatically generated files"
34
+ task :clean do
35
+ FileUtils.rm_rf "gems"
36
+ end
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'router_crypt'
3
+ s.version = '0.3.0'
4
+ s.platform = Gem::Platform::RUBY
5
+ s.authors = [ 'Saku Ytti' ]
6
+ s.email = %w( saku@ytti.fi )
7
+ s.homepage = 'http://github.com/ytti/router_crypt'
8
+ s.summary = 'Crypt library for JunOS/IOS/NX-OS passwords'
9
+ s.description = 'Library and binary which decrypt (crypt unimplemented) Juniper JunOS $9$, Cisco IOS type 7 and Cisco NX-OS passwords'
10
+ s.rubyforge_project = s.name
11
+ s.files = `git ls-files`.split("\n")
12
+ s.executables = %w( rtrcrypt )
13
+ s.require_path = 'lib'
14
+ s.required_rubygems_version = '>= 1.3.6'
15
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'router_crypt'
3
+
4
+ describe RouterCrypt::IOS, '#decrypt' do
5
+ it 'returns correct decrypted password' do
6
+ clear = RouterCrypt::IOS.decrypt CRYPT_IOS
7
+ clear.should eq CLEAR
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ require 'router_crypt'
2
+
3
+
4
+ describe RouterCrypt::JunOS, '#nibble' do
5
+ it 'returns k for 1 char out of "kakka"' do
6
+ str = 'kakka'
7
+ nib = RouterCrypt::JunOS.send :nibble, str, 1
8
+ nib.should eq 'k'
9
+ str.should eq 'akka'
10
+ end
11
+ it 'returns kak for 3 char out of "kakka"' do
12
+ str = 'kakka'
13
+ nib = RouterCrypt::JunOS.send :nibble, str, 3
14
+ nib.should eq 'kak'
15
+ str.should eq 'ka'
16
+ end
17
+ end
18
+
19
+ describe RouterCrypt::JunOS, '#gap' do
20
+ it 'returns 7 for gap between k and J' do
21
+ gap = RouterCrypt::JunOS.send :gap, 'k', 'J'
22
+ gap.should eq 7
23
+ end
24
+ it 'returns 56 for gap between J and k' do
25
+ gap = RouterCrypt::JunOS.send :gap, 'J', 'k'
26
+ gap.should eq 56
27
+ end
28
+ end
29
+
30
+ describe RouterCrypt::JunOS, "#gaps" do
31
+ it 'returns ) for [gaps], [dec]' do
32
+ chr = RouterCrypt::JunOS.send :gap_decode, RouterCrypt::JunOS::ENCODE[1], [9, 42, 12]
33
+ chr.should eq ')'
34
+ end
35
+ it 'returns n for [gaps2], [dec2]' do
36
+ chr = RouterCrypt::JunOS.send :gap_decode, RouterCrypt::JunOS::ENCODE[5], [42, 69, 99, 4]
37
+ chr.should eq 'n'
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'router_crypt'
3
+
4
+ describe RouterCrypt::JunOS, '#decrypt' do
5
+ it 'returns correct decrypted password' do
6
+ clear = RouterCrypt::JunOS.decrypt CRYPT_JUNOS
7
+ clear.should eq CLEAR
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'router_crypt'
3
+
4
+ describe RouterCrypt::NXOS, '#decrypt' do
5
+ it 'returns correct decrypted password' do
6
+ clear = RouterCrypt::NXOS.decrypt CRYPT_NXOS
7
+ clear.should eq CLEAR
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ CLEAR = '99problemsbutpwaintone'
2
+ CRYPT_JUNOS = '$9$40aikFn/9tOQFRSleXxoJGDi.CA0Ihr.PRSylXxGDi.Qn/9p0BEz3rvLNY2.P5QF/'
3
+ CRYPT_IOS = '12405C0700040E082F26372A26213204061F0D1559575D'
4
+ CRYPT_NXOS = '99twgbgjevlzjlaqgeftiw'
5
+
6
+ RSpec.configure do |config|
7
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: router_crypt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Saku Ytti
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-07 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Library and binary which decrypt (crypt unimplemented) Juniper JunOS
15
+ $9$, Cisco IOS type 7 and Cisco NX-OS passwords
16
+ email:
17
+ - saku@ytti.fi
18
+ executables:
19
+ - rtrcrypt
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - .gitignore
24
+ - .rspec
25
+ - Gemfile
26
+ - Gemfile.lock
27
+ - README.md
28
+ - bin/rtrcrypt
29
+ - lib/cli/cli.rb
30
+ - lib/ios/common.rb
31
+ - lib/ios/decrypt.rb
32
+ - lib/junos/common.rb
33
+ - lib/junos/decrypt.rb
34
+ - lib/nxos/common.rb
35
+ - lib/nxos/decrypt.rb
36
+ - lib/router_crypt.rb
37
+ - rakefile
38
+ - router_crypt.gemspec
39
+ - spec/ios/decrypt_spec.rb
40
+ - spec/junos/common_spec.rb
41
+ - spec/junos/decrypt_spec.rb
42
+ - spec/nxos/decrypt_spec.rb
43
+ - spec/spec_helper.rb
44
+ homepage: http://github.com/ytti/router_crypt
45
+ licenses: []
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ segments:
57
+ - 0
58
+ hash: 322463051478397895
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - '>='
63
+ - !ruby/object:Gem::Version
64
+ version: 1.3.6
65
+ requirements: []
66
+ rubyforge_project: router_crypt
67
+ rubygems_version: 1.8.25
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Crypt library for JunOS/IOS/NX-OS passwords
71
+ test_files: []