mirror of
https://github.com/nmap/nmap.git
synced 2025-12-10 17:59:04 +00:00
Add the http-date.nse script. Also the function http.parse_date that
parses an HTTP date in any of three possible formats. http-date.nse gets the Date: header field value from and HTTP server, then displays it with how much it differs from local time.
This commit is contained in:
@@ -428,6 +428,63 @@ request = function( host, port, data, options )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local MONTH_MAP = {
|
||||||
|
Jan = 1, Feb = 2, Mar = 3, Apr = 4, May = 5, Jun = 6,
|
||||||
|
Jul = 7, Aug = 8, Sep = 9, Oct = 10, Nov = 11, Dec = 12
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Parses an HTTP date string, in any of the following formats from section
|
||||||
|
-- 3.3.1 of RFC 2616:
|
||||||
|
-- * Sun, 06 Nov 1994 08:49:37 GMT (RFC 822, updated by RFC 1123)
|
||||||
|
-- * Sunday, 06-Nov-94 08:49:37 GMT (RFC 850, obsoleted by RFC 1036)
|
||||||
|
-- * Sun Nov 6 08:49:37 1994 (ANSI C's <code>asctime()</code> format)
|
||||||
|
-- @arg s the date string.
|
||||||
|
-- @return a table with keys <code>year</code>, <code>month</code>,
|
||||||
|
-- <code>day</code>, <code>hour</code>, <code>min</code>, <code>sec</code>, and
|
||||||
|
-- <code>isdst</code>, relative to GMT, suitable for input to
|
||||||
|
-- <code>os.time</code>.
|
||||||
|
function parse_date(s)
|
||||||
|
local day, month, year, hour, min, sec, tz, month_name
|
||||||
|
-- RFC 2616, section 3.3.1:
|
||||||
|
|
||||||
|
-- Handle RFC 1123 and 1036 at once.
|
||||||
|
day, month_name, year, hour, min, sec, tz = s:match("^%w+, (%d+)[- ](%w+)[- ](%d+) (%d+):(%d+):(%d+) (%w+)$")
|
||||||
|
if not day then
|
||||||
|
month_name, day, hour, min, sec, year = s:match("%w+ (%w+) ?(%d+) (%d+):(%d+):(%d+) (%d+)")
|
||||||
|
tz = "GMT"
|
||||||
|
end
|
||||||
|
if not day then
|
||||||
|
stdnse.print_debug(1, "http.parse_date: can't parse date \"%s\": unknown format.", s)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
-- Look up the numeric code for month.
|
||||||
|
month = MONTH_MAP[month_name]
|
||||||
|
if not month then
|
||||||
|
stdnse.print_debug(1, "http.parse_date: unknown month name \"%s\".", month_name)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
if tz ~= "GMT" then
|
||||||
|
stdnse.print_debug(1, "http.parse_date: don't know time zone \"%s\", only \"GMT\".", tz)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
day = tonumber(day)
|
||||||
|
year = tonumber(year)
|
||||||
|
hour = tonumber(hour)
|
||||||
|
min = tonumber(min)
|
||||||
|
sec = tonumber(sec)
|
||||||
|
|
||||||
|
if year < 100 then
|
||||||
|
-- Two-digit year. Make a guess.
|
||||||
|
if year < 70 then
|
||||||
|
year = year + 2000
|
||||||
|
else
|
||||||
|
year = year + 1900
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return { year = year, month = month, day = day, hour = hour, min = min, sec = sec, isdst = false }
|
||||||
|
end
|
||||||
|
|
||||||
get_default_timeout = function( nmap_timing )
|
get_default_timeout = function( nmap_timing )
|
||||||
local timeout = {}
|
local timeout = {}
|
||||||
if nmap_timing >= 0 and nmap_timing <= 3 then
|
if nmap_timing >= 0 and nmap_timing <= 3 then
|
||||||
|
|||||||
80
scripts/http-date.nse
Normal file
80
scripts/http-date.nse
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
description = [[
|
||||||
|
Gets the date from HTTP-like services. Also prints how much the date
|
||||||
|
differs from local time. Local time is the time the HTTP request was
|
||||||
|
sent, so the difference includes at least the duration of one RTT.
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @output
|
||||||
|
-- 80/tcp open http
|
||||||
|
-- |_ http-date: Mon, 13 Jul 2009 20:53:46 GMT; -5s from local time.
|
||||||
|
|
||||||
|
author = "David Fifield <david@bamsoftware.com>"
|
||||||
|
|
||||||
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
|
||||||
|
categories = {"discovery", "safe"}
|
||||||
|
|
||||||
|
require("http")
|
||||||
|
require("shortport")
|
||||||
|
|
||||||
|
portrule = shortport.port_or_service({80, 443, 631, 8080},
|
||||||
|
{"http", "https", "ipp", "http-alt"})
|
||||||
|
|
||||||
|
-- Turn a positive or negative number of seconds into a string in one of the
|
||||||
|
-- forms:
|
||||||
|
-- 0s
|
||||||
|
-- +2s
|
||||||
|
-- -4s
|
||||||
|
-- +02m38s
|
||||||
|
-- -9h12m34s
|
||||||
|
-- 5d17h05m06s
|
||||||
|
local function format_difftime(t)
|
||||||
|
local s, sign, sec
|
||||||
|
|
||||||
|
if t > 0 then
|
||||||
|
sign = "+"
|
||||||
|
elseif t < 0 then
|
||||||
|
sign = "-"
|
||||||
|
else
|
||||||
|
sign = ""
|
||||||
|
end
|
||||||
|
t = math.abs(t)
|
||||||
|
|
||||||
|
-- Seconds.
|
||||||
|
sec = t % 60
|
||||||
|
s = string.format("%gs", sec)
|
||||||
|
t = math.floor(t / 60)
|
||||||
|
if t == 0 then return sign .. s end
|
||||||
|
-- Minutes.
|
||||||
|
s = string.format("%02dm%02ds", t % 60, sec)
|
||||||
|
t = math.floor(t / 60)
|
||||||
|
if t == 0 then return sign .. s end
|
||||||
|
-- Hours.
|
||||||
|
s = string.format("%dh", t % 24) .. s
|
||||||
|
t = math.floor(t / 24)
|
||||||
|
if t == 0 then return sign .. s end
|
||||||
|
-- Days.
|
||||||
|
s = string.format("%dd", t) .. s
|
||||||
|
return sign .. s
|
||||||
|
end
|
||||||
|
|
||||||
|
action = function(host, port)
|
||||||
|
-- Get local time in UTC.
|
||||||
|
local request_time = os.time(os.date("!*t"))
|
||||||
|
local response = http.get(host, port, "/")
|
||||||
|
if not response.status or not response.header["date"] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local date = http.parse_date(response.header["date"])
|
||||||
|
if not date then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Should account for estimated RTT too.
|
||||||
|
local diff = os.difftime(os.time(date), request_time)
|
||||||
|
|
||||||
|
return string.format("%s; %s from local time.",
|
||||||
|
response.header["date"], format_difftime(diff))
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user