You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.rb 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. require 'socket'
  2. module CryptCheck
  3. module Ssh
  4. class Server
  5. TCP_TIMEOUT = 10
  6. class SshNotAvailableException < Exception
  7. end
  8. attr_reader :ip, :port, :hostname, :kex, :encryption, :hmac, :compression, :key
  9. KEX = {
  10. 'curve25519-sha256@libssh.org' => :green,
  11. 'ecdh-sha2-nistp521' => nil, # NIST
  12. 'ecdh-sha2-nistp384' => nil, # NIST
  13. 'ecdh-sha2-nistp256' => nil, # NIST
  14. 'diffie-hellman-group-exchange-sha256' => :green, # DLP (PFS)
  15. 'diffie-hellman-group-exchange-sha1' => :yellow, # DLP (PFS)
  16. 'diffie-hellman-group14-sha1' => :yellow, # 2048 bits < 3072 bits
  17. 'diffie-hellman-group1-sha1' => :red # 768 bits < 1024 bits
  18. }
  19. ENCRYPTION = {
  20. 'chacha20-poly1305@openssh.com' => :green,
  21. 'aes256-gcm@openssh.com' => :green,
  22. 'aes128-gcm@openssh.com' => :green,
  23. 'aes256-ctr' => nil, # CTR < GCM
  24. 'aes192-ctr' => nil, # CTR < GCM
  25. 'aes128-ctr' => nil, # CTR < GCM
  26. 'aes256-cbc' => :yellow, # CBC
  27. 'aes192-cbc' => :yellow, # CBC
  28. 'aes128-cbc' => :yellow, # CBC
  29. 'blowfish-cbc' => :yellow, # CBC
  30. 'cast128-cbc' => :yellow, # CBC
  31. '3des-cbc' => :red, # 3DES
  32. 'arcfour' => :red, # RC4
  33. 'arcfour128' => :red, # RC4
  34. 'arcfour256' => :red # RC4
  35. }
  36. HMAC = {
  37. 'hmac-sha2-512-etm@openssh.com' => :green,
  38. 'hmac-sha2-256-etm@openssh.com' => :green,
  39. 'hmac-sha2-512' => nil,
  40. 'hmac-sha2-256' => nil,
  41. 'hmac-sha1-etm@openssh.com' => :green,
  42. 'hmac-sha1' => nil,
  43. 'hmac-sha1-96-etm@openssh.com' => :red, # EXPORT
  44. 'hmac-sha1-96' => :red, # EXPORT
  45. 'hmac-ripemd160-etm@openssh.com' => :green,
  46. 'hmac-ripemd160' => nil,
  47. 'hmac-md5-etm@openssh.com' => :red, # MD5
  48. 'hmac-md5' => :red, # MD5
  49. 'hmac-md5-96-etm@openssh.com' => :red, # MD5 + EXPORT
  50. 'hmac-md5-96' => :red, # MD5 + EXPORT
  51. 'umac-128-etm@openssh.com' => :green,
  52. 'umac-128@openssh.com' => nil,
  53. 'umac-64-etm@openssh.com' => :red, # < 128 bits
  54. 'umac-64@openssh.com' => :red # < 128 bits
  55. }
  56. COMPRESSION = {
  57. 'none' => nil,
  58. 'zlib@openssh.com' => nil
  59. }
  60. KEY = {
  61. 'ssh-ed25519' => :green,
  62. 'ssh-ed25519-cert-v01@openssh.com' => :green,
  63. 'ecdsa-sha2-nistp256' => nil, # NIST
  64. 'ecdsa-sha2-nistp384' => nil, # NIST
  65. 'ecdsa-sha2-nistp521' => nil, # NIST
  66. 'ssh-rsa' => :yellow, # RSA
  67. 'ssh-dss' => :red, # DSA
  68. 'ecdsa-sha2-nistp256-cert-v01@openssh.com' => nil, # NIST
  69. 'ecdsa-sha2-nistp384-cert-v01@openssh.com' => nil, # NIST
  70. 'ecdsa-sha2-nistp521-cert-v01@openssh.com' => nil, # NIST
  71. 'ssh-rsa-cert-v01@openssh.com' => :yellow, # RSA
  72. 'ssh-rsa-cert-v00@openssh.com' => :yellow, # RSA
  73. 'ssh-dss-cert-v01@openssh.com' => :red, # DSA
  74. 'ssh-dss-cert-v00@openssh.com' => :red, # DSA
  75. }
  76. def initialize(ip, port=22, hostname:)
  77. @ip, @port, @hostname = ip, port, hostname
  78. Logger.info { name.colorize :blue }
  79. kex = ::Socket.tcp ip, port, connect_timeout: TCP_TIMEOUT do |socket|
  80. socket.readline
  81. socket.write "SSH-2.0-CryptCheck\r\n"
  82. Packet.read_kex_init socket
  83. end
  84. @kex, @encryption, @hmac, @compression, @key = kex[:kex], kex[:encryption], kex[:mac], kex[:compression], kex[:host_key]
  85. Logger.info { '' }
  86. @kex.each { |k| Logger.info { "Key exchange : #{k.colorize KEX[k]}" } }
  87. Logger.info { '' }
  88. @encryption.each { |e| Logger.info { "Encryption : #{e.colorize ENCRYPTION[e]}" } }
  89. Logger.info { '' }
  90. @hmac.each { |h| Logger.info { "HMAC : #{h.colorize HMAC[h]}" } }
  91. Logger.info { '' }
  92. @compression.each { |c| Logger.info { "Compression : #{c}" } }
  93. Logger.info { '' }
  94. @key.each { |k| Logger.info { "Key type : #{k.colorize KEY[k]}" } }
  95. rescue => e
  96. Logger.debug { "SSH not supported : #{e}" }
  97. raise SshNotAvailableException, e
  98. end
  99. private
  100. def name
  101. name = "#{@hostname || @ip}:#@port"
  102. name += " [#@ip]" if @hostname
  103. name
  104. end
  105. end
  106. end
  107. end