description = [[ Detects Ruby on Rails servers vulnerable to object injection, remote command executions and denial of service attacks. (CVE-2013-0156) All Ruby on Rails versions before 2.3.15, 3.0.x before 3.0.19, 3.1.x before 3.1.10, and 3.2.x before 3.2.11 are vulnerable. This script sends 3 harmless YAML payloads to detect vulnerable installations. If the malformed object receives a status 500 response, the server is processing YAML objects and therefore is likely vulnerable. References: * https://community.rapid7.com/community/metasploit/blog/2013/01/10/exploiting-ruby-on-rails-with-metasploit-cve-2013-0156', * https://groups.google.com/forum/?fromgroups=#!msg/rubyonrails-security/61bkgvnSGTQ/nehwjA8tQ8EJ', * http://cvedetails.com/cve/2013-0156/ ]] --- -- @usage -- nmap -sV --script http-vuln-cve2013-0156 -- nmap -sV --script http-vuln-cve2013-0156 --script-args uri="/test/" -- -- @output -- PORT STATE SERVICE REASON -- 80/tcp open http syn-ack -- | http-vuln-cve2013-0156: -- | VULNERABLE: -- | Parameter parsing vulnerabilities in several versions of Ruby on Rails allow object injection, remote command execution and Denial Of Service attacks (CVE-2013-0156) -- | State: VULNERABLE -- | Risk factor: High -- | Description: -- | All Ruby on Rails versions before 2.3.15, 3.0.x before 3.0.19, 3.1.x before 3.1.10, and 3.2.x before 3.2.11 are vulnerable to object injection, remote command execution and denial of service attacks. -- | The attackers don't need to be authenticated to exploit these vulnerabilities. -- | -- | References: -- | https://groups.google.com/forum/?fromgroups=#!msg/rubyonrails-security/61bkgvnSGTQ/nehwjA8tQ8EJ -- | https://community.rapid7.com/community/metasploit/blog/2013/01/10/exploiting-ruby-on-rails-with-metasploit-cve-2013-0156 -- |_ http://cvedetails.com/cve/2013-0156/ -- -- @args http-vuln-cve2013-0156.uri Basepath URI (default: /). --- -- TODO: -- * Add argument to exploit cmd exec vuln author = "Paulino Calderon " license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"exploit","vuln"} local http = require "http" local shortport = require "shortport" local stdnse = require "stdnse" local vulns = require "vulns" portrule = shortport.http local PAYLOAD_OK = [=[ ]=] local PAYLOAD_TIME = [=[ ]=] local PAYLOAD_MALFORMED = [=[ ]=] --- --detect(host, port, uri) --Sends 3 payloads where one of them is malformed. Status 500 indicates that yaml parsing is enabled. --- local function detect(host, port, uri) local opts = {header={}} opts["header"]["Content-type"] = 'application/xml' local req_ok = http.post(host, port, uri, opts, nil, PAYLOAD_OK) local req_time = http.post(host, port, uri, opts, nil, PAYLOAD_TIME) stdnse.debug2("First request returned status %d. Second request returned status %d", req_ok.status, req_time.status) if req_ok.status == 200 and req_time.status == 200 then local req_malformed = http.post(host, port, uri, opts, nil, PAYLOAD_MALFORMED) stdnse.debug2("Malformed request returned status %d", req_malformed.status) if req_malformed.status == 500 then return true end end return false end --- --MAIN action = function(host, port) local uri = stdnse.get_script_args(SCRIPT_NAME..".uri") or "/" local vuln_table = { title = "Parameter parsing vulnerabilities in several versions of Ruby on Rails allow object injection, remote command execution and Denial Of Service attacks (CVE-2013-0156)", state = vulns.STATE.NOT_VULN, risk_factor = "High", description = [[ All Ruby on Rails versions before 2.3.15, 3.0.x before 3.0.19, 3.1.x before 3.1.10, and 3.2.x before 3.2.11 are vulnerable to object injection, remote command execution and denial of service attacks. The attackers don't need to be authenticated to exploit these vulnerabilities. ]], references = { 'https://community.rapid7.com/community/metasploit/blog/2013/01/10/exploiting-ruby-on-rails-with-metasploit-cve-2013-0156', 'https://groups.google.com/forum/?fromgroups=#!msg/rubyonrails-security/61bkgvnSGTQ/nehwjA8tQ8EJ', 'http://cvedetails.com/cve/2013-0156/', } } if detect(host,port,uri) then stdnse.debug1("Received status 500 as expected in vulnerable installations. Marking as vulnerable...") vuln_table.state = vulns.STATE.VULN local report = vulns.Report:new(SCRIPT_NAME, host, port) return report:make_output(vuln_table) end return nil end