├── .gitignore ├── README.md ├── http-apache-server-status.nse └── http-rails-xml-parser.nse /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .AppleDouble 3 | .LSOverride 4 | Icon 5 | ._* 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nmap NSE Scripts 2 | 3 | **A collection of [Nmap NSE scripts](http://nmap.org/nsedoc/) that I made.** 4 | 5 | ## Scripts: 6 | 7 | ### http-rails-xml-parser 8 | This script sends a specially crafted XML body in a POST request to any detected web services to see if it is a Ruby on Rails server 9 | that is vulnerable to the recently discovered [CVE-2013-0156](https://groups.google.com/forum/#!topic/rubyonrails-security/61bkgvnSGTQ/discussion) bug. 10 | 11 | **Usage:** 12 | 13 | $ nmap -sV --script http-rails-xml-parser 14 | 15 | ---- 16 | 17 | ### http-apache-server-status 18 | This script checks if a web server is serving the Apache Server Status page which might contain a lot of interesting information. Daniel Cid did some 19 | research and found big sites having the server-status page wide open to the public. [Read more about it here](http://blog.sucuri.net/2012/10/popular-sites-with-apache-server-status-enabled.html). 20 | 21 | **Usage:** 22 | 23 | $ nmap -sV --script http-apache-server-status -------------------------------------------------------------------------------- /http-apache-server-status.nse: -------------------------------------------------------------------------------- 1 | description = [[ 2 | Checks if a web server is serving the Apache Server Status page which can contain a lot of interesting 3 | information such as Apache version, CPU usage, uptime and the latest requests. 4 | 5 | Daniel Cid did some research and found sites such as php.net, cloudfare.com, disney.com, ford.com and cisco.com 6 | having the /server-status page wide open to the public. 7 | 8 | Read more about his findings here: http://blog.sucuri.net/2012/10/popular-sites-with-apache-server-status-enabled.html 9 | 10 | To see how a server status page looks: http://www.apache.org/server-status 11 | ]] 12 | 13 | --- 14 | -- @usage 15 | -- nmap -sV --script http-apache-server-status 16 | -- 17 | -- @output 18 | -- PORT STATE SERVICE 19 | -- 80/tcp open http 20 | -- | Apache Server Status page is available and might contain juicy info. (/server-status) 21 | 22 | author = "Michael Henriksen" 23 | license = "Same as Nmap--See http://nmap.org/book/man-legal.html" 24 | categories = {"safe", "discovery"} 25 | 26 | local http = require "http" 27 | local shortport = require "shortport" 28 | local stdnse = require "stdnse" 29 | local openssl = stdnse.silent_require "openssl" 30 | 31 | portrule = shortport.http 32 | 33 | action = function(host, port) 34 | local response = http.get(host, port, "/server-status") 35 | 36 | if response.status == 200 and string.match(response.body, "Apache Status") then 37 | return "Apache Server Status page is available and might contain juicy info. (/server-status)" 38 | else 39 | stdnse.print_debug(1, "GET /server-status returned " .. response['status-line']) 40 | end 41 | end -------------------------------------------------------------------------------- /http-rails-xml-parser.nse: -------------------------------------------------------------------------------- 1 | description = [[ 2 | Checks to see if a web server is running a Ruby on Rails application that is vulnerable to the CVE-2013-0156 bug. 3 | 4 | The script sends a specially crafted XML body in a POST request that triggers the XML parser into attempting to parse invalid YAML and should result 5 | in a `500 Internal Server Error` from the application. 6 | 7 | If an application is vulnerable, it is possible to execute arbitrary Ruby code, perform SQL Injection under certain conditions and Denial of Service. 8 | See https://community.rapid7.com/community/metasploit/blog/2013/01/10/exploiting-ruby-on-rails-with-metasploit-cve-2013-0156 for more details. 9 | ]] 10 | 11 | --- 12 | -- @usage 13 | -- nmap -sV --script http-rails-xml-parser 14 | -- 15 | -- @output 16 | -- PORT STATE SERVICE 17 | -- 80/tcp open http 18 | -- | Looks like a Rails server with vulnerable XML parser (CVE-2013-0156) 19 | -- | See http://bit.ly/13uq8Uk for exploitation details 20 | -- 21 | -- @args http-rails-xml-parser.uri URI used in POST request. Default: / 22 | 23 | author = "Michael Henriksen" 24 | license = "Same as Nmap--See http://nmap.org/book/man-legal.html" 25 | categories = {"vuln"} 26 | 27 | local http = require "http" 28 | local shortport = require "shortport" 29 | local stdnse = require "stdnse" 30 | local openssl = stdnse.silent_require "openssl" 31 | 32 | portrule = shortport.http 33 | 34 | local DEFAULT_URI = "/" 35 | local HTTP_OPTIONS = { 36 | ['header'] = { 37 | ['Content-Type'] = 'application/xml' 38 | } 39 | } 40 | 41 | probe = function(host, port, uri, data) 42 | local response = http.post(host, port, uri, HTTP_OPTIONS, nil, data) 43 | return response.status 44 | end 45 | 46 | action = function(host, port) 47 | local output = {} 48 | local uri = stdnse.get_script_args("http-rails-xml-parser.uri") or DEFAULT_URI 49 | stdnse.print_debug(1, "URI: %s", uri) 50 | 51 | local probe_normal_xml = probe(host, port, uri, "\n") 52 | local probe_valid_yaml = probe(host, port, uri, "\n") 53 | local probe_invalid_yaml = probe(host, port, uri, "\n") 54 | 55 | stdnse.print_debug(1, "Response with normal XML : %i", probe_normal_xml) 56 | stdnse.print_debug(1, "Response with valid YAML : %i", probe_valid_yaml) 57 | stdnse.print_debug(1, "Response with invalid YAML : %i", probe_invalid_yaml) 58 | 59 | if probe_invalid_yaml ~= probe_normal_xml and probe_invalid_yaml ~= probe_valid_yaml and probe_invalid_yaml == 500 then 60 | output[#output+1] = "Looks like a Rails server with vulnerable XML parser (CVE-2013-0156)" 61 | output[#output+1] = "See http://bit.ly/13uq8Uk for exploitation details" 62 | else 63 | stdnse.print_debug(1, "Host does not seem to have a vulnerable XML parser") 64 | end 65 | 66 | if #output > 0 then 67 | return stdnse.strjoin("\n", output) 68 | end 69 | end --------------------------------------------------------------------------------