router_crypt 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []