From 169641c514f6e090cf694f679b0e9af492a22192 Mon Sep 17 00:00:00 2001 From: Patrick Kelley Date: Wed, 7 May 2025 14:12:22 -0400 Subject: [PATCH] Initial --- CODEOWNERS | 2 + CONTRIBUTING-ARCHIVED.md | 5 + LICENSE.txt | 12 + README.md | 78 ++++ logo.png | Bin 0 -> 5262 bytes packet_sequence.png | Bin 0 -> 118861 bytes python/.DS_Store | Bin 0 -> 6148 bytes python/Pipfile | 19 + python/Pipfile.lock | 126 ++++++ python/README.md | 158 +++++++ python/docker/Dockerfile | 27 ++ python/hassh.py | 428 ++++++++++++++++++ python/hasshGen/README.md | 82 ++++ python/hasshGen/dockerfiles/Dockerfile.alpine | 10 + python/hasshGen/dockerfiles/Dockerfile.centos | 11 + python/hasshGen/dockerfiles/Dockerfile.debian | 14 + python/hasshGen/dockerfiles/Dockerfile.python | 27 ++ python/hasshGen/hassh_fingerprints.csv | 50 ++ python/hasshGen/hassh_fingerprints.json | 49 ++ python/hasshGen/hasshgen.py | 192 ++++++++ python/hasshGen/paramiko_conn.py | 17 + python/hasshGen/sshClient_list | 51 +++ zeek/README.md | 94 ++++ zeek/__load__.zeek | 1 + zeek/hassh.zeek | 144 ++++++ zkg.meta | 5 + 26 files changed, 1602 insertions(+) create mode 100644 CODEOWNERS create mode 100644 CONTRIBUTING-ARCHIVED.md create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 logo.png create mode 100644 packet_sequence.png create mode 100644 python/.DS_Store create mode 100644 python/Pipfile create mode 100644 python/Pipfile.lock create mode 100644 python/README.md create mode 100644 python/docker/Dockerfile create mode 100644 python/hassh.py create mode 100644 python/hasshGen/README.md create mode 100644 python/hasshGen/dockerfiles/Dockerfile.alpine create mode 100644 python/hasshGen/dockerfiles/Dockerfile.centos create mode 100644 python/hasshGen/dockerfiles/Dockerfile.debian create mode 100644 python/hasshGen/dockerfiles/Dockerfile.python create mode 100644 python/hasshGen/hassh_fingerprints.csv create mode 100644 python/hasshGen/hassh_fingerprints.json create mode 100644 python/hasshGen/hasshgen.py create mode 100644 python/hasshGen/paramiko_conn.py create mode 100644 python/hasshGen/sshClient_list create mode 100644 zeek/README.md create mode 100644 zeek/__load__.zeek create mode 100644 zeek/hassh.zeek create mode 100644 zkg.meta diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..522fa4a --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,2 @@ +# Comment line immediately above ownership line is reserved for related gus information. Please be careful while editing. +#ECCN:Open Source diff --git a/CONTRIBUTING-ARCHIVED.md b/CONTRIBUTING-ARCHIVED.md new file mode 100644 index 0000000..4db2c29 --- /dev/null +++ b/CONTRIBUTING-ARCHIVED.md @@ -0,0 +1,5 @@ +# ARCHIVED + +This project is `Archived` and is no longer actively maintained; +We are not accepting contributions or Pull Requests. + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..90ac7cb --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,12 @@ +Copyright (c) 2018, Salesforce.com, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..eb7f8e0 --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# "HASSH" - a Profiling Method for SSH Clients and Servers. + +

+ + +

+ + +"HASSH" is a network fingerprinting standard which can be used to identify specific Client and Server SSH implementations. The fingerprints can be easily stored, searched and shared in the form of an MD5 fingerprint. + +HASSH was invented at Salesforce in 2018. However, the project is no longer being actively maintained by Salesforce. Its original creator, Ben Reardon maintains the active fork at [Corelight](https://github.com/corelight/hassh) + +[![License: BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) +## What can HASSH help with: +- Use in highly controlled, well understood environments, where any fingerprints outside of a known good set are alertable. +- It is possible to detect, control and investigate brute force or Cred Stuffing password attempts at a higher level of granularity than IP Source - which may be impacted by NAT or botnet-like behaviour. The hassh will be a feature of the specific Client software implementation being used, even if the IP is NATed such that it is shared by many other SSH clients. +- Detect covert exfiltration of data within the components of the Client algorithm sets. In this case, a specially coded SSH Client can send data outbound from a trusted to a less trusted environment within a series of SSH_MSG_KEXINIT packets. In a scenario similar to the more known exfiltration via DNS, data could be sent as a series of attempted, but incomplete and unlogged connections to an SSH server controlled by bad actors who can then record, decode and reconstitute these pieces of data into their original form. Until now such attempts - much less the contents of the clear text packets - are not logged even by mature packet analyzers or on end point systems. Detection of this style of exfiltration can now be performed easily by using anomaly detection or alerting on SSH Clients with multiple different hassh +- Use in conjunction with other contextual indicators, for example detect Network discovery and Lateral movement attempts by unusual hassh such as those used by Paramiko, Powershell, Ruby, Meterpreter, Empire. +- Share malicious hassh as Indicators of Compromise. +- Create an additional level of Client application control, for example one could block all Clients from connecting to an SSH server that are outside of an approved known set of hassh values. +- Contribute to Non Repudiation in a Forensic context - at a higher level of abstraction than IPSource - which may be impacted by NAT, or where multiple IP Sources are used. +- Detect Deceptive Applications. Eg a hasshServer value known to belong to the Cowrie/Kippo SSH honeypot server installation, which is purporting to be a common OpenSSH server in the Server String. +- Detect devices having a hassh known to belong to IOT embedded systems. Examples may include cameras, mics, keyloggers, wiretaps that could be easily be hidden from view and communicating quietly over encrypted channels back to a control server. + +## How does HASSH work: +"hassh" and "hasshServer" are MD5 hashes constructed from a specific set of algorithms that are supported by various SSH Client and Server Applications. These algorithms are exchanged after the initial TCP three-way handshake as clear-text packets known as "SSH_MSG_KEXINIT" messages, and are an integral part of the setup of the final encrypted SSH channel. +The existence and ordering of these algorithms is unique enough such that it can be used as a fingerprint to help identify the underlying Client and Server application or unique implementation, regardless of higher level ostensible identifiers such as "Client" or "Server" strings. +

+ +

+ +## Example 1: Client Fingerprinting - the "hassh" +For the "Cyberduck" SFTP client (specifically SSH-2.0-Cyberduck/6.7.1.28683 (Mac OS X/10.13.6) (x86_64)" , the set of supported algorithms is as follows : + +|Function|Algorithms seen in SSH_MSG_KEXINIT packets| +| ------------- | ------------- | +|Key Exchange methods|```curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group14-sha256,diffie-hellman-group15-sha512,diffie-hellman-group16-sha512,diffie-hellman-group17-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256@ssh.com,diffie-hellman-group15-sha256,diffie-hellman-group15-sha256@ssh.com,diffie-hellman-group15-sha384@ssh.com,diffie-hellman-group16-sha256,diffie-hellman-group16-sha384@ssh.com,diffie-hellman-group16-sha512@ssh.com,diffie-hellman-group18-sha512@ssh.com```| +|Encryption| ```aes128-cbc,aes128-ctr,aes192-cbc,aes192-ctr,aes256-cbc,aes256-ctr,blowfish-cbc,blowfish-ctr,cast128-cbc,cast128-ctr,idea-cbc,idea-ctr,serpent128-cbc,serpent128-ctr,serpent192-cbc,serpent192-ctr,serpent256-cbc,serpent256-ctr,3des-cbc,3des-ctr,twofish128-cbc,twofish128-ctr,twofish192-cbc,twofish192-ctr,twofish256-cbc,twofish256-ctr,twofish-cbc,arcfour,arcfour128,arcfour256```| +|Message Authentication|```hmac-sha1,hmac-sha1-96,hmac-md5,hmac-md5-96,hmac-sha2-256,hmac-sha2-512```| +|Compression|```zlib@openssh.com,zlib,none```| + +Concatenating these algorithms together with a delimiter of ";" gives the hasshAlgorithms, which is useful for detailed analysis. +```curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group14-sha256,diffie-hellman-group15-sha512,diffie-hellman-group16-sha512,diffie-hellman-group17-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256@ssh.com,diffie-hellman-group15-sha256,diffie-hellman-group15-sha256@ssh.com,diffie-hellman-group15-sha384@ssh.com,diffie-hellman-group16-sha256,diffie-hellman-group16-sha384@ssh.com,diffie-hellman-group16-sha512@ssh.com,diffie-hellman-group18-sha512@ssh.com;aes128-cbc,aes128-ctr,aes192-cbc,aes192-ctr,aes256-cbc,aes256-ctr,blowfish-cbc,blowfish-ctr,cast128-cbc,cast128-ctr,idea-cbc,idea-ctr,serpent128-cbc,serpent128-ctr,serpent192-cbc,serpent192-ctr,serpent256-cbc,serpent256-ctr,3des-cbc,3des-ctr,twofish128-cbc,twofish128-ctr,twofish192-cbc,twofish192-ctr,twofish256-cbc,twofish256-ctr,twofish-cbc,arcfour,arcfour128,arcfour256;hmac-sha1,hmac-sha1-96,hmac-md5,hmac-md5-96,hmac-sha2-256,hmac-sha2-512;zlib@openssh.com,zlib,none``` + +Finally the hassh is simply the MD5 of hasshAlgorithms, and is used for storage, searching and sharing. Some examples follow: + +```de30354b88bae4c2810426614e1b6976``` Powershell Renci.SshNet.SshClient.0.0.1 (used by Empire exploit modules) +```fafc45381bfde997b6305c4e1600f1bf``` Ruby/Net::SSH_5.0.2 x86_64-linux (used by Metasploit exploit modules) +```b5752e36ba6c5979a575e43178908adf``` Python Paramiko_2.4.1 (used by Metasploit exploit modules) +```16f898dd8ed8279e1055350b4e20666c``` Dropbear_2012.55 (used in IOT embedded systems) +```8a8ae540028bf433cd68356c1b9e8d5b``` CyberDuck Version 6.7.1 (28683) +```06046964c022c6407d15a27b12a6a4fb``` OpenSSH_7.7p1 Ubuntu-4 + +## Example 2: Server Fingerprinting - the "hasshServer" +For a standard SSH-2.0-OpenSSH_5.3 SSH server, the set of supported algorithms is as follows : + +|Function|Algorithms seen in SSH_MSG_KEXINIT packets| +| ------------- | ------------- | +|Key Exchange methods| ```diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1```| +|Encryption| ```aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se```| +|Message Authentication|```hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96```| +|Compression|```none,zlib@openssh.com```| + +Concatenating these algorithms together with a delimiter of ";" gives the hasshServerAlgorithms, which is useful for detailed analysis. +```diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com``` + +Finally the hasshServer is simply the MD5 of hasshServerAlgorithms, some examples follow: +```c1c596caaeb93c566b8ecf3cae9b5a9e``` SSH-2.0-dropbear_2016.74 +```d93f46d063c4382b6232a4d77db532b2``` SSH-2.0-dropbear_2016.72 +```2dd9a9b3dbebfaeec8b8aabd689e75d2``` SSH-2.0-AWSCodeCommit +```696e7f84ac571fdf8fa5073e64ee2dc8``` SSH-2.0-FTP + +## References: +- [RFC4253 The Secure Shell (SSH) Transport Layer Protocol](https://www.ietf.org/rfc/rfc4253.txt) +- [Salesforce Engineering blog](https://engineering.salesforce.com/open-sourcing-hassh-abed3ae5044c) + +## Credits: +hassh and hasshServer were conceived and developed by [Ben Reardon](mailto:breardon@salesforce.com) ([@benreardon](https://twitter.com/@benreardon)) within the Detection Cloud Team at Salesforce, with inspiration and contributions from [Adel Karimi](mailto:akarimishiraz@salesforce.com) (@0x4d31) and the [JA3 crew](https://github.com/salesforce/ja3/) crew:[John B. Althouse](mailto:jalthouse@salesforce.com) , [Jeff Atkinson](mailto:jatkinson@salesforce.com) and [Josh Atkins](mailto:j.atkins@salesforce.com) diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f9aa438a3618f0f07a35574b4046020c0335ddf3 GIT binary patch literal 5262 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 literal 0 HcmV?d00001 diff --git a/packet_sequence.png b/packet_sequence.png new file mode 100644 index 0000000000000000000000000000000000000000..57fc33abce39adc45cccb8f7fa3d16995b7d5741 GIT binary patch literal 118861 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 z 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 literal 0 HcmV?d00001 diff --git a/python/.DS_Store b/python/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..31c864efc04f30be3de0941d9292131a51802db7 GIT binary patch literal 6148 zcmeHKu};H44E2Qw1+jEwygxwwgHQ$W0sVoJ1`&ydR8-xwFfi~f`~Wk5!oteL#o2;fw zTH&hc0=e7{_L6&l+UB#F&*O8SPc&E4e&zI=-ypAK#(9|-1IBm4`s{)c8c=pKqE&0U<$Jc`tmOa^lSj;0Xs!lAWlPp8tTFk!)Z9|KKSJU zJ4FpACo5x~u(As$6ep|0?!}#4u4t_>U*Z=dM&;P?9yE6uifxTkDrNy+E z;E_UYjUJ9`t%uH_EbP}Q_95s= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.11.0" + }, + "pyshark": { + "hashes": [ + "sha256:8965e8e2da50a7fe97f80b0b8db676a0bfc131aa8f4d6017e6b0cedc46b11288" + ], + "index": "pypi", + "version": "==0.4.1" + } + }, + "develop": {} +} diff --git a/python/README.md b/python/README.md new file mode 100644 index 0000000..57e7235 --- /dev/null +++ b/python/README.md @@ -0,0 +1,158 @@ +# HASSH.py + +[![License: BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) + +HASSH is a method for creating SSH Client and Server fingerprints. This python script generates HASSH fingerprints from input PCAP files and live network traffic. + +You can use [hasshGen.py](hasshGen/) to automate building docker images with different SSH clients/versions for generating HASSH fingerprints. As a demonstration we created a list ([sshClient_list](hasshGen/sshClient_list)) containing 49 different version of OpenSSH, Python’s paramiko and Dropbear SSH clients and generated a database of HASSH fingerprints in [JSON](hasshGen/hassh_fingerprints.json) and [CSV](hasshGen/hassh_fingerprints.csv) formats. + +## Getting Started +1. Install Tshark. + > `apt-get install tshark` on Debian/Ubuntu or `yum install wireshark` on Centos 7 + + +2. Install Pipenv: + > `pip3 install pipenv` + +3. Install dependencies: + > `pipenv install` + +4. Test: + +To activate the virtualenv, run pipenv shell: +``` +$ pipenv shell +(python-ZnElGiuE) bash-3.2$ python3 hassh.py -h +``` + +Alternatively, run a command inside the virtualenv with pipenv run: + +``` +$ pipenv run python3 hassh.py -h +``` + +Output: + +``` +usage: hassh.py [-h] [-r READ_FILE] [-d READ_DIRECTORY] [-i INTERFACE] + [-fp {client,server}] [-da DECODE_AS] [-f BPF_FILTER] + [-l {json,csv}] [-o OUTPUT_FILE] [-w WRITE_PCAP] [-p] + +A python script for extracting HASSH fingerprints + +optional arguments: + -h, --help show this help message and exit + -r READ_FILE, --read_file READ_FILE + pcap file to process + -d READ_DIRECTORY, --read_directory READ_DIRECTORY + directory of pcap files to process + -i INTERFACE, --interface INTERFACE + listen on interface + -fp {client,server}, --fingerprint {client,server} + client or server fingerprint. Default: all + -da DECODE_AS, --decode_as DECODE_AS + a dictionary of {decode_criterion_string: + decode_as_protocol} that are used to tell tshark to + decode protocols in situations it wouldn't usually. + Default: {'tcp.port==2222': 'ssh'}. + -f BPF_FILTER, --bpf_filter BPF_FILTER + BPF capture filter to use (for live capture only). + Default: 'tcp port 22 or tcp port 2222' + -l {json,csv}, --log_format {json,csv} + specify the output log format (json/csv) + -o OUTPUT_FILE, --output_file OUTPUT_FILE + specify the output log file. Default: hassh.log + -w WRITE_PCAP, --write_pcap WRITE_PCAP + save the live captured packets to this file + -p, --print_output print the output +``` + +## Usage + * Live network traffic capture: + ``` + $ python3 hassh.py -i eth0 -l json -o hassh.json --print + ``` + +Output: +``` +[+] Server SSH_MSG_KEXINIT detected + [ 192.1.2.3:22 -> 10.1.2.3:52068 ] + [-] Identification String: SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4 + [-] hasshServer: d43d91bc39d5aaed819ad9f6b57b7348 + [-] hasshServer Algorithms: curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com +[+] Client SSH_MSG_KEXINIT detected + [ 10.1.2.3:52068 -> 192.1.2.3:22 ] + [-] Identification String: SSH-2.0-OpenSSH_7.6 + [-] hassh: 06046964c022c6407d15a27b12a6a4fb + [-] hassh Algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib +``` + +JSON Output: + ```javascript +{ + "timestamp": "2018-09-04T18:57:03.644663", + "sourceIp": "10.1.2.3", + "destinationIp": "192.1.2.3", + "sourcePort": "52068", + "destinationPort": "22", + "client": "SSH-2.0-OpenSSH_7.6", + "hassh": "06046964c022c6407d15a27b12a6a4fb", + "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", + "hasshVersion": "1.0", + "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", + "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", + "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", + "ccacts": "none,zlib@openssh.com,zlib", + "clcts": "[Empty]", + "clstc": "[Empty]", + "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", + "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", + "ccastc": "none,zlib@openssh.com,zlib", + "cshka": "ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa" +} +{ + "timestamp": "2018-09-04T18:57:04.534235", + "eventType": "retransmission", + "eventMessage": "This packet is a (suspected) retransmission", + "sourceIp": "10.1.2.3", + "destinationIp": "192.1.2.3", + "sourcePort": "52068", + "destinationPort": "22" +} +``` + + * Reading from an input PCAP file (```-r pcapfile.pcap```) or a directory of PCAP files (```-d pcap_dir/```): + + ``` + $ python3 hassh.py -r traffic.pcap -l csv -o hassh.csv --print + ``` + +CSV Output: +``` +timestamp,sourceIp,destinationIp,sourcePort,destinationPort,hasshType,identificationString,hassh,hasshVersion,hasshAlgorithms,kexAlgs,encAlgs,macAlgs,cmpAlgs +2018-09-04T18:57:03.642572,192.1.2.3,10.1.2.3,22,52068,server,"SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4",d43d91bc39d5aaed819ad9f6b57b7348,1.0,"curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1","chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com","umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1","none,zlib@openssh.com" +2018-09-04T18:57:03.644663,10.1.2.3,192.1.2.3,52068,22,client,"SSH-2.0-OpenSSH_7.6",06046964c022c6407d15a27b12a6a4fb,1.0,"curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c","chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com","umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1","none,zlib@openssh.com,zlib" +``` + +## Docker + +A dockerized version of hassh.py can be used to extract HASSH fingerprints from input PCAP files and live network traffic. + +Build the docker image using Dockerfile: + ``` + $ docker build -t hassh:latest . + ``` + + * Reading from input PCAP files: + +You can mount your host ~/pcap dir to copy pcap files to the container and also keep the logs on your host: + ``` + $ docker run -v ~/pcap:/tmp/ -it hassh:latest -d /tmp/ -l json -o /tmp/log.json + ``` + + * Live network traffic capture: + ``` + $ docker run --net=host -it hassh:latest -i any --print + ``` + +Note: According to Docker's [docs](https://docs.docker.com/network/host/), the host networking driver only works on Linux hosts, and is not supported on Docker for Mac, Docker for Windows, or Docker EE for Windows Server. diff --git a/python/docker/Dockerfile b/python/docker/Dockerfile new file mode 100644 index 0000000..d82a17d --- /dev/null +++ b/python/docker/Dockerfile @@ -0,0 +1,27 @@ +# Copyright (c) 2018, salesforce.com, inc. +# All rights reserved. +# Licensed under the BSD 3-Clause license. +# For full license text, see the LICENSE file in the repo root +# or https://opensource.org/licenses/BSD-3-Clause +# +# A dockerized version of hassh.py can be used to extract HASSH fingerprints from input PCAP files and live network traffic. +# +# Build the docker image using Dockerfile: +# $ docker build -t hassh:latest . +# - Reading from input PCAP files: +# You can mount your host ~/pcap dir to copy pcap files to the container and also keep the logs on your host: +# $ docker run -v ~/pcap:/tmp/ -it hassh:latest -d /tmp/ -l json -o /tmp/log.json +# - Live network traffic capture: +# $ docker run --net=host -it hassh:latest -i any --print +# Note: According to Docker's docs, the host networking driver only works on Linux hosts, and is not supported on Docker for Mac, Docker for Windows, or Docker EE for Windows Server. + +FROM alpine:latest +MAINTAINER Adel Karimi (@0x4d31) +ENV DEBIAN_FRONTEND noninteractive +RUN apk --no-cache add python3 gcc \ + py3-pip py3-lxml tshark \ + && pip3 install pyshark +WORKDIR /opt/hassh +ADD https://raw.githubusercontent.com/salesforce/hassh/master/python/hassh.py . +ENTRYPOINT ["python3","hassh.py"] +CMD ["-h"] diff --git a/python/hassh.py b/python/hassh.py new file mode 100644 index 0000000..5e309f9 --- /dev/null +++ b/python/hassh.py @@ -0,0 +1,428 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018, salesforce.com, inc. +# All rights reserved. +# Licensed under the BSD 3-Clause license. +# For full license text, see the LICENSE file in the repo root +# or https://opensource.org/licenses/BSD-3-Clause + +import argparse +import pyshark +import os +import json +import logging +import textwrap +from hashlib import md5 + +__author__ = "Adel '0x4D31' Karimi" +__email__ = "akarimishiraz@salesforce.com" +__version__ = "1.1" +__copyright__ = "Copyright (c) 2018, salesforce.com, inc." +__license__ = "BSD 3-Clause License" +__credits__ = ["Ben Reardon", "Adel Karimi", "John B. Althouse", + "Jeff Atkinson", "Josh Atkins"] + +HASSH_VERSION = '1.0' +CAP_BPF_FILTER = 'tcp port 22 or tcp port 2222' +DECODE_AS = {'tcp.port==2222': 'ssh'} + +protocol_dict = {} + + +class color: + CL1 = '\u001b[38;5;81m' + CL2 = '\u001b[38;5;220m' + CL3 = '\u001b[38;5;181m' + CL4 = '\u001b[38;5;208m' + END = '\033[0m' + + +def process_packet(packet, logf, fingerprint, pout): + logger = logging.getLogger() + global protocol_dict + + if not packet.highest_layer == 'SSH': + return + # Extract SSH identification string and correlate with KEXINIT msg + if 'protocol' in packet.ssh.field_names: + protocol = packet.ssh.protocol + srcip = packet.ip.src + dstip = packet.ip.dst + sport = packet.tcp.srcport + dport = packet.tcp.srcport + key = '{}:{}_{}:{}'.format(srcip, sport, dstip, dport) + protocol_dict[key] = protocol + if 'message_code' not in packet.ssh.field_names: + return + if packet.ssh.message_code != '20': + return + if ("analysis_retransmission" in packet.tcp.field_names or + "analysis_spurious_retransmission" in packet.tcp.field_names): + event = event_log(packet, event="retransmission") + if logf == 'json': + logger.info(json.dumps(event)) + return + # Client HASSH + if ((fingerprint == 'client' or fingerprint == 'all') + and int(packet.tcp.srcport) > int(packet.tcp.dstport)): + record = client_hassh(packet) + if logf == 'json': + logger.info(json.dumps(record)) + elif logf == 'csv': + csv_record = csv_logging(record) + logger.info(csv_record) + # Print the result + if not pout: + return + tmp = textwrap.dedent("""\ + [+] Client SSH_MSG_KEXINIT detected + {cl1}[ {sip}:{sport} -> {dip}:{dport} ]{cl1e} + [-] Identification String: {cl2}{proto}{cl2e} + [-] hassh: {cl2}{hassh}{cl2e} + [-] hassh Algorithms: {cl3}{hasshv}{cl3e}""") + tmp = tmp.format( + cl1=color.CL1, + sip=record['sourceIp'], + sport=record['sourcePort'], + dip=record['destinationIp'], + dport=record['destinationPort'], + cl1e=color.END, + cl2=color.CL2, + hassh=record['hassh'], + cl2e=color.END, + cl3=color.CL3, + hasshv=record['hasshAlgorithms'], + cl3e=color.END, + proto=record['client']) + print(tmp) + # Server HASSH + elif ((fingerprint == 'server' or fingerprint == 'all') + and int(packet.tcp.srcport) < int(packet.tcp.dstport)): + record = server_hassh(packet) + if logf == 'json': + logger.info(json.dumps(record)) + elif logf == 'csv': + csv_record = csv_logging(record) + logger.info(csv_record) + # Print the result + if not pout: + return + tmp = textwrap.dedent("""\ + [+] Server SSH_MSG_KEXINIT detected + {cl1}[ {sip}:{sport} -> {dip}:{dport} ]{cl1e} + [-] Identification String: {cl4}{proto}{cl4e} + [-] hasshServer: {cl4}{hasshs}{cl4e} + [-] hasshServer Algorithms: {cl3}{hasshsv}{cl3e}""") + tmp = tmp.format( + cl1=color.CL1, + sip=record['sourceIp'], + sport=record['sourcePort'], + dip=record['destinationIp'], + dport=record['destinationPort'], + cl1e=color.END, + cl4=color.CL4, + hasshs=record['hasshServer'], + cl4e=color.END, + cl3=color.CL3, + hasshsv=record['hasshServerAlgorithms'], + cl3e=color.END, + proto=record['server']) + print(tmp) + + +def event_log(packet, event): + """log the anomalous packets""" + if event == "retransmission": + event_message = "This packet is a (suspected) retransmission" + # Report the event (only for JSON output) + msg = {"timestamp": packet.sniff_time.isoformat(), + "eventType": event, + "eventMessage": event_message, + "sourceIp": packet.ip.src, + "destinationIp": packet.ip.dst, + "sourcePort": packet.tcp.srcport, + "destinationPort": packet.tcp.dstport} + return msg + + +def client_hassh(packet): + """returns HASSH (i.e. SSH Client Fingerprint) + HASSH = md5(KEX;EACTS;MACTS;CACTS) + """ + srcip = packet.ip.src + dstip = packet.ip.dst + sport = packet.tcp.srcport + dport = packet.tcp.srcport + protocol = None + key = '{}:{}_{}:{}'.format(srcip, sport, dstip, dport) + if key in protocol_dict: + protocol = protocol_dict[key] + # hassh fields + ckex = ceacts = cmacts = ccacts = "" + if 'kex_algorithms' in packet.ssh.field_names: + ckex = packet.ssh.kex_algorithms + if 'encryption_algorithms_client_to_server' in packet.ssh.field_names: + ceacts = packet.ssh.encryption_algorithms_client_to_server + if 'mac_algorithms_client_to_server' in packet.ssh.field_names: + cmacts = packet.ssh.mac_algorithms_client_to_server + if 'compression_algorithms_client_to_server' in packet.ssh.field_names: + ccacts = packet.ssh.compression_algorithms_client_to_server + # Log other kexinit fields (only in JSON) + clcts = clstc = ceastc = cmastc = ccastc = cshka = "" + if 'languages_client_to_server' in packet.ssh.field_names: + clcts = packet.ssh.languages_client_to_server + if 'languages_server_to_client' in packet.ssh.field_names: + clstc = packet.ssh.languages_server_to_client + if 'encryption_algorithms_server_to_client' in packet.ssh.field_names: + ceastc = packet.ssh.encryption_algorithms_server_to_client + if 'mac_algorithms_server_to_client' in packet.ssh.field_names: + cmastc = packet.ssh.mac_algorithms_server_to_client + if 'compression_algorithms_server_to_client' in packet.ssh.field_names: + ccastc = packet.ssh.compression_algorithms_server_to_client + if 'server_host_key_algorithms' in packet.ssh.field_names: + cshka = packet.ssh.server_host_key_algorithms + # Create hassh + hassh_str = ';'.join([ckex, ceacts, cmacts, ccacts]) + hassh = md5(hassh_str.encode()).hexdigest() + record = {"timestamp": packet.sniff_time.isoformat(), + "sourceIp": packet.ip.src, + "destinationIp": packet.ip.dst, + "sourcePort": packet.tcp.srcport, + "destinationPort": packet.tcp.dstport, + "client": protocol, + "hassh": hassh, + "hasshAlgorithms": hassh_str, + "hasshVersion": HASSH_VERSION, + "ckex": ckex, + "ceacts": ceacts, + "cmacts": cmacts, + "ccacts": ccacts, + "clcts": clcts, + "clstc": clstc, + "ceastc": ceastc, + "cmastc": cmastc, + "ccastc": ccastc, + "cshka": cshka} + return record + + +def server_hassh(packet): + """returns HASSHServer (i.e. SSH Server Fingerprint) + HASSHServer = md5(KEX;EASTC;MASTC;CASTC) + """ + srcip = packet.ip.src + dstip = packet.ip.dst + sport = packet.tcp.srcport + dport = packet.tcp.srcport + protocol = None + key = '{}:{}_{}:{}'.format(srcip, sport, dstip, dport) + if key in protocol_dict: + protocol = protocol_dict[key] + # hasshServer fields + skex = seastc = smastc = scastc = "" + if 'kex_algorithms' in packet.ssh.field_names: + skex = packet.ssh.kex_algorithms + if 'encryption_algorithms_server_to_client' in packet.ssh.field_names: + seastc = packet.ssh.encryption_algorithms_server_to_client + if 'mac_algorithms_server_to_client' in packet.ssh.field_names: + smastc = packet.ssh.mac_algorithms_server_to_client + if 'compression_algorithms_server_to_client' in packet.ssh.field_names: + scastc = packet.ssh.compression_algorithms_server_to_client + # Log other kexinit fields (only in JSON) + slcts = slstc = seacts = smacts = scacts = sshka = "" + if 'languages_client_to_server' in packet.ssh.field_names: + slcts = packet.ssh.languages_client_to_server + if 'languages_server_to_client' in packet.ssh.field_names: + slstc = packet.ssh.languages_server_to_client + if 'encryption_algorithms_client_to_server' in packet.ssh.field_names: + seacts = packet.ssh.encryption_algorithms_client_to_server + if 'mac_algorithms_client_to_server' in packet.ssh.field_names: + smacts = packet.ssh.mac_algorithms_client_to_server + if 'compression_algorithms_client_to_server' in packet.ssh.field_names: + scacts = packet.ssh.compression_algorithms_client_to_server + if 'server_host_key_algorithms' in packet.ssh.field_names: + sshka = packet.ssh.server_host_key_algorithms + # Create hasshServer + hasshs_str = ';'.join([skex, seastc, smastc, scastc]) + hasshs = md5(hasshs_str.encode()).hexdigest() + record = {"timestamp": packet.sniff_time.isoformat(), + "sourceIp": packet.ip.src, + "destinationIp": packet.ip.dst, + "sourcePort": packet.tcp.srcport, + "destinationPort": packet.tcp.dstport, + "server": protocol, + "hasshServer": hasshs, + "hasshServerAlgorithms": hasshs_str, + "hasshVersion": HASSH_VERSION, + "skex": skex, + "seastc": seastc, + "smastc": smastc, + "scastc": scastc, + "slcts": slcts, + "slstc": slstc, + "seacts": seacts, + "smacts": smacts, + "scacts": scacts, + "sshka": sshka} + return record + + +def csv_logging(record): + """generate output in csv format""" + csv_record = ('{ts},{si},{di},{sp},{dp},{t},"{p}",{h},{v},"{ha}",' + '"{k}","{e}","{m}","{c}"') + if 'hassh' in record: + hasshType = 'client' + kexAlgs = record['ckex'] + encAlgs = record['ceacts'] + macAlgs = record['cmacts'] + cmpAlgs = record['ccacts'] + hassh = record['hassh'] + hasshAlgorithms = record['hasshAlgorithms'] + identificationString = record['client'] + elif 'hasshServer' in record: + hasshType = 'server' + kexAlgs = record['skex'] + encAlgs = record['seastc'] + macAlgs = record['smastc'] + cmpAlgs = record['scastc'] + hassh = record['hasshServer'] + hasshAlgorithms = record['hasshServerAlgorithms'] + identificationString = record['server'] + csv_record = csv_record.format( + ts=record['timestamp'], si=record['sourceIp'], + di=record['destinationIp'], sp=record['sourcePort'], + dp=record['destinationPort'], t=hasshType, p=identificationString, + h=hassh, v=HASSH_VERSION, ha=hasshAlgorithms, k=kexAlgs, e=encAlgs, + m=macAlgs, c=cmpAlgs) + return csv_record + + +def parse_cmd_args(): + """parse command line arguments""" + desc = """A python script for extracting HASSH fingerprints""" + parser = argparse.ArgumentParser(description=(desc)) + helptxt = "pcap file to process" + parser.add_argument('-r', '--read_file', type=str, help=helptxt) + helptxt = "directory of pcap files to process" + parser.add_argument('-d', '--read_directory', type=str, help=helptxt) + helptxt = "listen on interface" + parser.add_argument('-i', '--interface', type=str, help=helptxt) + helptxt = "client or server fingerprint. Default: all" + parser.add_argument( + '-fp', + '--fingerprint', + default='all', + choices=['client', 'server'], + help=helptxt) + helptxt = "a dictionary of {decode_criterion_string: decode_as_protocol} \ + that are used to tell tshark to decode protocols in situations it \ + wouldn't usually. Default: {'tcp.port==2222': 'ssh'}." + parser.add_argument( + '-da', '--decode_as', type=dict, default=DECODE_AS, help=helptxt) + helptxt = "BPF capture filter to use (for live capture only).\ + Default: 'tcp port 22 or tcp port 2222'" + parser.add_argument( + '-f', '--bpf_filter', type=str, default=CAP_BPF_FILTER, help=helptxt) + helptxt = "specify the output log format (json/csv)" + parser.add_argument( + '-l', + '--log_format', + choices=['json', 'csv'], + help=helptxt) + helptxt = "specify the output log file. Default: hassh.log" + parser.add_argument( + '-o', '--output_file', default='hassh.log', type=str, help=helptxt) + helptxt = "save the live captured packets to this file" + parser.add_argument( + '-w', '--write_pcap', default=None, type=str, help=helptxt) + helptxt = "print the output" + parser.add_argument( + '-p', '--print_output', action="store_true", help=helptxt) + return parser.parse_args() + + +def setup_logging(logfile): + """setup logging""" + logger = logging.getLogger() + handler = logging.FileHandler(logfile) + formatter = logging.Formatter('%(message)s') + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.setLevel(logging.INFO) + return logger + + +def main(): + """intake arguments from the user and extract HASSH fingerprints.""" + args = parse_cmd_args() + setup_logging(args.output_file) + logger = logging.getLogger() + + csv_header = ("timestamp,sourceIp,destinationIp,sourcePort," + "destinationPort,hasshType,identificationString," + "hassh,hasshVersion,hasshAlgorithms,kexAlgs,encAlgs," + "macAlgs,cmpAlgs") + if args.log_format == 'csv': + logger.info(csv_header) + + # Process PCAP file + if args.read_file: + cap = pyshark.FileCapture(args.read_file, decode_as=args.decode_as) + try: + for packet in cap: + process_packet( + packet, + logf=args.log_format, + fingerprint=args.fingerprint, + pout=args.print_output) + cap.close() + cap.eventloop.stop() + except Exception as e: + print('Error: {}'.format(e)) + pass + + # Process directory of PCAP files + elif args.read_directory: + files = [f.path for f in os.scandir(args.read_directory) + if not f.name.startswith('.') and not f.is_dir() + and (f.name.endswith(".pcap") or f.name.endswith(".pcapng") + or f.name.endswith(".cap"))] + for file in files: + cap = pyshark.FileCapture(file, decode_as=args.decode_as) + try: + for packet in cap: + process_packet( + packet, + logf=args.log_format, + fingerprint=args.fingerprint, + pout=args.print_output) + cap.close() + cap.eventloop.stop() + except Exception as e: + print('Error: {}'.format(e)) + pass + + # Capture live network traffic + elif args.interface: + # TODO: Use a Ring Buffer (LiveRingCapture), when the issue is fixed: + # https://github.com/KimiNewt/pyshark/issues/299 + cap = pyshark.LiveCapture( + interface=args.interface, + decode_as=args.decode_as, + bpf_filter=args.bpf_filter, + output_file=args.write_pcap) + try: + for packet in cap.sniff_continuously(packet_count=0): + # if len(protocol_dict) > 10000: + # protocol_dict.clear() + process_packet( + packet, + logf=args.log_format, + fingerprint=args.fingerprint, + pout=args.print_output) + except (KeyboardInterrupt, SystemExit): + print("Exiting..\nBYE o/\n") + + +if __name__ == '__main__': + main() diff --git a/python/hasshGen/README.md b/python/hasshGen/README.md new file mode 100644 index 0000000..d88b876 --- /dev/null +++ b/python/hasshGen/README.md @@ -0,0 +1,82 @@ +# hasshGen.py + +[![License: BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) + +Sample python script and Dockerfiles to automate building docker images with different SSH clients/versions for generating HASSH fingerprints. +As a demonstration we created a list ([sshClient_list](sshClient_list)) containing 49 different version of OpenSSH, Python’s paramiko and Dropbear SSH clients and generated a database of HASSH fingerprints in [JSON](hassh_fingerprints.json) and [CSV](hassh_fingerprints.csv) formats. + +## Getting Started +1. Install Docker CE: + > [Download Docker Engine](https://store.docker.com/search?type=edition&offering=community) + +2. Install the Docker's Python library: + > `pipenv install docker` + +4. Test: + > `pipenv run python3 hasshgen.py -h` + +Output: + +``` +usage: hasshgen.py [-h] [-i IMAGE] [-iV IMAGE_VER] [-c SSHCLIENT] + [-cV SSHCLIENT_VER] [-d DOCKER_FILE] -s SERVER + [-iF INPUT_FILE] [-f] [--cmd CMD] + +A python script to automate building docker images with different SSH +clients/versions. + +optional arguments: + -h, --help show this help message and exit + -i IMAGE, --image IMAGE + Docker image name. e.g. alpine, ubuntu + -iV IMAGE_VER, --image_ver IMAGE_VER + Docker image version. e.g. 18.04, latest + -c SSHCLIENT, --sshclient SSHCLIENT + SSH client name + -cV SSHCLIENT_VER, --sshclient_ver SSHCLIENT_VER + SSH client version + -d DOCKER_FILE, --docker_file DOCKER_FILE + Specify the Dockerfile + -s SERVER, --server SERVER + Specify the server address to test the SSH connection + -iF INPUT_FILE, --input_file INPUT_FILE + Bulk mode; Specify an input file containing a list of + docker image, image version, sshclient and sshclient + version + -f, --fingerprint Set this option to automatically run hassh.py for + capturing SSH client fingerprints (HASSH). Specify the + command for running hassh.py using --cmd arg. + --cmd CMD Enter the command for running hassh.py. Use with + -f/--fingerprint arg +``` + +## Usage + * Build and run a docker image with specific SSH client/version: +``` +$ python3 hasshgen.py --docker_file Dockerfile.alpine --image alpine -iV 3.6 --sshclient openssh-client --sshclient_ver 7.5_p1-r2 --server + +[+] successfully built + - image: alpine:3.6, ssh client: openssh-client 7.5_p1-r2 +[+] Command successfully executed! + ``` + +After building the docker image, the script runs a SSH command to generate SSH connections for fingerprinting. It currently supports openssh, paramiko, and dropbear SSH clients. You can easily add other SSH clients. + + * Build docker images using an input file in this format: [sshClient_list](sshClient_list) +``` +$ python3 hasshgen.py --input_file sshClient_list --server +[+] successfully built + - image: alpine:3.3, ssh client: openssh-client 7.2_p2-r3 +[+] Command successfully executed! +[+] successfully built + - image: alpine:3.4, ssh client: openssh-client 7.2_p2-r5 +[+] Command successfully executed! +[+] successfully built + - image: alpine:3.5, ssh client: openssh-client 7.4_p1-r1 +[+] Command successfully executed! +``` + + * You can use `-f` or `--fingerprint` arg to automatically run `hassh.py` for extracting the fingerprints. Use `--cmd` to change the default HASSH_COMMAND: + ``` +$ python3 hasshgen.py --input_file sshClient_list --server --fingerprint --cmd 'python3 ../hassh.py -i eth0 -l json -o fingerprint.json' + ``` diff --git a/python/hasshGen/dockerfiles/Dockerfile.alpine b/python/hasshGen/dockerfiles/Dockerfile.alpine new file mode 100644 index 0000000..d66d925 --- /dev/null +++ b/python/hasshGen/dockerfiles/Dockerfile.alpine @@ -0,0 +1,10 @@ +# https://hub.docker.com/_/alpine/ +ARG IMAGE +ARG IMAGE_VER +FROM $IMAGE:$IMAGE_VER +MAINTAINER Adel "0x4D31" Karimi + +ARG SSHCLIENT +ARG SSHCLIENT_VER +# Install the SSH client +RUN apk --no-cache add $SSHCLIENT=$SSHCLIENT_VER diff --git a/python/hasshGen/dockerfiles/Dockerfile.centos b/python/hasshGen/dockerfiles/Dockerfile.centos new file mode 100644 index 0000000..5e3af70 --- /dev/null +++ b/python/hasshGen/dockerfiles/Dockerfile.centos @@ -0,0 +1,11 @@ +# https://hub.docker.com/_/centos/ +# https://hub.docker.com/_/fedora/ +ARG IMAGE +ARG IMAGE_VER +FROM $IMAGE:$IMAGE_VER +MAINTAINER Adel "0x4D31" Karimi + +ARG SSHCLIENT +ARG SSHCLIENT_VER +# Install the SSH client +RUN yum -y install $SSHCLIENT-$SSHCLIENT_VER && yum clean all diff --git a/python/hasshGen/dockerfiles/Dockerfile.debian b/python/hasshGen/dockerfiles/Dockerfile.debian new file mode 100644 index 0000000..4b9ef23 --- /dev/null +++ b/python/hasshGen/dockerfiles/Dockerfile.debian @@ -0,0 +1,14 @@ +# https://hub.docker.com/_/debian/ +# https://hub.docker.com/_/ubuntu/ +ARG IMAGE +ARG IMAGE_VER +FROM $IMAGE:$IMAGE_VER +MAINTAINER Adel "0x4D31" Karimi + +ENV DEBIAN_FRONTEND noninteractive +ARG SSHCLIENT +ARG SSHCLIENT_VER +# Install the SSH client +RUN apt-get update && apt-get install -y \ + $SSHCLIENT=$SSHCLIENT_VER \ + && rm -rf /var/lib/apt/lists/* diff --git a/python/hasshGen/dockerfiles/Dockerfile.python b/python/hasshGen/dockerfiles/Dockerfile.python new file mode 100644 index 0000000..34065ed --- /dev/null +++ b/python/hasshGen/dockerfiles/Dockerfile.python @@ -0,0 +1,27 @@ +# https://hub.docker.com/_/python/ +ARG IMAGE +ARG IMAGE_VER +FROM $IMAGE:$IMAGE_VER +MAINTAINER Adel "0x4D31" Karimi + +# ARG SSHCLIENT +ARG SSHCLIENT_VER +# Install paramiko (ref: eduardoshanahan/paramiko) +RUN apk add --virtual .install_dependencies_paramiko \ + gcc \ + musl-dev \ + python-dev \ + libffi-dev \ + openssl-dev \ + build-base \ + py-pip \ +&& apk add zlib \ + zlib-dev \ + libssl1.0 \ + openssl-dev \ +&& pip install cffi \ +&& pip install paramiko==$SSHCLIENT_VER \ +&& apk del .install_dependencies_paramiko + +# Copy the python script +COPY paramiko_conn.py /tmp/ diff --git a/python/hasshGen/hassh_fingerprints.csv b/python/hasshGen/hassh_fingerprints.csv new file mode 100644 index 0000000..5aa160e --- /dev/null +++ b/python/hasshGen/hassh_fingerprints.csv @@ -0,0 +1,50 @@ +image,imageVersion,sshClient,sshClientVersion,clientIdentificationString,hassh,hasshVersion,hasshAlgorithms +debian,"sid-slim",dropbear,"2018.76-4","SSH-2.0-dropbear_2018.76",e22efe3cde8b396b874c3f13fdb6c61a,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256;zlib@openssh.com,zlib,none" +debian,"buster-slim",dropbear,"2018.76-4","SSH-2.0-dropbear_2018.76",e22efe3cde8b396b874c3f13fdb6c61a,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256;zlib@openssh.com,zlib,none" +debian,"stretch-slim",dropbear,"2016.74-5","SSH-2.0-dropbear_2016.74",7742887e2a57712bdb91a772093f54ce,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none" +debian,"jessie-slim",dropbear,"2014.65-1+deb8u2","SSH-2.0-dropbear_2014.65",ad00edb0c2a031d9884826ba7b7ba41e,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none" +debian,"jessie-slim",dropbear,"2014.65-1+deb8u3","SSH-2.0-dropbear_2014.65",ad00edb0c2a031d9884826ba7b7ba41e,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none" +debian,"wheezy-slim",dropbear,"2012.55-1.3","SSH-2.0-dropbear_2012.55",16f898dd8ed8279e1055350b4e20666c,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group14-sha1;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none" +debian,"wheezy-slim",dropbear,"2012.55-1.3+deb7u2","SSH-2.0-dropbear_2012.55",16f898dd8ed8279e1055350b4e20666c,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group14-sha1;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none" +ubuntu,"18.04",dropbear,"2017.75-3build1","SSH-2.0-dropbear_2017.75",7742887e2a57712bdb91a772093f54ce,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none" +ubuntu,"16.04",dropbear,"2016.72-1","SSH-2.0-dropbear_2016.72",7742887e2a57712bdb91a772093f54ce,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none" +ubuntu,"14.04",dropbear,"2013.60-1ubuntu2","SSH-2.0-dropbear_2013.60",22865d7159a8dedcb091cd4fc5fd2841,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none" +alpine,"3.8","dropbear-dbclient","2018.76-r2","SSH-2.0-dropbear_2018.76",e22efe3cde8b396b874c3f13fdb6c61a,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256;zlib@openssh.com,zlib,none" +alpine,"3.7","dropbear-dbclient","2017.75-r1","SSH-2.0-dropbear_2017.75",7742887e2a57712bdb91a772093f54ce,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none" +alpine,"3.5","dropbear-dbclient","2017.75-r0","SSH-2.0-dropbear_2017.75",7742887e2a57712bdb91a772093f54ce,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none" +python,"3.6-alpine",paramiko,"1.13.0","SSH-2.0-paramiko_1.13.0",b05dfbbf26090c7792d4aa6b76cd1f1a,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1;aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none" +python,"3.6-alpine",paramiko,"1.14.0","SSH-2.0-paramiko_1.14.0",b05dfbbf26090c7792d4aa6b76cd1f1a,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1;aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none" +python,"3.6-alpine",paramiko,"1.15.0","SSH-2.0-paramiko_1.15.0",d72f74b08466652d162ca02ad197b9ad,"1.0","diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none" +python,"3.6-alpine",paramiko,"1.16.0","SSH-2.0-paramiko_1.16.0",c6f5e6d54285a11b9f02fef7fc77bd6f,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none" +python,"3.6-alpine",paramiko,"1.17.0","SSH-2.0-paramiko_1.17.0",c6f5e6d54285a11b9f02fef7fc77bd6f,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none" +python,"3.6-alpine",paramiko,"1.18.0","SSH-2.0-paramiko_1.18.0",c6f5e6d54285a11b9f02fef7fc77bd6f,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none" +python,"3.6-alpine",paramiko,"2.0.0","SSH-2.0-paramiko_2.0.0",c6f5e6d54285a11b9f02fef7fc77bd6f,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none" +python,"3.6-alpine",paramiko,"2.1.0","SSH-2.0-paramiko_2.1.0",c6f5e6d54285a11b9f02fef7fc77bd6f,"1.0","diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none" +python,"3.6-alpine",paramiko,"2.2.0","SSH-2.0-paramiko_2.2.0",b5752e36ba6c5979a575e43178908adf,"1.0","ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc;hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none" +python,"3.6-alpine",paramiko,"2.3.0","SSH-2.0-paramiko_2.3.0",b5752e36ba6c5979a575e43178908adf,"1.0","ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc;hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none" +python,"3.6-alpine",paramiko,"2.4.1","SSH-2.0-paramiko_2.4.1",b5752e36ba6c5979a575e43178908adf,"1.0","ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc;hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none" +centos,7,"openssh-clients","7.4p1-16.el7","SSH-2.0-OpenSSH_7.4",ec9ea89c70f5fc71cf61061bff5e4740,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +centos,6,"openssh-clients","5.3p1-123.el6_9","SSH-2.0-OpenSSH_5.3",3646f4d62498cd92721bd242ce988a42,"1.0","diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se;hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96;none,zlib@openssh.com,zlib" +fedora,rawhide,"openssh-clients","7.8p1-2.fc30","SSH-2.0-OpenSSH_7.8",4eea4239dc591cbf6e661a656ae9d58c,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc;hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512;none,zlib@openssh.com,zlib" +fedora,29,"openssh-clients","7.8p1-1.fc29","SSH-2.0-OpenSSH_7.8",4eea4239dc591cbf6e661a656ae9d58c,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc;hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512;none,zlib@openssh.com,zlib" +fedora,28,"openssh-clients","7.7p1-2.fc28","SSH-2.0-OpenSSH_7.7",4eea4239dc591cbf6e661a656ae9d58c,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc;hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512;none,zlib@openssh.com,zlib" +fedora,27,"openssh-clients","7.5p1-5.fc27","SSH-2.0-OpenSSH_7.5",82a9e17b13a816a13b8c8bfe1b5cf030,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc,3des-cbc;umac-128-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128@openssh.com,hmac-sha1,hmac-sha2-256,hmac-sha2-512;none,zlib@openssh.com,zlib" +fedora,26,"openssh-clients","7.5p1-2.fc26","SSH-2.0-OpenSSH_7.5",251479d8057683f8201e4a52b80a75ff,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc,3des-cbc;umac-128-etm@openssh.com,umac-128@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1,hmac-sha2-256-etm@openssh.com,hmac-sha2-256,hmac-sha2-512-etm@openssh.com,hmac-sha2-512;none,zlib@openssh.com,zlib" +debian,"sid-slim","openssh-client","1:7.8p1-1","SSH-2.0-OpenSSH_7.8p1 Debian-1",ec7378c1a92f5a8dde7e8b7a1ddf33d1,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +debian,"buster-slim","openssh-client","1:7.8p1-1","SSH-2.0-OpenSSH_7.8p1 Debian-1",ec7378c1a92f5a8dde7e8b7a1ddf33d1,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +debian,"stretch-slim","openssh-client","1:7.4p1-10+deb9u4","SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u4",0df0d56bb50c6b2426d8d40234bf1826,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +debian,"jessie-slim","openssh-client","1:6.7p1-5+deb8u4","SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u4",46c5bd9748882f1a5d75753fb7d47a61,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib" +debian,"jessie-slim","openssh-client","1:6.7p1-5+deb8u7","SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u7",46c5bd9748882f1a5d75753fb7d47a61,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib" +debian,"wheezy-backports","openssh-client","1:6.6p1-4~bpo70+1","SSH-2.0-OpenSSH_6.6.1p1 Debian-4~bpo70+1",e30029a55fea2fcd3501023fb659bfae,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib" +debian,"wheezy-slim","openssh-client","1:6.0p1-4+deb7u4","SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u4",c0216580c330eab8906d740d31f761a8,"1.0","ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib" +debian,"wheezy-slim","openssh-client","1:6.0p1-4+deb7u7","SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u7",c0216580c330eab8906d740d31f761a8,"1.0","ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib" +ubuntu,"18.10","openssh-client","1:7.7p1-4","SSH-2.0-OpenSSH_7.7p1 Ubuntu-4",06046964c022c6407d15a27b12a6a4fb,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +ubuntu,"18.04","openssh-client","1:7.6p1-4","SSH-2.0-OpenSSH_7.6p1 Ubuntu-4",06046964c022c6407d15a27b12a6a4fb,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +ubuntu,"16.04","openssh-client","1:7.2p2-4ubuntu2.4","SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4",68e0ba85e1a818f7c49ea3f4b849bd15,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +ubuntu,"14.04","openssh-client","1:6.6p1-2ubuntu2.10","SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.10",e30029a55fea2fcd3501023fb659bfae,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib" +alpine,edge,"openssh-client","7.8_p1-r0","SSH-2.0-OpenSSH_7.8",ec7378c1a92f5a8dde7e8b7a1ddf33d1,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +alpine,"3.7","openssh-client","7.5_p1-r8","SSH-2.0-OpenSSH_7.5p1-hpn14v4",0df0d56bb50c6b2426d8d40234bf1826,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +alpine,"3.6","openssh-client","7.5_p1-r2","SSH-2.0-OpenSSH_7.5p1-hpn14v4",0df0d56bb50c6b2426d8d40234bf1826,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +alpine,"3.5","openssh-client","7.4_p1-r1","SSH-2.0-OpenSSH_7.4",0df0d56bb50c6b2426d8d40234bf1826,"1.0","curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +alpine,"3.4","openssh-client","7.2_p2-r5","SSH-2.0-OpenSSH_7.2p2-hpn14v4",68e0ba85e1a818f7c49ea3f4b849bd15,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" +alpine,"3.3","openssh-client","7.2_p2-r3","SSH-2.0-OpenSSH_7.2p2-hpn14v4",68e0ba85e1a818f7c49ea3f4b849bd15,"1.0","curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib" diff --git a/python/hasshGen/hassh_fingerprints.json b/python/hasshGen/hassh_fingerprints.json new file mode 100644 index 0000000..b6bf8a7 --- /dev/null +++ b/python/hasshGen/hassh_fingerprints.json @@ -0,0 +1,49 @@ +{"image": "alpine", "imageVersion": "3.3", "sshClient": "openssh-client", "sshClientVersion": "7.2_p2-r3", "clientIdentificationString": "SSH-2.0-OpenSSH_7.2p2-hpn14v4", "hassh": "68e0ba85e1a818f7c49ea3f4b849bd15", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "alpine", "imageVersion": "3.4", "sshClient": "openssh-client", "sshClientVersion": "7.2_p2-r5", "clientIdentificationString": "SSH-2.0-OpenSSH_7.2p2-hpn14v4", "hassh": "68e0ba85e1a818f7c49ea3f4b849bd15", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "alpine", "imageVersion": "3.5", "sshClient": "openssh-client", "sshClientVersion": "7.4_p1-r1", "clientIdentificationString": "SSH-2.0-OpenSSH_7.4", "hassh": "0df0d56bb50c6b2426d8d40234bf1826", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "alpine", "imageVersion": "3.6", "sshClient": "openssh-client","sshClientVersion": "7.5_p1-r2", "clientIdentificationString": "SSH-2.0-OpenSSH_7.5p1-hpn14v4", "hassh": "0df0d56bb50c6b2426d8d40234bf1826", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "alpine", "imageVersion": "3.7", "sshClient": "openssh-client","sshClientVersion": "7.5_p1-r8", "clientIdentificationString": "SSH-2.0-OpenSSH_7.5p1-hpn14v4", "hassh": "0df0d56bb50c6b2426d8d40234bf1826", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "alpine", "imageVersion": "edge", "sshClient": "openssh-client","sshClientVersion": "7.8_p1-r0", "clientIdentificationString": "SSH-2.0-OpenSSH_7.8", "hassh": "ec7378c1a92f5a8dde7e8b7a1ddf33d1", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "ubuntu", "imageVersion": "14.04", "sshClient": "openssh-client","sshClientVersion": "1:6.6p1-2ubuntu2.10", "clientIdentificationString": "SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.10", "hassh": "e30029a55fea2fcd3501023fb659bfae", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmacts": "hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmastc": "hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "ubuntu", "imageVersion": "16.04", "sshClient": "openssh-client","sshClientVersion": "1:7.2p2-4ubuntu2.4", "clientIdentificationString": "SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4", "hassh": "68e0ba85e1a818f7c49ea3f4b849bd15", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "ubuntu", "imageVersion": "18.04", "sshClient": "openssh-client","sshClientVersion": "1:7.6p1-4", "clientIdentificationString": "SSH-2.0-OpenSSH_7.6p1 Ubuntu-4", "hassh": "06046964c022c6407d15a27b12a6a4fb", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "ubuntu", "imageVersion": "18.10", "sshClient": "openssh-client","sshClientVersion": "1:7.7p1-4", "clientIdentificationString": "SSH-2.0-OpenSSH_7.7p1 Ubuntu-4", "hassh": "06046964c022c6407d15a27b12a6a4fb", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "debian", "imageVersion": "wheezy-slim", "sshClient": "openssh-client","sshClientVersion": "1:6.0p1-4+deb7u7", "clientIdentificationString": "SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u7", "hassh": "c0216580c330eab8906d740d31f761a8", "hasshAlgorithms": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmacts": "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmastc": "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "debian", "imageVersion": "wheezy-slim", "sshClient": "openssh-client","sshClientVersion": "1:6.0p1-4+deb7u4", "clientIdentificationString": "SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u4", "hassh": "c0216580c330eab8906d740d31f761a8", "hasshAlgorithms": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmacts": "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmastc": "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "debian", "imageVersion": "wheezy-backports", "sshClient": "openssh-client","sshClientVersion": "1:6.6p1-4~bpo70+1", "clientIdentificationString": "SSH-2.0-OpenSSH_6.6.1p1 Debian-4~bpo70+1", "hassh": "e30029a55fea2fcd3501023fb659bfae", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmacts": "hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmastc": "hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "debian", "imageVersion": "jessie-slim", "sshClient": "openssh-client","sshClientVersion": "1:6.7p1-5+deb8u7", "clientIdentificationString": "SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u7", "hassh": "46c5bd9748882f1a5d75753fb7d47a61", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "debian", "imageVersion": "jessie-slim", "sshClient": "openssh-client","sshClientVersion": "1:6.7p1-5+deb8u4", "clientIdentificationString": "SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u4", "hassh": "46c5bd9748882f1a5d75753fb7d47a61", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "debian", "imageVersion": "stretch-slim", "sshClient": "openssh-client","sshClientVersion": "1:7.4p1-10+deb9u4", "clientIdentificationString": "SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u4", "hassh": "0df0d56bb50c6b2426d8d40234bf1826", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "debian", "imageVersion": "buster-slim", "sshClient": "openssh-client","sshClientVersion": "1:7.8p1-1", "clientIdentificationString": "SSH-2.0-OpenSSH_7.8p1 Debian-1", "hassh": "ec7378c1a92f5a8dde7e8b7a1ddf33d1", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "debian", "imageVersion": "sid-slim", "sshClient": "openssh-client","sshClientVersion": "1:7.8p1-1", "clientIdentificationString": "SSH-2.0-OpenSSH_7.8p1 Debian-1", "hassh": "ec7378c1a92f5a8dde7e8b7a1ddf33d1", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "fedora", "imageVersion": "26", "sshClient": "openssh-clients","sshClientVersion": "7.5p1-2.fc26", "clientIdentificationString": "SSH-2.0-OpenSSH_7.5", "hassh": "251479d8057683f8201e4a52b80a75ff", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc,3des-cbc;umac-128-etm@openssh.com,umac-128@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1,hmac-sha2-256-etm@openssh.com,hmac-sha2-256,hmac-sha2-512-etm@openssh.com,hmac-sha2-512;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc,3des-cbc", "cmacts": "umac-128-etm@openssh.com,umac-128@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1,hmac-sha2-256-etm@openssh.com,hmac-sha2-256,hmac-sha2-512-etm@openssh.com,hmac-sha2-512", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc,3des-cbc", "cmastc": "umac-128-etm@openssh.com,umac-128@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1,hmac-sha2-256-etm@openssh.com,hmac-sha2-256,hmac-sha2-512-etm@openssh.com,hmac-sha2-512", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "fedora", "imageVersion": "27", "sshClient": "openssh-clients","sshClientVersion": "7.5p1-5.fc27", "clientIdentificationString": "SSH-2.0-OpenSSH_7.5", "hassh": "82a9e17b13a816a13b8c8bfe1b5cf030", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc,3des-cbc;umac-128-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128@openssh.com,hmac-sha1,hmac-sha2-256,hmac-sha2-512;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc,3des-cbc", "cmacts": "umac-128-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128@openssh.com,hmac-sha1,hmac-sha2-256,hmac-sha2-512", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc,3des-cbc", "cmastc": "umac-128-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128@openssh.com,hmac-sha1,hmac-sha2-256,hmac-sha2-512", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "fedora", "imageVersion": "28", "sshClient": "openssh-clients","sshClientVersion": "7.7p1-2.fc28", "clientIdentificationString": "SSH-2.0-OpenSSH_7.7", "hassh": "4eea4239dc591cbf6e661a656ae9d58c", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc;hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc", "cmacts": "hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc", "cmastc": "hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "fedora", "imageVersion": "29", "sshClient": "openssh-clients","sshClientVersion": "7.8p1-1.fc29", "clientIdentificationString": "SSH-2.0-OpenSSH_7.8", "hassh": "4eea4239dc591cbf6e661a656ae9d58c", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc;hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc", "cmacts": "hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc", "cmastc": "hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "fedora", "imageVersion": "rawhide", "sshClient": "openssh-clients","sshClientVersion": "7.8p1-2.fc30", "clientIdentificationString": "SSH-2.0-OpenSSH_7.8", "hassh": "4eea4239dc591cbf6e661a656ae9d58c", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c;aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc;hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c", "ceacts": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc", "cmacts": "hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc", "cmastc": "hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "centos", "imageVersion": "6", "sshClient": "openssh-clients","sshClientVersion": "5.3p1-123.el6_9", "clientIdentificationString": "SSH-2.0-OpenSSH_5.3", "hassh": "3646f4d62498cd92721bd242ce988a42", "hasshAlgorithms": "diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se;hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se", "cmacts": "hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se", "cmastc": "hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "centos", "imageVersion": "7", "sshClient": "openssh-clients","sshClientVersion": "7.4p1-16.el7", "clientIdentificationString": "SSH-2.0-OpenSSH_7.4", "hassh": "ec9ea89c70f5fc71cf61061bff5e4740", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc;umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,ext-info-c", "ceacts": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmacts": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccacts": "none,zlib@openssh.com,zlib", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc", "cmastc": "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1", "ccastc": "none,zlib@openssh.com,zlib"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "2.4.1", "clientIdentificationString": "SSH-2.0-paramiko_2.4.1", "hassh": "b5752e36ba6c5979a575e43178908adf", "hasshAlgorithms": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc;hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none", "hasshVersion": "1.0", "ckex": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc", "cmacts": "hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc", "cmastc": "hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "2.3.0", "clientIdentificationString": "SSH-2.0-paramiko_2.3.0", "hassh": "b5752e36ba6c5979a575e43178908adf", "hasshAlgorithms": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc;hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none", "hasshVersion": "1.0", "ckex": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc", "cmacts": "hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc", "cmastc": "hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "2.2.0", "clientIdentificationString": "SSH-2.0-paramiko_2.2.0", "hassh": "b5752e36ba6c5979a575e43178908adf", "hasshAlgorithms": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc;hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none", "hasshVersion": "1.0", "ckex": "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc", "cmacts": "hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,3des-cbc", "cmastc": "hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "2.1.0", "clientIdentificationString": "SSH-2.0-paramiko_2.1.0", "hassh": "c6f5e6d54285a11b9f02fef7fc77bd6f", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmacts": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmastc": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "2.0.0", "clientIdentificationString": "SSH-2.0-paramiko_2.0.0", "hassh": "c6f5e6d54285a11b9f02fef7fc77bd6f", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmacts": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmastc": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "1.18.0", "clientIdentificationString": "SSH-2.0-paramiko_1.18.0", "hassh": "c6f5e6d54285a11b9f02fef7fc77bd6f", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmacts": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmastc": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "1.17.0", "clientIdentificationString": "SSH-2.0-paramiko_1.17.0", "hassh": "c6f5e6d54285a11b9f02fef7fc77bd6f", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmacts": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmastc": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "1.16.0", "clientIdentificationString": "SSH-2.0-paramiko_1.16.0", "hassh": "c6f5e6d54285a11b9f02fef7fc77bd6f", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256;aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1;none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256", "ceacts": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmacts": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmastc": "hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-sha1", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "1.15.0", "clientIdentificationString": "SSH-2.0-paramiko_1.15.0", "hassh": "d72f74b08466652d162ca02ad197b9ad", "hasshAlgorithms": "diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1;aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmacts": "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmastc": "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "1.14.0", "clientIdentificationString": "SSH-2.0-paramiko_1.14.0", "hassh": "b05dfbbf26090c7792d4aa6b76cd1f1a", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1;aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmacts": "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmastc": "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccastc": "none"} +{"image": "python", "imageVersion": "3.6-alpine", "sshClient": "paramiko","sshClientVersion": "1.13.0", "clientIdentificationString": "SSH-2.0-paramiko_1.13.0", "hassh": "b05dfbbf26090c7792d4aa6b76cd1f1a", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1;aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256;hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96;none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmacts": "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccacts": "none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,blowfish-cbc,aes256-cbc,3des-cbc,arcfour128,arcfour256", "cmastc": "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96", "ccastc": "none"} +{"image": "alpine", "imageVersion": "3.5", "sshClient": "dropbear-dbclient","sshClientVersion": "2017.75-r0", "clientIdentificationString": "SSH-2.0-dropbear_2017.75", "hassh": "7742887e2a57712bdb91a772093f54ce", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccacts": "zlib@openssh.com,zlib,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccastc": "zlib@openssh.com,zlib,none"} +{"image": "alpine", "imageVersion": "3.7", "sshClient": "dropbear-dbclient","sshClientVersion": "2017.75-r1", "clientIdentificationString": "SSH-2.0-dropbear_2017.75", "hassh": "7742887e2a57712bdb91a772093f54ce", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccacts": "zlib@openssh.com,zlib,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccastc": "zlib@openssh.com,zlib,none"} +{"image": "alpine", "imageVersion": "3.8", "sshClient": "dropbear-dbclient","sshClientVersion": "2018.76-r2", "clientIdentificationString": "SSH-2.0-dropbear_2018.76", "hassh": "e22efe3cde8b396b874c3f13fdb6c61a", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256;zlib@openssh.com,zlib,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-sha2-256", "ccacts": "zlib@openssh.com,zlib,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-sha2-256", "ccastc": "zlib@openssh.com,zlib,none"} +{"image": "ubuntu", "imageVersion": "14.04", "sshClient": "dropbear","sshClientVersion": "2013.60-1ubuntu2", "clientIdentificationString": "SSH-2.0-dropbear_2013.60", "hassh": "22865d7159a8dedcb091cd4fc5fd2841", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccacts": "zlib,zlib@openssh.com,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccastc": "zlib,zlib@openssh.com,none"} +{"image": "ubuntu", "imageVersion": "16.04", "sshClient": "dropbear","sshClientVersion": "2016.72-1", "clientIdentificationString": "SSH-2.0-dropbear_2016.72", "hassh": "7742887e2a57712bdb91a772093f54ce", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccacts": "zlib@openssh.com,zlib,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccastc": "zlib@openssh.com,zlib,none"} +{"image": "ubuntu", "imageVersion": "18.04", "sshClient": "dropbear","sshClientVersion": "2017.75-3build1", "clientIdentificationString": "SSH-2.0-dropbear_2017.75", "hassh": "7742887e2a57712bdb91a772093f54ce", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccacts": "zlib@openssh.com,zlib,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccastc": "zlib@openssh.com,zlib,none"} +{"image": "debian", "imageVersion": "wheezy-slim", "sshClient": "dropbear","sshClientVersion": "2012.55-1.3+deb7u2", "clientIdentificationString": "SSH-2.0-dropbear_2012.55", "hassh": "16f898dd8ed8279e1055350b4e20666c", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1", "ceacts": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccacts": "zlib,zlib@openssh.com,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccastc": "zlib,zlib@openssh.com,none"} +{"image": "debian", "imageVersion": "wheezy-slim", "sshClient": "dropbear","sshClientVersion": "2012.55-1.3", "clientIdentificationString": "SSH-2.0-dropbear_2012.55", "hassh": "16f898dd8ed8279e1055350b4e20666c", "hasshAlgorithms": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none", "hasshVersion": "1.0", "ckex": "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1", "ceacts": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccacts": "zlib,zlib@openssh.com,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccastc": "zlib,zlib@openssh.com,none"} +{"image": "debian", "imageVersion": "jessie-slim", "sshClient": "dropbear","sshClientVersion": "2014.65-1+deb8u3", "clientIdentificationString": "SSH-2.0-dropbear_2014.65", "hassh": "ad00edb0c2a031d9884826ba7b7ba41e", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccacts": "zlib,zlib@openssh.com,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccastc": "zlib,zlib@openssh.com,none"} +{"image": "debian", "imageVersion": "jessie-slim", "sshClient": "dropbear","sshClientVersion": "2014.65-1+deb8u2", "clientIdentificationString": "SSH-2.0-dropbear_2014.65", "hassh": "ad00edb0c2a031d9884826ba7b7ba41e", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc;hmac-sha1-96,hmac-sha1,hmac-md5;zlib,zlib@openssh.com,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccacts": "zlib,zlib@openssh.com,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,3des-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-md5", "ccastc": "zlib,zlib@openssh.com,none"} +{"image": "debian", "imageVersion": "stretch-slim", "sshClient": "dropbear","sshClientVersion": "2016.74-5", "clientIdentificationString": "SSH-2.0-dropbear_2016.74", "hassh": "7742887e2a57712bdb91a772093f54ce", "hasshAlgorithms": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5;zlib@openssh.com,zlib,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccacts": "zlib@openssh.com,zlib,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,twofish256-cbc,twofish-cbc,twofish128-cbc,3des-ctr,3des-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-md5", "ccastc": "zlib@openssh.com,zlib,none"} +{"image": "debian", "imageVersion": "buster-slim", "sshClient": "dropbear","sshClientVersion": "2018.76-4", "clientIdentificationString": "SSH-2.0-dropbear_2018.76", "hassh": "e22efe3cde8b396b874c3f13fdb6c61a", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256;zlib@openssh.com,zlib,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-sha2-256", "ccacts": "zlib@openssh.com,zlib,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-sha2-256", "ccastc": "zlib@openssh.com,zlib,none"} +{"image": "debian", "imageVersion": "sid-slim", "sshClient": "dropbear","sshClientVersion": "2018.76-4", "clientIdentificationString": "SSH-2.0-dropbear_2018.76", "hassh": "e22efe3cde8b396b874c3f13fdb6c61a", "hasshAlgorithms": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au;aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc;hmac-sha1-96,hmac-sha1,hmac-sha2-256;zlib@openssh.com,zlib,none", "hasshVersion": "1.0", "ckex": "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au", "ceacts": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc", "cmacts": "hmac-sha1-96,hmac-sha1,hmac-sha2-256", "ccacts": "zlib@openssh.com,zlib,none", "clcts": "[Empty]", "clstc": "[Empty]", "ceastc": "aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc,3des-ctr,3des-cbc", "cmastc": "hmac-sha1-96,hmac-sha1,hmac-sha2-256", "ccastc": "zlib@openssh.com,zlib,none"} diff --git a/python/hasshGen/hasshgen.py b/python/hasshGen/hasshgen.py new file mode 100644 index 0000000..e69fc93 --- /dev/null +++ b/python/hasshGen/hasshgen.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018, salesforce.com, inc. +# All rights reserved. +# Licensed under the BSD 3-Clause license. +# For full license text, see the LICENSE file in the repo root +# or https://opensource.org/licenses/BSD-3-Clause + +import argparse +import json +import docker +import time +from subprocess import Popen + +__author__ = "Adel '0x4D31' Karimi" +__email__ = "akarimishiraz@salesforce.com" +__version__ = "1.0" +__copyright__ = "Copyright (c) 2018, salesforce.com, inc." +__license__ = "BSD 3-Clause License" + + +# Default command for running hassh.py +HASSH_COMMAND = 'python3 ../hassh.py -i en1 -l json -o fingerprint.json' +# Dockerfiles directory +DOCKERFILE_DIR = 'dockerfiles' + + +def parse_cmd_args(): + """parse command line arguments""" + desc = "A python script to automate building docker images with different\ + SSH clients/versions." + parser = argparse.ArgumentParser(description=(desc)) + helptxt = 'Docker image name. e.g. alpine, ubuntu' + parser.add_argument('-i', '--image', type=str, help=helptxt) + helptxt = 'Docker image version. e.g. 18.04, latest' + parser.add_argument('-iV', '--image_ver', type=str, help=helptxt) + helptxt = 'SSH client name' + parser.add_argument('-c', '--sshclient', type=str, help=helptxt) + helptxt = 'SSH client version' + parser.add_argument('-cV', '--sshclient_ver', type=str, help=helptxt) + helptxt = 'Specify the Dockerfile' + parser.add_argument('-d', '--docker_file', type=str, help=helptxt) + helptxt = 'Specify the server address to test the SSH connection' + parser.add_argument( + '-s', '--server', type=str, required=True, help=helptxt) + helptxt = 'Bulk mode; Specify an input file containing a list of docker\ + image, image version, sshclient and sshclient version' + parser.add_argument('-iF', '--input_file', type=str, help=helptxt) + helptxt = 'Set this option to automatically run hassh.py for capturing SSH\ + client fingerprints (HASSH). Specify the command for running hassh.py\ + using --cmd arg.' + parser.add_argument( + '-f', '--fingerprint', action="store_true", help=helptxt) + helptxt = 'Enter the command for running hassh.py. Use with\ + -f/--fingerprint arg' + parser.add_argument( + '--cmd', type=str, default=HASSH_COMMAND, help=helptxt) + return parser.parse_args() + + +def command_exec(container, server, ssh_client, rm): + """Runs the container and exec SSH command""" + client = docker.DockerClient( + base_url='unix://var/run/docker.sock', + version='auto') + if 'openssh' in ssh_client: + cmd = ('ssh -o UserKnownHostsFile=/dev/null ' + '-o StrictHostKeyChecking=no {}').format(server) + elif 'dropbear' in ssh_client: + cmd = 'dbclient -y {}'.format(server) + elif 'paramiko' in ssh_client: + cmd = 'python /tmp/paramiko_conn.py {}'.format(server) + try: + client.containers.run(container, command=cmd) + except Exception as e: + errorMsg = str(e) + pass + if ('Permission denied' in errorMsg or 'paramiko.ssh_exception' in errorMsg + or 'dbclient: Connection' in errorMsg): + out = "[+] Command successfully executed!" + else: + out = "[-] Error: {}".format(errorMsg) + # Delete the image + if rm: + client.images.remove(image=container, force=True, noprune=True) + + return out + + +def main(): + """Intake arguments from the user to build docker images and initiate SSH + connections for generating client HASSHs""" + args = parse_cmd_args() + tag_id = 0 + tag_name = "hasshgen:{img}{id}" + client = docker.DockerClient( + base_url='unix://var/run/docker.sock', + version='auto') + + if args.input_file: + with open(args.input_file) as file: + input_list = json.load(file) + # Run hassh.py + proc = None + if args.fingerprint and not proc: + proc = Popen(args.cmd, shell=True) + time.sleep(1) + for record in input_list: + # Find the Dockerfile + if record['image'] in ('debian', 'ubuntu'): + docker_file = "{}/Dockerfile.debian".format(DOCKERFILE_DIR) + elif record['image'] in ('centos', 'fedora'): + docker_file = "{}/Dockerfile.centos".format(DOCKERFILE_DIR) + else: + docker_file = "{}/Dockerfile.{}".format( + DOCKERFILE_DIR, + record['image']) + # Build the docker images + tag_id += 1 + container = tag_name.format(img=record['image'], id=tag_id) + try: + output = client.images.build( + path='.', + dockerfile=docker_file, + tag=container, + nocache=True, + rm=True, + forcerm=True, + buildargs={"IMAGE": record['image'], + "IMAGE_VER": record['image_ver'], + "SSHCLIENT": record['sshclient'], + "SSHCLIENT_VER": record['sshclient_ver']}) + # Docker image successfully built + print("[+]", output[0], "successfully built") + print(" - image: {}:{}, ssh client: {} {}".format( + record['image'], record['image_ver'], record['sshclient'], + record['sshclient_ver'])) + # Run the container and exec SSH command + out = command_exec( + container, args.server, record['sshclient'], rm=False) + if out: + print(out) + except Exception as e: + print("[-] Error:", e) + # One more command_exec to make sure all captured (bug) + command_exec(container, args.server, record['sshclient'], rm=True) + # Kill hassh.py + if proc: + proc.kill() + + elif (args.image and args.image_ver and args.sshclient_ver + and args.sshclient): + container = tag_name.format(img=args.image, id=tag_id) + try: + output = client.images.build( + path='.', + dockerfile=args.docker_file, + tag=container, + nocache=True, + rm=True, + forcerm=True, + buildargs={"IMAGE": args.image, + "IMAGE_VER": args.image_ver, + "SSHCLIENT": args.sshclient, + "SSHCLIENT_VER": args.sshclient_ver}) + # Docker image successfully built + print("[+]", output[0], "successfully built") + print(" - image: {}:{}, ssh client: {} {}".format( + args.image, args.image_ver, args.sshclient, args.sshclient_ver)) + # Run hassh.py + proc = None + if args.fingerprint and not proc: + proc = Popen(args.cmd, shell=True) + # Run the container and exec SSH command + time.sleep(1) + out = command_exec( + container, args.server, args.sshclient, rm=False) + time.sleep(1) + # One more command_exec to make sure all captured (bug) + out = command_exec( + container, args.server, args.sshclient, rm=True) + time.sleep(1) + if out: + print(out) + # Kill hassh.py + if proc: + proc.kill() + except Exception as e: + print("[-] Error:", e) + + +if __name__ == '__main__': + main() diff --git a/python/hasshGen/paramiko_conn.py b/python/hasshGen/paramiko_conn.py new file mode 100644 index 0000000..f27dace --- /dev/null +++ b/python/hasshGen/paramiko_conn.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +import paramiko +import sys + +hostname = sys.argv[1] +port = 22 +usr = 'user' +pwd = 'pass' + +try: + client = paramiko.SSHClient() + client.load_system_host_keys() + client.set_missing_host_key_policy(paramiko.WarningPolicy()) + client.connect(hostname, port=port, username=usr, password=pwd) +except paramiko.SSHException as e: + raise diff --git a/python/hasshGen/sshClient_list b/python/hasshGen/sshClient_list new file mode 100644 index 0000000..8296843 --- /dev/null +++ b/python/hasshGen/sshClient_list @@ -0,0 +1,51 @@ +[ +{"image": "alpine", "image_ver": "3.3", "sshclient": "openssh-client", "sshclient_ver": "7.2_p2-r3"}, +{"image": "alpine", "image_ver": "3.4", "sshclient": "openssh-client", "sshclient_ver": "7.2_p2-r5"}, +{"image": "alpine", "image_ver": "3.5", "sshclient": "openssh-client", "sshclient_ver": "7.4_p1-r1"}, +{"image": "alpine", "image_ver": "3.6", "sshclient": "openssh-client","sshclient_ver": "7.5_p1-r2"}, +{"image": "alpine", "image_ver": "3.7", "sshclient": "openssh-client","sshclient_ver": "7.5_p1-r8"}, +{"image": "alpine", "image_ver": "edge", "sshclient": "openssh-client","sshclient_ver": "7.8_p1-r0"}, +{"image": "ubuntu", "image_ver": "14.04", "sshclient": "openssh-client","sshclient_ver": "1:6.6p1-2ubuntu2.10"}, +{"image": "ubuntu", "image_ver": "16.04", "sshclient": "openssh-client","sshclient_ver": "1:7.2p2-4ubuntu2.4"}, +{"image": "ubuntu", "image_ver": "18.04", "sshclient": "openssh-client","sshclient_ver": "1:7.6p1-4"}, +{"image": "ubuntu", "image_ver": "18.10", "sshclient": "openssh-client","sshclient_ver": "1:7.7p1-4"}, +{"image": "debian", "image_ver": "wheezy-slim", "sshclient": "openssh-client","sshclient_ver": "1:6.0p1-4+deb7u7"}, +{"image": "debian", "image_ver": "wheezy-slim", "sshclient": "openssh-client","sshclient_ver": "1:6.0p1-4+deb7u4"}, +{"image": "debian", "image_ver": "wheezy-backports", "sshclient": "openssh-client","sshclient_ver": "1:6.6p1-4~bpo70+1"}, +{"image": "debian", "image_ver": "jessie-slim", "sshclient": "openssh-client","sshclient_ver": "1:6.7p1-5+deb8u7"}, +{"image": "debian", "image_ver": "jessie-slim", "sshclient": "openssh-client","sshclient_ver": "1:6.7p1-5+deb8u4"}, +{"image": "debian", "image_ver": "stretch-slim", "sshclient": "openssh-client","sshclient_ver": "1:7.4p1-10+deb9u4"}, +{"image": "debian", "image_ver": "buster-slim", "sshclient": "openssh-client","sshclient_ver": "1:7.8p1-1"}, +{"image": "debian", "image_ver": "sid-slim", "sshclient": "openssh-client","sshclient_ver": "1:7.8p1-1"}, +{"image": "fedora", "image_ver": "26", "sshclient": "openssh-clients","sshclient_ver": "7.5p1-2.fc26"}, +{"image": "fedora", "image_ver": "27", "sshclient": "openssh-clients","sshclient_ver": "7.5p1-5.fc27"}, +{"image": "fedora", "image_ver": "28", "sshclient": "openssh-clients","sshclient_ver": "7.7p1-2.fc28"}, +{"image": "fedora", "image_ver": "29", "sshclient": "openssh-clients","sshclient_ver": "7.8p1-1.fc29"}, +{"image": "fedora", "image_ver": "rawhide", "sshclient": "openssh-clients","sshclient_ver": "7.8p1-2.fc30"}, +{"image": "centos", "image_ver": "6", "sshclient": "openssh-clients","sshclient_ver": "5.3p1-123.el6_9"}, +{"image": "centos", "image_ver": "7", "sshclient": "openssh-clients","sshclient_ver": "7.4p1-16.el7"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "2.4.1"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "2.3.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "2.2.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "2.1.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "2.0.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "1.18.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "1.17.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "1.16.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "1.15.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "1.14.0"}, +{"image": "python", "image_ver": "3.6-alpine", "sshclient": "paramiko","sshclient_ver": "1.13.0"}, +{"image": "alpine", "image_ver": "3.5", "sshclient": "dropbear-dbclient","sshclient_ver": "2017.75-r0"}, +{"image": "alpine", "image_ver": "3.7", "sshclient": "dropbear-dbclient","sshclient_ver": "2017.75-r1"}, +{"image": "alpine", "image_ver": "3.8", "sshclient": "dropbear-dbclient","sshclient_ver": "2018.76-r2"}, +{"image": "ubuntu", "image_ver": "14.04", "sshclient": "dropbear","sshclient_ver": "2013.60-1ubuntu2"}, +{"image": "ubuntu", "image_ver": "16.04", "sshclient": "dropbear","sshclient_ver": "2016.72-1"}, +{"image": "ubuntu", "image_ver": "18.04", "sshclient": "dropbear","sshclient_ver": "2017.75-3build1"}, +{"image": "debian", "image_ver": "wheezy-slim", "sshclient": "dropbear","sshclient_ver": "2012.55-1.3+deb7u2"}, +{"image": "debian", "image_ver": "wheezy-slim", "sshclient": "dropbear","sshclient_ver": "2012.55-1.3"}, +{"image": "debian", "image_ver": "jessie-slim", "sshclient": "dropbear","sshclient_ver": "2014.65-1+deb8u3"}, +{"image": "debian", "image_ver": "jessie-slim", "sshclient": "dropbear","sshclient_ver": "2014.65-1+deb8u2"}, +{"image": "debian", "image_ver": "stretch-slim", "sshclient": "dropbear","sshclient_ver": "2016.74-5"}, +{"image": "debian", "image_ver": "buster-slim", "sshclient": "dropbear","sshclient_ver": "2018.76-4"}, +{"image": "debian", "image_ver": "sid-slim", "sshclient": "dropbear","sshclient_ver": "2018.76-4"} +] diff --git a/zeek/README.md b/zeek/README.md new file mode 100644 index 0000000..8b1affa --- /dev/null +++ b/zeek/README.md @@ -0,0 +1,94 @@ +# hassh.zeek +[![License: BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) + +## Features +**hassh.zeek** by default will add these fields to your Zeek ssh.log file +- hasshVersion +- hassh, hasshAlgorithms +- hasshServer, hasshServerAlgorithms +- cshka (Client Host Key Algorithms), sshka (Server Host Key Algorithms) +- The script has been tested on Bro 2.5, 2.5.1, 2.5.5, 2.6.0, 2.6.1, 2.6.3, 3.0.0 and 3.1.2 +- Note that Zeek (formerly bro) versions < v2.6.0 had a bug which reversed the Client/server flag , see https://github.com/zeek/zeek/pull/191. The current version of the hassh.zeek script does version checking to deal with these version issues. Failure to update Zeek and not the hassh.zeek script will result in the Server and Client packets being processed incorrectly, in effect swapping around hassh with hasshServer. + +## Installation +Place hassh.zeek in zeek/share/zeek/site/hassh and add this line to your local.zeek script: +```bash +@load ./hassh +``` +If running Zeek >= 3.0.0 or a Zeek product like Corelight, install by using the Zeek Package Manager with this command: +```bash +zkg install hassh +``` + + +## Configuration +**hassh.zeek** by default will add these fields to your Zeek ssh.log file: ```hasshVersion, hassh, hasshAlgorithms, hasshServer and hasshServerAlgorithms, cshka, sshka.``` If you don't want some of these fields to be logged, simply comment those field lines out in each of the locations within hassh.zeek as shown in the code blocks below. +```bash +redef record SSH::Info += { + hasshVersion: string &log &optional; + hassh: string &log &optional; + hasshServer: string &log &optional; + + # ===> Log Client variables <=== # + # Comment out any fields that are not required to be logged in their raw form to ssh.log + #ckex: string &log &optional; + cshka: string &log &optional; + #ceacts: string &log &optional; + #cmacts: string &log &optional; + #ccacts: string &log &optional; + #clcts: string &log &optional; + hasshAlgorithms: string &log &optional; + + # ===> Log Server variables <=== # + # Comment out any fields that are not required to be logged in their raw form to ssh.log + #skex: string &log &optional; + sshka: string &log &optional; + #seastc: string &log &optional; + #smastc: string &log &optional; + #scastc: string &log &optional; + #slstc: string &log &optional; + hasshServerAlgorithms: string &log &optional; +}; +``` +```bash + if ( capabilities$is_server == T ) { + get_hassh(c, capabilities); + c$ssh$hasshVersion = c$hassh$hasshVersion; + c$ssh$hassh = c$hassh$hassh; + + # ===> Log Client variables <=== # + # Comment out any fields that are not required to be logged in their raw form to ssh.log + #c$ssh$ckex = c$hassh$ckex; + c$ssh$cshka = c$hassh$cshka; + #c$ssh$ceacts = c$hassh$ceacts; + #c$ssh$cmacts = c$hassh$cmacts; + #c$ssh$ccacts = c$hassh$ccacts; + #c$ssh$clcts = c$hassh$clcts; + c$ssh$hasshAlgorithms = c$hassh$hasshAlgorithms; + } + if ( capabilities$is_server == F ) { + get_hasshServer(c, capabilities); + c$ssh$hasshVersion = c$hassh$hasshVersion; + c$ssh$hasshServer = c$hassh$hasshServer; + + # ===> Log Server variables <=== # + # Comment out any fields that are not required to be logged in their raw form to ssh.log + #c$ssh$skex = c$hassh$skex; + c$ssh$sshka = c$hassh$sshka; + #c$ssh$seastc = c$hassh$seastc; + #c$ssh$smastc = c$hassh$smastc; + #c$ssh$scastc = c$hassh$scastc; + #c$ssh$slstc = c$hassh$clcts; + c$ssh$hasshServerAlgorithms = c$hassh$hasshServerAlgorithms; + } +``` + +After ammending the Zeek script, don't forget to reload Zeek. +```bash +zeekctl stop +zeekctl install +zeekctl start +``` + +## Credits: +HASSH was conceived and developed by [Ben Reardon](mailto:breardon@salesforce.com) (@benreardon) within the Detection Cloud Team at Salesforce, with inspiration and contributions from [Adel Karimi](mailto:akarimishiraz@salesforce.com) (@0x4d31) and the [JA3 crew](https://github.com/salesforce/ja3/) crew:[John B. Althouse](mailto:jalthouse@salesforce.com) , [Jeff Atkinson](mailto:jatkinson@salesforce.com) and [Josh Atkins](mailto:j.atkins@salesforce.com) diff --git a/zeek/__load__.zeek b/zeek/__load__.zeek new file mode 100644 index 0000000..c8698a1 --- /dev/null +++ b/zeek/__load__.zeek @@ -0,0 +1 @@ +@load ./hassh.zeek diff --git a/zeek/hassh.zeek b/zeek/hassh.zeek new file mode 100644 index 0000000..961b49a --- /dev/null +++ b/zeek/hassh.zeek @@ -0,0 +1,144 @@ +# HASSH # +# SSH Key Initiation Exchange Fingerprinting # +# # +# Script Version: v1.5 22 August 2019 # +# Authors: Ben Reardon (breardon@salesforce.com, @benreardon) # +# : Jeff Atkinson (jatkinson@salesforce.com) # +# : John Althouse (jalthouse@salesforce.com) # +# Description: This Zeek script appends hassh data to ssh.log # +# by enumerating the SSH_MSG_KEXINIT packets sent # +# as clear text between the client and server as part # +# of the negotiation of an SSH connection. # +# # +# Copyright (c) 2018, salesforce.com, inc. # +# All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause # +# For full license text, see the LICENSE file in the repo root or # +# https://opensource.org/licenses/BSD-3-Clause # + + +module SSH; + +export { + type HASSHStorage: record { + hasshVersion:string &log &default="1.1"; # ANY change in hassh/hasshServer composition requires Version update + hassh: string &log &optional &default=""; + hasshServer: string &log &optional &default=""; + + # Client variables # + ckex: string &log &optional &default=""; + cshka: string &log &optional &default=""; + ceacts: string &log &optional &default=""; + cmacts: string &log &optional &default=""; + ccacts: string &log &optional &default=""; + #clcts: string &log &optional &default=""; + hasshAlgorithms: string &log &optional &default=""; + + # Server variables # + skex: string &log &optional &default=""; + sshka: string &log &optional &default=""; + seastc: string &log &optional &default=""; + smastc: string &log &optional &default=""; + scastc: string &log &optional &default=""; + #slstc: string &log &optional &default=""; + hasshServerAlgorithms: string &log &optional &default=""; + }; +} + +redef record connection += { + hassh: HASSHStorage &optional; +}; + +redef record SSH::Info += { + hasshVersion: string &log &optional; + hassh: string &log &optional; + hasshServer: string &log &optional; + + # ===> Log Client variables <=== # + # Comment out any fields that are not required to be logged in their raw form to ssh.log + #ckex: string &log &optional; + cshka: string &log &optional; + #ceacts: string &log &optional; + #cmacts: string &log &optional; + #ccacts: string &log &optional; + #clcts: string &log &optional; + hasshAlgorithms: string &log &optional; + + # ===> Log Server variables <=== # + # Comment out any fields that are not required to be logged in their raw form to ssh.log + #skex: string &log &optional; + sshka: string &log &optional; + #seastc: string &log &optional; + #smastc: string &log &optional; + #scastc: string &log &optional; + #slstc: string &log &optional; + hasshServerAlgorithms: string &log &optional; +}; + + +# Build Client Application fingerprint # +function get_hassh(c:connection, capabilities: SSH::Capabilities ) { + c$hassh = HASSHStorage(); + c$hassh$ckex = join_string_vec(capabilities$kex_algorithms,","); + c$hassh$ceacts = join_string_vec(capabilities$encryption_algorithms$client_to_server,","); + c$hassh$cmacts = join_string_vec(capabilities$mac_algorithms$client_to_server,","); + c$hassh$ccacts = join_string_vec(capabilities$compression_algorithms$client_to_server,","); + c$hassh$cshka = join_string_vec(capabilities$server_host_key_algorithms,","); # The Host key algorithm set may be useful information by itself but is not included in the hassh. + #c$hassh$clcts = join_string_vec(capabilities$languages$client_to_server,","); # The Languages field may be useful information by itself but is not included in the hasshServer. + c$hassh$hasshAlgorithms = string_cat(c$hassh$ckex,";",c$hassh$ceacts,";",c$hassh$cmacts,";",c$hassh$ccacts); # Contatenate the four selected lists of algorithms (Key,Enc,MAC,Compression) to build the Client hash + c$hassh$hassh = md5_hash(c$hassh$hasshAlgorithms); +} + +# Build Server Application fingerprint # +function get_hasshServer(c:connection, capabilities: SSH::Capabilities ) { + c$hassh = HASSHStorage(); + c$hassh$skex = join_string_vec(capabilities$kex_algorithms,","); + c$hassh$seastc = join_string_vec(capabilities$encryption_algorithms$server_to_client,","); + c$hassh$smastc = join_string_vec(capabilities$mac_algorithms$server_to_client,","); + c$hassh$scastc = join_string_vec(capabilities$compression_algorithms$server_to_client,","); + c$hassh$sshka = join_string_vec(capabilities$server_host_key_algorithms,","); # The Host key algorithm set may be useful information by itself but is not included in the hasshServer. + #c$hassh$slstc = join_string_vec(capabilities$languages$server_to_client,","); # The Languages field may be useful information by itself but is not included in the hasshServer. + c$hassh$hasshServerAlgorithms = string_cat(c$hassh$skex,";",c$hassh$seastc,";",c$hassh$smastc,";",c$hassh$scastc); # Contatenate the four selected lists of algorithms (Key,Enc,Message,Compression) to build the Server hash + c$hassh$hasshServer = md5_hash(c$hassh$hasshServerAlgorithms); +} + +# Event # +event ssh_capabilities(c: connection, cookie: string, capabilities: SSH::Capabilities) { + if ( !c?$ssh ) {return;} + c$hassh = HASSHStorage(); + + # Prior to 2.6.0 Zeek has a bug which it reverses the Client/server flag. + # See https://github.com/zeek/zeek/pull/191 + # The "if" statements here do a version check to account for this bug in versions older than 2.6.0 + + if ((Version::info$version_number < 20600 && capabilities$is_server == T) || (Version::info$version_number >= 20600 && capabilities$is_server == F) ) { + get_hassh(c, capabilities); + c$ssh$hasshVersion = c$hassh$hasshVersion; + c$ssh$hassh = c$hassh$hassh; + + # ===> Log Client variables <=== # + # Comment out any fields that are not required to be logged in their raw form to ssh.log + #c$ssh$ckex = c$hassh$ckex; + c$ssh$cshka = c$hassh$cshka; + #c$ssh$ceacts = c$hassh$ceacts; + #c$ssh$cmacts = c$hassh$cmacts; + #c$ssh$ccacts = c$hassh$ccacts; + #c$ssh$clcts = c$hassh$clcts; + c$ssh$hasshAlgorithms = c$hassh$hasshAlgorithms; + } + if ( (Version::info$version_number < 20600 && capabilities$is_server == F) || (Version::info$version_number >= 20600 && capabilities$is_server == T) ) { + get_hasshServer(c, capabilities); + c$ssh$hasshVersion = c$hassh$hasshVersion; + c$ssh$hasshServer = c$hassh$hasshServer; + + # ===> Log Server variables <=== # + # Comment out any fields that are not required to be logged in their raw form to ssh.log + #c$ssh$skex = c$hassh$skex; + c$ssh$sshka = c$hassh$sshka; + #c$ssh$seastc = c$hassh$seastc; + #c$ssh$smastc = c$hassh$smastc; + #c$ssh$scastc = c$hassh$scastc; + #c$ssh$slstc = c$hassh$clcts; + c$ssh$hasshServerAlgorithms = c$hassh$hasshServerAlgorithms; + } +} diff --git a/zkg.meta b/zkg.meta new file mode 100644 index 0000000..3f56b19 --- /dev/null +++ b/zkg.meta @@ -0,0 +1,5 @@ +[package] +script_dir = zeek +description = HASSH is used to identify specific Client and Server SSH implementations. The fingerprints can be stored, searched and shared in the form of an MD5 fingerprint. This package logs components to ssh.log +tags = zeek plugin, ssh, fingerprint, logging +version = 1.0