1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-15 20:29:03 +00:00

NSE add STARTTLS to sslv2 improving detection of SSLv2 and DROWN oracles. Closes #320

This commit is contained in:
tomsellers
2016-03-03 02:06:05 +00:00
parent 13006aea4d
commit 318accba6e
3 changed files with 52 additions and 19 deletions

View File

@@ -1,5 +1,11 @@
# Nmap Changelog ($Id$); -*-text-*-
o [NSE][GH#320] Add STARTTLS support to sslv2 to enable SSLv2 detection
against services that are not TLS encrypted by default but that support
post connection upgrade. This will enable more comprehensive detection
of SSLv2 and DROWN (CVE-2016-0800) attack oracles. [Tom Sellers]
o [NSE][GH#301] Added default credential checks for RICOH Web Image Monitor and
BeEF to http-default-accounts. [nnposter]

4
nping/configure vendored
View File

@@ -2229,6 +2229,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
# Check whether --with-localdirs was given.
if test "${with_localdirs+set}" = set; then :
withval=$with_localdirs; case "$with_localdirs" in

View File

@@ -4,6 +4,7 @@ local string = require "string"
local table = require "table"
local bin = require "bin"
local stdnse = require "stdnse"
local sslcert = require "sslcert"
description = [[
Determines whether the server supports obsolete and less secure SSLv2, and discovers which ciphers it
@@ -42,7 +43,9 @@ license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "safe"}
portrule = shortport.ssl
portrule = function(host, port)
return shortport.ssl(host, port) or sslcert.getPrepareTLSWithoutReconnect(port)
end
local ssl_ciphers = {
-- (cut down) table of codes with their corresponding ciphers.
@@ -80,8 +83,28 @@ local ciphers = function(cipher_list)
end
action = function(host, port)
local timeout = stdnse.get_timeout(host, 10000, 5000)
local socket = nmap.new_socket();
-- Create socket.
local status, sock, err
local starttls = sslcert.getPrepareTLSWithoutReconnect(port)
if starttls then
status, socket = starttls(host, port)
if not status then
stdnse.debug(1, "Can't connect using STARTTLS: %s", socket)
return nil
end
else
socket = nmap.new_socket()
socket:set_timeout(timeout)
status, err = socket:connect(host, port)
if not status then
stdnse.debug(1, "Can't connect: %s", err)
return nil
end
end
socket:set_timeout(timeout)
-- build client hello packet (contents inspired by
-- http://mail.nessus.org/pipermail/plugins-writers/2004-October/msg00041.html )
@@ -101,49 +124,49 @@ action = function(host, port)
.. "\x02\x00\x80" -- SSL2_RC4_128_EXPORT40_WITH_MD5
.. "\xe4\xbd\x00\x00\xa4\x41\xb6\x74\x71\x2b\x27\x95\x44\xc0\x3d\xc0" -- challenge
socket:connect(host, port);
socket:send(ssl_v2_hello);
socket:send(ssl_v2_hello)
local status, server_hello = socket:receive_bytes(2);
local status, server_hello = socket:receive_bytes(2)
if (not status) then
socket:close();
return;
socket:close()
return
end
local idx, server_hello_len = bin.unpack(">S", server_hello)
-- length record doesn't include its own length, and is "broken".
server_hello_len = server_hello_len - (128 * 256) + 2;
server_hello_len = server_hello_len - (128 * 256) + 2
-- the hello needs to be at least 13 bytes long to be of any use
if (server_hello_len < 13) then
socket:close();
return;
socket:close()
stdnse.debug(1, "Server Hello too short")
return
end
--try to get entire hello, if we don't already
if (#server_hello < server_hello_len) then
local status, tmp = socket:receive_bytes(server_hello_len - #server_hello);
local status, tmp = socket:receive_bytes(server_hello_len - #server_hello)
if (not status) then
socket:close();
return;
socket:close()
return
end
server_hello = server_hello .. tmp;
end;
server_hello = server_hello .. tmp
end
socket:close();
socket:close()
-- split up server hello into components
local idx, message_type, SID_hit, certificate_type, ssl_version, certificate_len, ciphers_len, connection_ID_len = bin.unpack(">CCCSSSS", server_hello, idx)
-- some sanity checks:
-- is response a server hello?
if (message_type ~= 4) then
return;
return
end
-- is certificate in X.509 format?
if (certificate_type ~= 1) then
return;
return
end
local idx, certificate = bin.unpack("A" .. certificate_len, server_hello, idx)
@@ -160,5 +183,5 @@ action = function(host, port)
o["ciphers"] = available_ciphers
end
return o;
return o
end