besecure.rb 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. #
  2. # This plugin provides integration with beSECURE. Written by Noam Rathaus.
  3. #
  4. # Distributed under MIT license:
  5. # http://www.opensource.org/licenses/mit-license.php
  6. #
  7. # Version 10.5.17
  8. require 'base64'
  9. require 'zlib'
  10. require 'tempfile'
  11. require 'pathname'
  12. module Msf
  13. class Plugin::BeSECURE < Msf::Plugin
  14. class BeSECURECommandDispatcher
  15. include Msf::Ui::Console::CommandDispatcher
  16. def name
  17. 'beSECURE'
  18. end
  19. def commands
  20. {
  21. 'besecure_help' => 'Displays help',
  22. 'besecure_version' => 'Display the version of the beSECURE server',
  23. 'besecure_apikey' => 'Set the beSECURE API Key',
  24. 'besecure_hostname' => 'Set the beSECURE Hostname',
  25. 'besecure_debug' => 'Enable/Disable debugging',
  26. 'besecure_ssl_verify' => 'Enable/Disable SSL verification',
  27. 'besecure_report_list' => 'Display list of reports',
  28. 'besecure_report_download' => 'Save a report to disk',
  29. 'besecure_report_import' => 'Import report specified by ID into framework'
  30. }
  31. end
  32. def cmd_besecure_help
  33. print_status('besecure_help Display this help')
  34. print_status('besecure_debug Enable/Disable debugging')
  35. print_status('besecure_version Display the version of the beSECURE server')
  36. print_status('besecure_apikey Set the beSECURE API Key')
  37. print_status('besecure_ssl_verify Set whether to verify or not SSL')
  38. print_status('besecure_hostname Set the beSECURE Hostname')
  39. print_status
  40. print_status('REPORTS')
  41. print_status('=======')
  42. print_status('besecure_report_list Lists reports')
  43. print_status('besecure_report_download Downloads an beSECURE report specified by ID')
  44. print_status('besecure_report_import Import report specified by ID into framework')
  45. end
  46. # Verify the database is connected and usable
  47. def database?
  48. if !(framework.db && framework.db.usable)
  49. return false
  50. else
  51. return true
  52. end
  53. end
  54. # Verify correct number of arguments and verify -h was not given. Return
  55. # true if correct number of arguments and help was not requested.
  56. def args?(args, min = 1, max = nil)
  57. if !max then max = min end
  58. if ((args.length < min) || (args.length > max) || (args[0] == '-h'))
  59. return false
  60. end
  61. return true
  62. end
  63. #--------------------------
  64. # Basic Functions
  65. #--------------------------
  66. def cmd_besecure_hostname(*args)
  67. if args?(args)
  68. @hostname = args[0]
  69. print_good(@hostname)
  70. else
  71. print_status('Usage:')
  72. print_status('besecure_hostname string')
  73. end
  74. end
  75. def cmd_besecure_apikey(*args)
  76. if args?(args)
  77. @apikey = args[0]
  78. print_good(@apikey)
  79. else
  80. print_status('Usage:')
  81. print_status('besecure_apikey string')
  82. end
  83. end
  84. def cmd_besecure_ssl_verify(*args)
  85. if args?(args)
  86. @ssl_verify = args[0]
  87. if (@ssl_verify != 'yes') && (@ssl_verify != 'no')
  88. @ssl_verify = 'yes'
  89. end
  90. print_good(@ssl_verify)
  91. else
  92. print_status('Usage:')
  93. print_status("besecure_ssl_verify 'yes'/'no' (default is yes)")
  94. end
  95. end
  96. def cmd_besecure_debug(*args)
  97. if args?(args)
  98. @debug = args[0].to_i
  99. print_good(@debug)
  100. else
  101. print_status('Usage:')
  102. print_status('besecure_debug integer')
  103. end
  104. end
  105. def cmd_besecure_version
  106. req = Net::HTTP::Post.new('/json.cgi', { 'Host' => @hostname })
  107. req.set_form_data({ 'apikey' => @apikey, 'primary' => 'interface' })
  108. if @debug
  109. print_status(req.body)
  110. end
  111. http = Net::HTTP.new(@hostname, 443)
  112. if @debug
  113. http.set_debug_output($stdout) # Logger.new("foo.log") works too
  114. end
  115. http.use_ssl = true
  116. if @ssl_verify == 'no'
  117. http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  118. end
  119. res = http.start { |h| h.request(req) }
  120. unless res
  121. print_error("#{@hostname} - Connection timed out")
  122. return ''
  123. end
  124. body = ''
  125. begin
  126. body = JSON.parse(res.body)
  127. rescue JSON::ParserError
  128. print_error("#{@hostname} - Unable to parse the response")
  129. return ''
  130. end
  131. if body['error']
  132. print_error("#{@hostname} - An error occurred:")
  133. print_error(body)
  134. return ''
  135. end
  136. print_good(body['version'])
  137. end
  138. #--------------------------
  139. # Report Functions
  140. #--------------------------
  141. def cmd_besecure_report_list(*_args)
  142. tbl = Rex::Text::Table.new(
  143. 'Columns' => ['ID', 'Name', 'Hosts']
  144. )
  145. if @hostname.empty?
  146. print_error('Missing host value')
  147. return ''
  148. end
  149. req = Net::HTTP::Post.new('/json.cgi', { 'Host' => @hostname })
  150. req.set_form_data({ 'apikey' => @apikey, 'primary' => 'admin', 'secondary' => 'networks', 'action' => 'returnnetworks', 'search_limit' => 10000 })
  151. if @debug
  152. print_status(req.body)
  153. end
  154. http = Net::HTTP.new(@hostname, 443)
  155. if @debug
  156. http.set_debug_output($stdout) # Logger.new("foo.log") works too
  157. end
  158. http.use_ssl = true
  159. if @ssl_verify == 'no'
  160. http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  161. end
  162. res = http.start { |h| h.request(req) }
  163. unless res
  164. print_error("#{@hostname} - Connection timed out")
  165. return ''
  166. end
  167. body = ''
  168. begin
  169. body = JSON.parse(res.body)
  170. rescue JSON::ParserError
  171. print_error("#{@hostname} - Unable to parse the response")
  172. return ''
  173. end
  174. if body['error']
  175. print_error("#{@hostname} - An error occurred:")
  176. print_error(body)
  177. return ''
  178. end
  179. data = body['data']
  180. data.each do |item|
  181. tbl << [ item['ID'], item['Name'], item['PrettyRange']]
  182. end
  183. # print_good(body)
  184. print_good('beSECURE list of reports')
  185. print_line
  186. print_line tbl.to_s
  187. print_line
  188. end
  189. def cmd_besecure_report_download(*args)
  190. if args?(args, 4)
  191. req = Net::HTTP::Post.new('/json.cgi', { 'Host' => @hostname })
  192. format_file = args[1]
  193. req.set_form_data({ 'apikey' => @apikey, 'primary' => 'vulnerabilities', 'secondary' => 'report', 'action' => 'getreport', 'network' => args[0], 'format' => format_file })
  194. http = Net::HTTP.new(@hostname, 443)
  195. if @debug
  196. http.set_debug_output($stdout) # Logger.new("foo.log") works too
  197. end
  198. http.use_ssl = true
  199. if @ssl_verify == 'no'
  200. http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  201. end
  202. res = http.start { |h| h.request(req) }
  203. unless res
  204. print_error("#{@hostname} - Connection timed out")
  205. return ''
  206. end
  207. body = ''
  208. begin
  209. body = JSON.parse(res.body)
  210. rescue JSON::ParserError
  211. print_error("#{@hostname} - Unable to parse the response")
  212. return ''
  213. end
  214. if body['error']
  215. print_error("#{@hostname} - An error occurred:")
  216. print_error(body)
  217. return ''
  218. end
  219. decompressed = ''
  220. if format_file != 'json'
  221. compressed_base64 = body['compresseddata']
  222. compressed = Base64.decode64(compressed_base64)
  223. decompressed = Zlib::Inflate.inflate(compressed)
  224. else
  225. decompressed = body
  226. end
  227. if @debug
  228. print_status(decompressed)
  229. end
  230. ::FileUtils.mkdir_p(args[2])
  231. name = ::File.join(args[2], args[3])
  232. print_status("Saving report to #{name}")
  233. output = ::File.new(name, 'w')
  234. output.puts(decompressed)
  235. output.close
  236. ###
  237. # Return the report
  238. return decompressed
  239. else
  240. print_status('Usage: besecure_report_download <network_id> <format_name> <path> <report_name>')
  241. end
  242. return ''
  243. end
  244. def cmd_besecure_report_import(*args)
  245. if args?(args, 2)
  246. if !database?
  247. print_error('Database not ready')
  248. return ''
  249. end
  250. tempfile = Tempfile.new('results')
  251. res = cmd_besecure_report_download(args[0], 'nbe', File.dirname(tempfile) + '/', File.basename(tempfile))
  252. if res.empty?
  253. print_error('An empty report has been received')
  254. return ''
  255. end
  256. print_status('Importing report to database.')
  257. framework.db.import_file({ filename: tempfile })
  258. tempfile.unlink
  259. else
  260. print_status('Usage: besecure_report_import <network_id> <format_name>')
  261. print_status('Only the NBE and XML formats are supported for importing.')
  262. end
  263. end
  264. end
  265. #------------------------------
  266. # Plugin initialization
  267. #------------------------------
  268. def initialize(framework, opts)
  269. super
  270. add_console_dispatcher(BeSECURECommandDispatcher)
  271. print_status('Welcome to beSECURE integration by Noam Rathaus.')
  272. print_status
  273. print_status('beSECURE integration requires a database connection. Once the ')
  274. print_status('database is ready, connect to the beSECURE server using besecure_connect.')
  275. print_status('For additional commands use besecure_help.')
  276. print_status
  277. @debug = nil
  278. end
  279. def cleanup
  280. remove_console_dispatcher('beSECURE')
  281. end
  282. def name
  283. 'beSECURE'
  284. end
  285. def desc
  286. 'Integrates with the beSECURE - open source vulnerability management'
  287. end
  288. end
  289. end