description = [[ Finds RFI vulnerability in forms. ]] --TODO write a description --- -- @usage -- nmap --script http-rfi-finder -p 80 -- -- TODO -- comments -- -- @output -- PORT STATE SERVICE REASON -- 80/tcp open http syn-ack -- | http-rfi-finder: -- | Path: /rfi_test.php Action: /rfi_test.php -- |_ color -- -- @args http-rfi-finder.paths a table with the paths to check for rfi, -- for example {/index.html, /bar.html}. -- author = "Piotr Olma" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"intrusive"} local shortport = require 'shortport' local http = require 'http' local stdnse = require 'stdnse' local tab = require 'tab' local url = require 'url' local function check_response(response) --return string.find(response.body, "Advertising Programs") and string.find(response.body, "Give us feedback") and string.find(response.body, "About Google") --return string.find(response.body, '') -- that would work for google return string.find(response.body, "thisstringisuniqueforsure!") --this is for my file end -- checks if a field is of type we want to check for rfi local function rfi_field(field_type) return field_type=="text" or field_type=="radio" or field_type=="checkbox" end -- generates postdata with value of "sampleString" for every field (that is rfi_field()) of a form local function generate_safe_postdata(form) postdata = {} for _,field in ipairs(form["fields"]) do if rfi_field(field["type"]) then postdata[field["name"]] = "sampleString" end end return postdata end local function generate_get_string(data) get_str = {"?"} for name,value in pairs(data) do get_str[#get_str+1]=url.escape(name).."="..url.escape(value).."&" end return table.concat(get_str) end local function send_form_post(host, port, action, postdata) return http.post(host, port, action, nil, nil, postdata) end local function send_form_get(host, port, action, postdata) return http.get(host, port, action..generate_get_string(postdata)) end local function check_form(form, host, port) local vulnerable_fields = {} local postdata = generate_safe_postdata(form) local sending_function, response if not(form["method"]) or form["method"]=="post" then sending_function = send_form_post else sending_function = send_form_get end for _,field in ipairs(form["fields"]) do if rfi_field(field["type"]) then --postdata[field["name"]] = "http://www.google.com/search?q=rfi" -- thats what I wanted to do, but it doesn't seem to work --postdata[field["name"]] = "http://xxx/xxx/rficheck" -- script rficheck.php contains response = sending_function(host, port, form["action"], postdata) stdnse.print_debug(1,response.body) if check_response(response) then vulnerable_fields[#vulnerable_fields+1] = field["name"] end postdata[field["name"]] = "sampleString" end end return vulnerable_fields end portrule = shortport.port_or_service( {80, 443}, {"http", "https"}, "tcp", "open") function action(host, port) local paths = stdnse.get_script_args('http-rfi-finder.paths') if not paths then stdnse.print_debug(1, "No targets were specified") return nil end local return_table = {} for _,path in ipairs(paths) do local response = http.get( host, port, path ) local all_forms = http.grab_forms(response.body) for _,form_plain in ipairs(all_forms) do local form = http.parse_form(form_plain) if form then vulnerable_fields = check_form(form, host, port) if #vulnerable_fields > 0 then vulnerable_fields["name"] = "Path: "..path.." Action: "..form["action"] table.insert(return_table, vulnerable_fields) end end end end return stdnse.format_output(true, return_table) end