Nmap Development mailing list archives
Re: [NSE] False timestamp in ssl-date
From: nnposter () users sourceforge net
Date: Thu, 7 Aug 2014 22:22:25 +0000
David Fifield wrote:
This is great. I think I would just always make two probes, and not base the decision on a comparison to local time. If the server is generating the field randomly, then the chances that two measurements differ by 10 or less is about 10/2^32 = 2.3e-09 = 2^-28.6, or 1 in 400 million. You could always do three probes and make the probability negligible. Maybe there are servers that don't use the time and don't generate randomly, but do something else? Like a fixed value? I guess you can also reject if the second sample is less than the first.
I have tried to incorporate David's suggestions. The resulting script first takes two TLS time samples. If they are identical then it waits 1.1s and retakes the second sample. The script fails unless the second sample is greater than the first and the difference between the two samples is consistent with the actual time elapsed. Compared to the previous version of the script, this change attempts to detect and eliminate fixed values. The penalty for doing so is the one-second forced sleep that occurs against most targets (where the TLS value indeed represents time) because the first two samples are overwhelmingly taken within the same second (so there is no distinction from fixed values). Personally I would have preferred to keep the original quick-success clause and call the first sample good enough if it does not differ substantially from the scanner clock. Its main advantage is that it eliminates the forced sleep (and two additional connections/handshakes) in most cases. (It would be easy to add it back. If the concern is a false-positive match then we could be less tolerant than the original +/- 15 minutes.) Cheers, nnposter Patch against revision 33449 follows: --- scripts/ssl-date.nse.orig 2014-08-07 15:49:02.990490400 -0600 +++ scripts/ssl-date.nse 2014-08-07 15:53:20.340222800 -0600 @@ -134,39 +134,56 @@ -- extract time from response local tstatus, ttm = extract_time(response) if not tstatus then return nil end - return ttm, stm + stdnse.debug(2, "TLS time sample: %s", stdnse.format_timestamp(ttm, 0)) + return {target=ttm, scanner=stm, delta=os.difftime(ttm, stm)} +end + +local result = { STAGNANT = "stagnant", + ACCEPTED = "accepted", + REJECTED = "rejected" } + +local test_time_sample = function (host, port, reftm) + local tm = get_time_sample(host, port) + if not tm then return nil end + local tchange = os.difftime(tm.target, reftm.target) + local schange = os.difftime(tm.scanner, reftm.scanner) + local status = + -- clock cannot run backwards or drift substantially + (tchange < 0 or math.abs(tchange - schange) > 3) + and result.REJECTED + -- the clock did not advance + or tchange == 0 + and result.STAGNANT + -- plausible enough + or result.ACCEPTED + stdnse.debug(2, "TLS time test result: %s", status) + return status, tm end action = function(host, port) - local ttm, stm = get_time_sample(host, port) - if not ttm then + local reftm = get_time_sample(host, port) + if not reftm then return stdnse.format_output(false, "Unable to obtain data from the target") end - local delta = os.difftime(ttm, stm) - stdnse.debug(2, "Sample #1 time difference is %d seconds", delta) - - if math.abs(delta) > 15*60 then - -- time difference is suspect - -- get a second sample to determine if the clock is simply off - -- or if the TLS randomness does not represent the time at all - ttm, stm = get_time_sample(host, port) - if not ttm then - return stdnse.format_output(false, "Unable to obtain data from the target") - end - local origdelta = delta - delta = os.difftime(ttm, stm) - stdnse.debug(2, "Sample #2 time difference is %d seconds", delta) - if math.abs(origdelta - delta) > 5 then - return stdnse.format_output(false, "TLS randomness does not represent time") - end + local status, tm = test_time_sample(host, port, reftm) + if status and status == result.STAGNANT then + stdnse.sleep(1.1) + status, tm = test_time_sample(host, port, reftm) + end + if not status then + return stdnse.format_output(false, "Unable to obtain data from the target") + end + if status ~= result.ACCEPTED then + return stdnse.format_output(false, "TLS randomness does not represent time") end local output = { - date = stdnse.format_timestamp(ttm, 0), - delta = delta, + date = stdnse.format_timestamp(tm.target, 0), + delta = tm.delta, } return output, string.format("%s; %s from scanner time.", output.date, - stdnse.format_difftime(os.date("!*t",ttm),os.date("!*t", stm))) + stdnse.format_difftime(os.date("!*t", tm.target), + os.date("!*t", tm.scanner))) end _______________________________________________ Sent through the dev mailing list http://nmap.org/mailman/listinfo/dev Archived at http://seclists.org/nmap-dev/
Current thread:
- [NSE] False timestamp in ssl-date nnposter (Aug 01)
- Re: [NSE] False timestamp in ssl-date Daniel Miller (Aug 01)
- Re: [NSE] False timestamp in ssl-date David Fifield (Aug 01)
- Re: [NSE] False timestamp in ssl-date nnposter (Aug 07)
- Re: [NSE] False timestamp in ssl-date nnposter (Aug 07)
- Re: [NSE] False timestamp in ssl-date Fyodor (Aug 16)
- Re: [NSE] False timestamp in ssl-date nnposter (Aug 18)
- Re: [NSE] False timestamp in ssl-date Daniel Miller (Aug 20)
- Re: [NSE] False timestamp in ssl-date nnposter (Aug 22)
- Re: [NSE] False timestamp in ssl-date nnposter (Aug 07)