diff --git a/lib/ssh_scan/public_key.rb b/lib/ssh_scan/public_key.rb index ba71a481..9f86cbf3 100644 --- a/lib/ssh_scan/public_key.rb +++ b/lib/ssh_scan/public_key.rb @@ -20,6 +20,10 @@ def type return "rsa" elsif @key_string.start_with?("ssh-dss") return "dsa" + elsif @key_string.start_with?("ecdsa-sha2-nistp256") + return "ecdsa-sha2-nistp256" + elsif @key_string.start_with?("ssh-ed25519") + return "ed25519" else return "unknown" end diff --git a/lib/ssh_scan/scan_engine.rb b/lib/ssh_scan/scan_engine.rb index 4a0b763e..ee925421 100644 --- a/lib/ssh_scan/scan_engine.rb +++ b/lib/ssh_scan/scan_engine.rb @@ -123,7 +123,7 @@ def scan_target(socket, opts) output = "" - cmd = ['ssh-keyscan', '-t', 'rsa,dsa', '-p', port.to_s, target].join(" ") + cmd = ['ssh-keyscan', '-t', 'rsa,dsa,ecdsa,ed25519', '-p', port.to_s, target].join(" ") Utils::Subprocess.new(cmd) do |stdout, stderr, thread| if stdout @@ -144,6 +144,16 @@ def scan_target(socket, opts) key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" ")) keys.merge!(key.to_hash) end + + if host_keys[i].eql? "ecdsa-sha2-nistp256" + 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-ed25519" + key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" ")) + keys.merge!(key.to_hash) + end end result.keys = keys diff --git a/spec/public_key_spec.rb b/spec/public_key_spec.rb index 88b14492..b9e2ebc0 100644 --- a/spec/public_key_spec.rb +++ b/spec/public_key_spec.rb @@ -75,4 +75,61 @@ end end + context "when parsing an ecdsa key string" do + it "should parse it and have the right values for each attribute" do + key_string = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyN" + + "TYAAAAIbmlzdHAyNTYAAABBBC4gXA5naQtjcKu90NJ7A4jQ1U" + + "gxYGdnndJyr4PSZJ59qJUzkoH3VgdTlseXbIZHwO4k2gNcFpa" + + "Mq5gqVRobAwU=" + 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("ecdsa-sha2-nistp256") + expect(key.length).to be 520 + expect(key.fingerprint_md5).to eq("be:04:32:74:c6:63:fa:24:c3:c6:78:c2:cd:d2:3e:f4") + expect(key.fingerprint_sha1).to eq("00:67:e3:4d:78:2f:65:94:87:bf:54:5a:1e:92:af:67:0b:8d:b5:2c") + expect(key.fingerprint_sha256).to eq("EZe8ZoSwAzDOLR45H2PZ1aGGfnt59ZLrL5bwnjQwTUI=") + expect(key.to_hash).to eq( + { + "ecdsa-sha2-nistp256" => { + "fingerprints" => { + "md5"=>"be:04:32:74:c6:63:fa:24:c3:c6:78:c2:cd:d2:3e:f4", + "sha1"=>"00:67:e3:4d:78:2f:65:94:87:bf:54:5a:1e:92:af:67:0b:8d:b5:2c", + "sha256"=>"EZe8ZoSwAzDOLR45H2PZ1aGGfnt59ZLrL5bwnjQwTUI=" + }, + "length" => 520, + "raw" => "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC4gXA5naQtjcKu90NJ7A4jQ1UgxYGdnndJyr4PSZJ59qJUzkoH3VgdTlseXbIZHwO4k2gNcFpaMq5gqVRobAwU=", + } + } + ) + end + end + + context "when parsing an ed25519 key string" do + it "should parse it and have the right values for each attribute" do + key_string = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINO+ybidO9DGOb1dDwyVvGcrCD/wILFWTYtWUQZVxXwH" + 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("ed25519") + expect(key.length).to be 256 + expect(key.fingerprint_md5).to eq("0f:db:50:54:15:22:b3:6f:31:7c:ee:22:23:77:bc:77") + expect(key.fingerprint_sha1).to eq("32:d1:e8:50:ae:1c:cb:11:c5:09:fa:02:6e:f4:e8:dc:11:11:4c:48") + expect(key.fingerprint_sha256).to eq("p+P78wR61KZ4UvQZpr84EqslnRkhZ7txT1bN8vA/oHU=") + expect(key.to_hash).to eq( + { + "ed25519" => { + "fingerprints" => { + "md5"=>"0f:db:50:54:15:22:b3:6f:31:7c:ee:22:23:77:bc:77", + "sha1"=>"32:d1:e8:50:ae:1c:cb:11:c5:09:fa:02:6e:f4:e8:dc:11:11:4c:48", + "sha256"=>"p+P78wR61KZ4UvQZpr84EqslnRkhZ7txT1bN8vA/oHU=" + }, + "length" => 256, + "raw" => "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINO+ybidO9DGOb1dDwyVvGcrCD/wILFWTYtWUQZVxXwH", + } + } + ) + end + end + end \ No newline at end of file