New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added check and response for CVE-2017-12149 in jboss_vulnscan.rb #10352

Merged
merged 3 commits into from Nov 20, 2018

Conversation

Projects
None yet
4 participants
@timoles
Contributor

timoles commented Jul 20, 2018

This change adds an additional vulnerability check to auxiliary/scanner/http/jboss_vulnscan
The addition was a check for CVE-2017-12149, a deserialization RCE vulnerability in Red Hat JBoss EAP 5.

It was found that the doFilter method in the ReadOnlyAccessFilter of the HTTP Invoker does not restrict classes for which it performs deserialization. This allows an attacker to execute arbitrary code via crafted serialized data.

Changes made:
Added the URL to check
print_good() in case of the URL is accessible

Verification

List the steps needed to make sure this thing works

  • Start msfconsole
  • use auxiliary/scanner/http/jboss_vulnscan
  • set Host of a vulnerable JBoss EAP5 server
  • *Verify [+] 192.168.0.244:8080 /invoker/readonly responded (500) is displayed
  • set Host of a not vulnerable JBoss server version
  • Verify [*] 192.168.0.244:8080 /invoker/readonly not found (404) is displayed
@bcoles

This comment has been minimized.

Contributor

bcoles commented Jul 21, 2018

I know it's an issue with the original module, rather than your update, however, rather than wrapping everything in a conditional like this:

  def check_app(app)
    res = send_request_cgi({
      'uri'       => app,
      'method'    => 'GET',
      'ctype'     => 'text/plain'
    })

    if res
      case
      when res.code == 200
        print_good("#{rhost}:#{rport} #{app} does not require authentication (200)")
      when res.code == 403
        print_status("#{rhost}:#{rport} #{app} restricted (403)")
      when res.code == 401
        print_status("#{rhost}:#{rport} #{app} requires authentication (401): #{res.headers['WWW-Authenticate']}")
        bypass_auth(app)
        basic_auth_default_creds(app)
      when res.code == 404
        print_status("#{rhost}:#{rport} #{app} not found (404)")
      when res.code == 301, res.code == 302
        print_status("#{rhost}:#{rport} #{app} is redirected (#{res.code}) to #{res.headers['Location']} (not following)")
      else
        if res.code == 500 && app == "/invoker/readonly"
          print_good("#{rhost}:#{rport} #{app} responded (#{res.code})")
        end
        print_status("#{rhost}:#{rport} Don't know how to handle response code #{res.code}")
      end
    else
      print_status("#{rhost}:#{rport} #{app} not found")
    end
  end

This is better:

  def check_app(app)
    res = send_request_cgi({
      'uri'       => app,
      'method'    => 'GET',
      'ctype'     => 'text/plain'
    })

    unless res
      print_status("#{rhost}:#{rport} #{app} not found")
      return
    end

    case
    when res.code == 200
      print_good("#{rhost}:#{rport} #{app} does not require authentication (200)")
    when res.code == 403
      print_status("#{rhost}:#{rport} #{app} restricted (403)")
    when res.code == 401
      print_status("#{rhost}:#{rport} #{app} requires authentication (401): #{res.headers['WWW-Authenticate']}")
      bypass_auth(app)
      basic_auth_default_creds(app)
    when res.code == 404
      print_status("#{rhost}:#{rport} #{app} not found (404)")
    when res.code == 301, res.code == 302
      print_status("#{rhost}:#{rport} #{app} is redirected (#{res.code}) to #{res.headers['Location']} (not following)")
    else
      if res.code == 500 && app == "/invoker/readonly"
        print_good("#{rhost}:#{rport} #{app} responded (#{res.code})")
      end
      print_status("#{rhost}:#{rport} Don't know how to handle response code #{res.code}")
    end
  end
Timo
@timoles

This comment has been minimized.

Contributor

timoles commented Jul 23, 2018

Thanks for taking the time for the code improvement suggestions. They are now implemented.

Update jboss_vulnscan.rb
Fixed a paste error, or sneaked in character in the app url.

@space-r7 space-r7 self-assigned this Nov 16, 2018

@space-r7

This comment has been minimized.

Contributor

space-r7 commented Nov 20, 2018

I tested the changes on versions 5.2 and 7.1. Here's the output for the instances:

5.2

msf5 auxiliary(scanner/http/jboss_vulnscan) > set rhosts 172.16.215.181
rhosts => 172.16.215.181
msf5 auxiliary(scanner/http/jboss_vulnscan) > set rport 8080
rport => 8080
msf5 auxiliary(scanner/http/jboss_vulnscan) > run

[*] Apache-Coyote/1.1 ( Powered by Servlet 2.5; JBoss-5.0/JBossWeb-2.1 )
[-] 172.16.215.181:8080 JBoss error message: JBoss Web/2.1.13.GA-patch-01 - Error report
[*] 172.16.215.181:8080 Checking http...
[*] 172.16.215.181:8080 /jmx-console/HtmlAdaptor requires authentication (401): Basic realm="JBoss JMX Console"
...
[*] 172.16.215.181:8080 Could not get authentication bypass via HTTP verb tampering
[*] 172.16.215.181:8080 Could not guess admin credentials
[+] 172.16.215.181:8080 /invoker/readonly responded (500)
[*] 172.16.215.181:8080 Checking for JBoss AS default creds
[*] 172.16.215.181:8080 Could not guess admin credentials
[*] 172.16.215.181:8080 Checking services...
[*] 172.16.215.181:8080 Naming Service tcp/1098: open
[*] 172.16.215.181:8080 Naming Service tcp/1099: open
[*] 172.16.215.181:8080 RMI invoker tcp/4444: open
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/http/jboss_vulnscan) > 

7.1

msf5 auxiliary(scanner/http/jboss_vulnscan) > run

[*] JBoss-EAP/7 ( Powered by Undertow/1 )
[*] 172.16.215.181:8080 Checking http...
[*] 172.16.215.181:8080 /jmx-console/HtmlAdaptor not found (404)
[*] 172.16.215.181:8080 /status not found (404)
[*] 172.16.215.181:8080 /web-console/ServerInfo.jsp not found (404)
[*] 172.16.215.181:8080 /web-console/Invoker not found (404)
[*] 172.16.215.181:8080 /invoker/JMXInvokerServlet not found (404)
[*] 172.16.215.181:8080 /invoker/readonly not found (404)
[*] 172.16.215.181:8080 Checking for JBoss AS default creds
[*] 172.16.215.181:8080 Could not guess admin credentials
[*] 172.16.215.181:8080 Checking services...
[*] 172.16.215.181:8080 Naming Service tcp/1098: closed
[*] 172.16.215.181:8080 Naming Service tcp/1099: closed
[*] 172.16.215.181:8080 RMI invoker tcp/4444: closed
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/http/jboss_vulnscan) > 

@space-r7 space-r7 merged commit aaf664d into rapid7:master Nov 20, 2018

3 checks passed

Metasploit Automation - Sanity Test Execution Successfully completed all tests.
Details
Metasploit Automation - Test Execution Successfully completed all tests.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

space-r7 added a commit that referenced this pull request Nov 20, 2018

msjenkins-r7 added a commit that referenced this pull request Nov 20, 2018

@space-r7

This comment has been minimized.

Contributor

space-r7 commented Nov 20, 2018

Release Notes

This adds an additional vulnerability check to the jboss_vulnscan auxiliary module. The module now checks for a deserialization RCE vulnerability referenced in CVE-2017-12149.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment