Nmap Development mailing list archives

[NSE] XML output for http-rfi-spider.nse


From: nnposter () users sourceforge net
Date: Tue, 16 Sep 2014 21:29:25 +0000

Since I was already hacking at http-rfi-spider.nse I took a stab at
outfitting it with XML output. I did not try to preserve the original
formatted output layout. Among other changes the script now reports
which specific form on a given page is vulnerable.

Please feel free to voice opinions about how the suggested XML output
structure should be adjusted.


Before:

80/tcp open  http
| http-rfi-spider:
|   Possible RFI in form at path: /experiments/rfihome.html, action: rfi.pl for fields:
|     inc
|   Possible RFI in form at path: /experiments/rfihome.html, action: rfi.pl for fields:
|     inc2
|   Possible RFI in parameters at path: /experiments/rfi.pl for queries:
|_    inc=http%3a%2f%2ftools%2eietf%2eorg%2fhtml%2frfc13%3f


After:

80/tcp open  http
| http-rfi-spider:
|   Possible RFI in form fields
|     Form "(form 1)" at /experiments/rfihome.html (action rfi.pl) with fields:
|       inc
|     Form "someform" at /experiments/rfihome.html (action rfi.pl) with fields:
|       inc2
|   Possible RFI in query parameters
|     Path /experiments/rfi.pl with queries:
|_      inc=http%3a%2f%2ftools%2eietf%2eorg%2fhtml%2frfc13%3f


NOTE: The patch below assumes that the following patches have been
applied:
http://seclists.org/nmap-dev/2014/q3/427
http://seclists.org/nmap-dev/2014/q3/443


Cheers,
nnposter



--- scripts/http-rfi-spider.nse.orig    2014-09-10 16:41:13.412328400 -0600
+++ scripts/http-rfi-spider.nse 2014-09-16 14:48:36.693347300 -0600
@@ -9,11 +9,38 @@
 --
 -- @output
 -- PORT   STATE SERVICE REASON
--- 80/tcp open  http    syn-ack
+-- 80/tcp open  http
 -- | http-rfi-spider:
--- |   Possible RFI in form at path: /pio/rfi_test2.php, action: /rfi_test2.php for fields:
--- |     color
--- |_    inc
+-- |   Possible RFI in form fields
+-- |     Form "(form 1)" at /experiments/rfihome.html (action rfi.pl) with fields:
+-- |       inc
+-- |     Form "someform" at /experiments/rfihome.html (action rfi.pl) with fields:
+-- |       inc2
+-- |   Possible RFI in query parameters
+-- |     Path /experiments/rfi.pl with queries:
+-- |_      inc=http%3a%2f%2ftools%2eietf%2eorg%2fhtml%2frfc13%3f
+--
+-- @xmloutput
+-- <table key="Queries">
+--   <table key="/experiments/rfi.pl">
+--     <elem>inc=http%3a%2f%2ftools%2eietf%2eorg%2fhtml%2frfc13%3f</elem>
+--   </table>
+-- </table>
+-- <table key="Forms">
+--   <table key="/experiments/rfihome.html">
+--     <table key="(form 1)">
+--       <table key="Vulnerable fields">
+--         <elem>inc</elem>
+--       </table>
+--       <elem key="Action">rfi.pl</elem>
+--     </table>
+--   <table key="someform">
+--     <table key="Vulnerable fields">
+--       <elem>inc2</elem>
+--     </table>
+--     <elem key="Action">rfi.pl</elem>
+--   </table>
+-- </table>
 --
 -- @args http-rfi-spider.inclusionurl the url we will try to include, defaults
 --       to <code>http://tools.ietf.org/html/rfc13?</code>
@@ -45,6 +72,7 @@
 local httpspider = require 'httpspider'
 local string = require 'string'
 local table = require 'table'
+local listop = require 'listop'
 
 -- this is a variable that will hold the function that checks if a pattern we are searching for is in
 -- response's body
@@ -162,7 +190,7 @@
     return
   end
 
-  local return_table = {}
+  local output = {}
 
   while(true) do
     local status, r = crawler:crawl()
@@ -177,15 +205,21 @@
 
     -- first we try rfi on forms
     if r.response and r.response.body and r.response.status==200 then
+      local path = r.url.path
       local all_forms = http.grab_forms(r.response.body)
-      for _,form_plain in ipairs(all_forms) do
+      for seq, form_plain in ipairs(all_forms) do
         local form = http.parse_form(form_plain)
-        local path = r.url.path
         if form and form.action then
           local vulnerable_fields = check_form(form, host, port, path)
           if #vulnerable_fields > 0 then
-            vulnerable_fields["name"] = "Possible RFI in form at path: "..path..", action: "..form["action"].." for 
fields:"
-            table.insert(return_table, vulnerable_fields)
+            if not output.Forms then output.Forms = {} end
+            if not output.Forms[path] then output.Forms[path] = {} end
+            local out_forms = output.Forms[path]
+            local out_form = {
+                               ["Action"] = form.action,
+                               ["Vulnerable fields"] = vulnerable_fields
+                             }
+            out_forms[form.id or string.format("(form %d)", seq)] = out_form
           end
         end
       end --for
@@ -208,12 +242,36 @@
       local responses = inject(host, port, new_urls)
       local suspects = check_responses(new_urls, responses)
       for p,q in pairs(suspects) do
-        local vulnerable_fields = q
-        vulnerable_fields["name"] = "Possible RFI in parameters at path: "..p.." for queries:"
-        table.insert(return_table, vulnerable_fields)
+        if not output.Queries then output.Queries = {} end
+        if not output.Queries[p] then output.Queries[p] = {} end
+        output.Queries[p] = listop.append(output.Queries[p], q)
       end
     end
   end
-  return stdnse.format_output(true, return_table)
+
+  local text_output = {}
+  if output.Forms then
+    local rfi = { name = "Possible RFI in form fields" }
+    for path, forms in pairs(output.Forms) do
+      for fid, fobj in pairs(forms) do
+        local out = listop.append({}, fobj["Vulnerable fields"])
+        out.name = string.format('Form "%s" at %s (action %s) with fields:',
+                                 fid, path, fobj["Action"])
+        table.insert(rfi, out)
+      end
+    end
+    table.insert(text_output, rfi)
+  end
+  if output.Queries then
+    local rfi = { name = "Possible RFI in query parameters" }
+    for path, queries in pairs(output.Queries) do
+      local out = listop.append({}, queries)
+      out.name = string.format('Path %s with queries:', path)
+      table.insert(rfi, out)
+    end
+    table.insert(text_output, rfi)
+  end
+      
+  return output, stdnse.format_output(true, text_output)
 end
 



_______________________________________________
Sent through the dev mailing list
http://nmap.org/mailman/listinfo/dev
Archived at http://seclists.org/nmap-dev/


Current thread: