router_crypt 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +17 -0
- data/README.md +36 -0
- data/bin/rtrcrypt +9 -0
- data/lib/cli/cli.rb +16 -0
- data/lib/ios/common.rb +3 -0
- data/lib/ios/decrypt.rb +15 -0
- data/lib/junos/common.rb +40 -0
- data/lib/junos/decrypt.rb +27 -0
- data/lib/nxos/common.rb +4 -0
- data/lib/nxos/decrypt.rb +15 -0
- data/lib/router_crypt.rb +10 -0
- data/rakefile +36 -0
- data/router_crypt.gemspec +15 -0
- data/spec/ios/decrypt_spec.rb +9 -0
- data/spec/junos/common_spec.rb +39 -0
- data/spec/junos/decrypt_spec.rb +9 -0
- data/spec/nxos/decrypt_spec.rb +9 -0
- data/spec/spec_helper.rb +7 -0
- metadata +71 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gems/*
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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
|
data/bin/rtrcrypt
ADDED
data/lib/cli/cli.rb
ADDED
@@ -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
|
data/lib/ios/common.rb
ADDED
data/lib/ios/decrypt.rb
ADDED
@@ -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
|
data/lib/junos/common.rb
ADDED
@@ -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
|
data/lib/nxos/common.rb
ADDED
data/lib/nxos/decrypt.rb
ADDED
@@ -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
|
data/lib/router_crypt.rb
ADDED
data/rakefile
ADDED
@@ -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,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
|
data/spec/spec_helper.rb
ADDED
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: []
|