Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Commit

Permalink
Merge a12898f into 22a934c
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Claudius committed Jan 17, 2019
2 parents 22a934c + a12898f commit 3eb3bca
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 101 deletions.
60 changes: 0 additions & 60 deletions lib/ssh_scan/crypto.rb

This file was deleted.

59 changes: 59 additions & 0 deletions lib/ssh_scan/public_key.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require 'openssl'
require 'sshkey'
require 'base64'

module SSHScan
# All cryptography related methods.
module Crypto
# House methods helpful in analysing SSH public keys.
class PublicKey
def initialize(key_string)
@key_string = key_string
end

def valid?
SSHKey.valid_ssh_public_key?(@key_string)
end

def type
if @key_string.start_with?("ssh-rsa")
return "rsa"
elsif @key_string.start_with?("ssh-dss")
return "dsa"
else
return "unknown"
end
end

def length
SSHKey.ssh_public_key_bits(@key_string)
end

def fingerprint_md5
SSHKey.fingerprint(@key_string)
end

def fingerprint_sha1
SSHKey.sha1_fingerprint(@key_string)
end

def fingerprint_sha256
SSHKey.sha256_fingerprint(@key_string)
end

def to_hash
{
self.type => {
"raw" => @key_string,
"length" => self.length,
"fingerprints" => {
"md5" => self.fingerprint_md5,
"sha1" => self.fingerprint_sha1,
"sha256" => self.fingerprint_sha256
}
}
}
end
end
end
end
14 changes: 7 additions & 7 deletions lib/ssh_scan/result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module SSHScan
class Result
def initialize()
@version = SSHScan::VERSION
@fingerprints = nil
@keys = nil
@duplicate_host_key_ips = Set.new()
@compliance = {}
end
Expand Down Expand Up @@ -157,12 +157,12 @@ def auth_methods=(auth_methods)
@auth_methods = auth_methods
end

def fingerprints=(fingerprints)
@fingerprints = fingerprints
def keys=(keys)
@keys = keys
end

def fingerprints
@fingerprints
def keys
@keys
end

def duplicate_host_key_ips=(duplicate_host_key_ips)
Expand Down Expand Up @@ -249,8 +249,8 @@ def to_hash
"languages_client_to_server" => self.languages_client_to_server,
"languages_server_to_client" => self.languages_server_to_client,
"auth_methods" => self.auth_methods,
"fingerprints" => self.fingerprints,
"duplicate_host_key_ips" => self.duplicate_host_key_ips,
"keys" => self.keys,
"duplicate_host_key_ips" => self.duplicate_host_key_ips.uniq,
"compliance" => @compliance,
"start_time" => self.start_time,
"end_time" => self.end_time,
Expand Down
49 changes: 15 additions & 34 deletions lib/ssh_scan/scan_engine.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require 'socket'
require 'ssh_scan/client'
require 'ssh_scan/crypto'
require 'ssh_scan/public_key'
require 'ssh_scan/fingerprint_database'
require 'ssh_scan/subprocess'
require 'net/ssh'
Expand Down Expand Up @@ -119,7 +119,7 @@ def scan_target(socket, opts)
end

# Figure out what rsa or dsa fingerprints exist
fingerprints = {}
keys = {}

output = ""

Expand All @@ -136,31 +136,17 @@ def scan_target(socket, opts)

for i in 0..host_keys_len
if host_keys[i].eql? "ssh-dss"
pkey = SSHScan::Crypto::PublicKey.new(host_keys[i + 1])
fingerprints.merge!({
"dsa" => {
"known_bad" => pkey.bad_key?.to_s,
"md5" => pkey.fingerprint_md5,
"sha1" => pkey.fingerprint_sha1,
"sha256" => pkey.fingerprint_sha256,
}
})
key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" "))
keys.merge!(key.to_hash)
end

if host_keys[i].eql? "ssh-rsa"
pkey = SSHScan::Crypto::PublicKey.new(host_keys[i + 1])
fingerprints.merge!({
"rsa" => {
"known_bad" => pkey.bad_key?.to_s,
"md5" => pkey.fingerprint_md5,
"sha1" => pkey.fingerprint_sha1,
"sha256" => pkey.fingerprint_sha256,
}
})
key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" "))
keys.merge!(key.to_hash)
end
end

result.fingerprints = fingerprints
result.keys = keys
result.set_end_time

return result
Expand Down Expand Up @@ -200,33 +186,28 @@ def scan(opts)
results.each do |result|
fingerprint_db.clear_fingerprints(result.ip)

if result.fingerprints
result.fingerprints.values.each do |host_key_algo|
host_key_algo.each do |fingerprint|
key, value = fingerprint
next if key == "known_bad"
fingerprint_db.add_fingerprint(value, result.ip)
if result.keys
result.keys.values.each do |host_key_algo|
host_key_algo['fingerprints'].values.each do |fingerprint|
fingerprint_db.add_fingerprint(fingerprint, result.ip)
end
end
end
end

# Decorate all the results with duplicate keys
results.each do |result|
if result.fingerprints
if result.keys
ip = result.ip
result.duplicate_host_key_ips = []
result.fingerprints.values.each do |host_key_algo|
host_key_algo.each do |fingerprint|
key, value = fingerprint
next if key == "known_bad"
fingerprint_db.find_fingerprints(value).each do |other_ip|
result.keys.values.each do |host_key_algo|
host_key_algo["fingerprints"].values.each do |fingerprint|
fingerprint_db.find_fingerprints(fingerprint).each do |other_ip|
next if ip == other_ip
result.duplicate_host_key_ips << other_ip
end
end
end
result.duplicate_host_key_ips
end
end

Expand Down
78 changes: 78 additions & 0 deletions spec/public_key_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require 'spec_helper'
require 'rspec'
require 'ssh_scan/public_key'

describe SSHScan::Crypto::PublicKey do
context "when parsing an RSA key string" do
it "should parse it and have the right values for each attribute" do
key_string = "ssh-rsa " +
"AAAAB3NzaC1yc2EAAAADAQABAAABAQCl/BNLUxR49+3AKqhf6sWKr" +
"h8XXzqXV00bEPFtcJFWxyRqC5pPWo9zRRiS2jitIcqljIQVohEEZH" +
"t48vZaA1hniVfe/FmrFzuCOuQOIP2fuRgLSNHu+lWVScsHoX/MuYX" +
"EIxj6aW7UpFn4lD01mvPtazXFO/tJ+LRs49YBP7UvL1smIS2xoyuH" +
"7kZDN17QG08YwbIB2fApMl8rXH+2Rpj5hlv+7rcZ1dqCGtmXmvsv8" +
"fKGYd7BxRy0s/d7EY4e/DeDxA1qTNV9BrBTNn6jAKIedTE5s4GNRb" +
"N/Q20mP2qmw70PiTGROw6xp9SBFA7N9hjjOT7iutK/pa7y1joXKjeJ"
key = SSHScan::Crypto::PublicKey.new(key_string)
expect(key).to be_kind_of SSHScan::Crypto::PublicKey
expect(key.valid?).to be true
expect(key.type).to eq("rsa")
expect(key.length).to be 2048
expect(key.fingerprint_md5).to eq("fc:c5:5b:0d:f0:c6:fd:fe:80:18:62:2c:05:38:20:8a")
expect(key.fingerprint_sha1).to eq("e1:3c:71:49:80:37:87:32:b5:0c:e3:86:41:ef:2e:2a:2f:14:e3:58")
expect(key.fingerprint_sha256).to eq("aH0wN2cs6x5Ktf9PvIzoQeFVqDBC4I484wq6vNv9XFA=")
expect(key.to_hash).to eq(
{
"rsa" => {
"fingerprints" => {
"md5"=>"fc:c5:5b:0d:f0:c6:fd:fe:80:18:62:2c:05:38:20:8a",
"sha1"=>"e1:3c:71:49:80:37:87:32:b5:0c:e3:86:41:ef:2e:2a:2f:14:e3:58",
"sha256"=>"aH0wN2cs6x5Ktf9PvIzoQeFVqDBC4I484wq6vNv9XFA="
},
"length" => 2048,
"raw" => "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl/BNLUxR49+3AKqhf6sWKrh8XXzqXV00bEPFtcJFWxyRqC5pPWo9zRRiS2jitIcqljIQVohEEZHt48vZaA1hniVfe/FmrFzuCOuQOIP2fuRgLSNHu+lWVScsHoX/MuYXEIxj6aW7UpFn4lD01mvPtazXFO/tJ+LRs49YBP7UvL1smIS2xoyuH7kZDN17QG08YwbIB2fApMl8rXH+2Rpj5hlv+7rcZ1dqCGtmXmvsv8fKGYd7BxRy0s/d7EY4e/DeDxA1qTNV9BrBTNn6jAKIedTE5s4GNRbN/Q20mP2qmw70PiTGROw6xp9SBFA7N9hjjOT7iutK/pa7y1joXKjeJ",
}
}
)
end
end

context "when parsing an DSA key string" do
it "should parse it and have the right values for each attribute" do
key_string = "ssh-dss " +
"AAAAB3NzaC1kc3MAAACBAOXOC6kuB7xDMgHS79KFQITNeAT9tMKd2oK1" +
"c6bQEHRgTSMP3sWZ1cntWVFKl5u6MEuEBBT9PZKWsy7vRE525Wwt+NbR" +
"IBso3vYFF1MtxZKpAsF+gbGI7y+aZcIceXrHkkY2bz3oGb9I9MZ2DSu2" +
"9crW11YHCmuOJ2FJiDcx7dV9AAAAFQC+Ws9e0KJaAsN8cj75DbTQumrd" +
"JQAAAIBjn5EA5JvQg7xu8TRcNmZWhuyBLoOZczU6nk2h4i+x4pbpVMVr" +
"Ch5Lr8wsH60w7IW4yKg6JvPlzmQW0ZRZAwnU9sC3YO64H1RFQg8tnmRr" +
"w0I9oi6wKPEe5rLgbdr9jYHePs9tiV+ZFfUKmXh0s7srr/dwmX/gHCPI" +
"whLEVa+dLQAAAIEAn/+dSyf6KXdfKNyx9MYc1l2/2YUhVuxClF26PNQX" +
"0CZhcSoDyUXU/eAqaS7S6EYqtM/8FK1OZY1tzM5Nm4GWY2LLF22Q2YkK" +
"ItkhfS3GaD5JeuTQ+HK0F+wQjmpqt2pUulVQXQAjvE1qoRFQ4/yeVrvh" +
"VqCzFICnariQP7tMYEo="
key = SSHScan::Crypto::PublicKey.new(key_string)
expect(key).to be_kind_of SSHScan::Crypto::PublicKey
expect(key.valid?).to be true
expect(key.type).to eq("dsa")
expect(key.length).to be 1024
expect(key.fingerprint_md5).to eq("6b:5f:8d:57:be:2e:55:7f:e3:d7:15:d1:66:17:d8:8c")
expect(key.fingerprint_sha1).to eq("49:84:7f:d7:9d:84:2a:20:61:72:10:3f:2c:b1:16:9b:12:5b:e7:07")
expect(key.fingerprint_sha256).to eq("sWZzgrGxzs/aMmcU2w6FyET/Iihd6HL1qNyDZnO0NDw=")
expect(key.to_hash).to eq(
{
"dsa" => {
"fingerprints" => {
"md5"=>"6b:5f:8d:57:be:2e:55:7f:e3:d7:15:d1:66:17:d8:8c",
"sha1"=>"49:84:7f:d7:9d:84:2a:20:61:72:10:3f:2c:b1:16:9b:12:5b:e7:07",
"sha256"=>"sWZzgrGxzs/aMmcU2w6FyET/Iihd6HL1qNyDZnO0NDw="
},
"length" => 1024,
"raw" => "ssh-dss AAAAB3NzaC1kc3MAAACBAOXOC6kuB7xDMgHS79KFQITNeAT9tMKd2oK1c6bQEHRgTSMP3sWZ1cntWVFKl5u6MEuEBBT9PZKWsy7vRE525Wwt+NbRIBso3vYFF1MtxZKpAsF+gbGI7y+aZcIceXrHkkY2bz3oGb9I9MZ2DSu29crW11YHCmuOJ2FJiDcx7dV9AAAAFQC+Ws9e0KJaAsN8cj75DbTQumrdJQAAAIBjn5EA5JvQg7xu8TRcNmZWhuyBLoOZczU6nk2h4i+x4pbpVMVrCh5Lr8wsH60w7IW4yKg6JvPlzmQW0ZRZAwnU9sC3YO64H1RFQg8tnmRrw0I9oi6wKPEe5rLgbdr9jYHePs9tiV+ZFfUKmXh0s7srr/dwmX/gHCPIwhLEVa+dLQAAAIEAn/+dSyf6KXdfKNyx9MYc1l2/2YUhVuxClF26PNQX0CZhcSoDyUXU/eAqaS7S6EYqtM/8FK1OZY1tzM5Nm4GWY2LLF22Q2YkKItkhfS3GaD5JeuTQ+HK0F+wQjmpqt2pUulVQXQAjvE1qoRFQ4/yeVrvhVqCzFICnariQP7tMYEo=",
}
}
)
end
end

end
2 changes: 2 additions & 0 deletions spec/ssh_scan/result_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'spec_helper'
require 'rspec'
require 'ssh_scan/version'
require 'ssh_scan/result'

describe SSHScan::Result do
Expand Down Expand Up @@ -32,6 +33,7 @@
expect(result.start_time).to be_nil
expect(result.end_time).to be_nil
expect(result.scan_duration).to be_nil
expect(result.keys).to be_nil
end

context "when setting IP" do
Expand Down

0 comments on commit 3eb3bca

Please sign in to comment.