1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
local smb = require "smb"
local vulns = require "vulns"
local stdnse = require "stdnse"
local string = require "string"
description = [[
Checks if the target machine is running the Double Pulsar SMB backdoor.
Based on the python detection script by Luke Jennings of Countercept.
https://github.com/countercept/doublepulsar-detection-script
]]
---
-- @usage nmap -p 445 <target> --script=smb-double-pulsar-backdoor
--
-- @see smb-vuln-ms17-010.nse
--
-- @output
-- | smb-double-pulsar-backdoor:
-- | VULNERABLE:
-- | Double Pulsar SMB Backdoor
-- | State: VULNERABLE
-- | Risk factor: HIGH CVSSv2: 10.0 (HIGH) (AV:N/AC:L/Au:N/C:C/I:C/A:C)
-- | The Double Pulsar SMB backdoor was detected running on the remote machine.
-- |
-- | Disclosure date: 2017-04-14
-- | References:
-- | https://isc.sans.edu/forums/diary/Detecting+SMB+Covert+Channel+Double+Pulsar/22312/
-- | https://github.com/countercept/doublepulsar-detection-script
-- |_ https://steemit.com/shadowbrokers/@theshadowbrokers/lost-in-translation
author = "Andrew Orr"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"vuln", "safe", "malware"}
hostrule = function(host)
return smb.get_port(host) ~= nil
end
-- stolen from smb.lua as timeout needs to be modified to get a response
local function send_transaction2(smbstate, sub_command, function_parameters, function_data, overrides)
overrides = overrides or {}
local header1, header2, header3, header4, command, status, flags, flags2, pid_high, signature, unused, pid, mid
local header, parameters, data
local parameter_offset = 0
local parameter_size = 0
local data_offset = 0
local data_size = 0
local total_word_count, total_data_count, reserved1, parameter_count, parameter_displacement, data_count, data_displacement, setup_count, reserved2
local response = {}
-- Header is 0x20 bytes long (not counting NetBIOS header).
header = smb.smb_encode_header(smbstate, 0x32, overrides) -- 0x32 = SMB_COM_TRANSACTION2
if(function_parameters) then
parameter_offset = 0x44
parameter_size = #function_parameters
data_offset = #function_parameters + 33 + 32
end
-- Parameters are 0x20 bytes long.
parameters = string.pack("<I2 I2 I2 I2 B B I2 I4 I2 I2 I2 I2 I2 B B I2",
parameter_size, -- Total parameter count.
data_size, -- Total data count.
0x000a, -- Max parameter count.
0x3984, -- Max data count.
0x00, -- Max setup count.
0x00, -- Reserved.
0x0000, -- Flags (0x0000 = 2-way transaction, don't disconnect TIDs).
10803622, -- Timeout
0x0000, -- Reserved.
parameter_size, -- Parameter bytes.
parameter_offset, -- Parameter offset.
data_size, -- Data bytes.
data_offset, -- Data offset.
0x01, -- Setup Count
0x00, -- Reserved
sub_command -- Sub command
)
local data = "\0\0\0" .. (function_parameters or '')
.. (function_data or '')
-- Send the transaction request
stdnse.debug2("SMB: Sending SMB_COM_TRANSACTION2")
local result, err = smb.smb_send(smbstate, header, parameters, data, overrides)
if(result == false) then
return false, err
end
return true
end
action = function(host,port)
local double_pulsar = {
title = "Double Pulsar SMB Backdoor",
-- IDS = {CVE = 'CVE-2010-2550'},
risk_factor = "HIGH",
scores = {
CVSSv2 = "10.0 (HIGH) (AV:N/AC:L/Au:N/C:C/I:C/A:C)",
},
description = [[
The Double Pulsar SMB backdoor was detected running on the remote machine.
]],
references = {
'https://github.com/countercept/doublepulsar-detection-script',
'https://isc.sans.edu/forums/diary/Detecting+SMB+Covert+Channel+Double+Pulsar/22312/',
'https://steemit.com/shadowbrokers/@theshadowbrokers/lost-in-translation'
},
dates = {
disclosure = {year = '2017', month = '04', day = '14'},
},
exploit_results = {},
}
local report = vulns.Report:new(SCRIPT_NAME, host, port)
double_pulsar.state = vulns.STATE.NOT_VULN
local share = "IPC$"
local status, smbstate = smb.start_ex(host, true, true, share, nil, nil, nil)
if not status then
stdnse.debug1("Could not connect to IPC$ share over SMB.")
else
-- the multiplex ID needs to be 65
smbstate["mid"] = 65;
-- 12 (not 11, not 13) nulls
local param = ("\0"):rep(12)
-- 0x000e is SESSION_SETUP
local status, result = send_transaction2(smbstate, 0xe, param)
if not status then
stdnse.debug1("Error: ", result)
else
local status, header, parameters, data = smb.smb_read(smbstate)
local multiplex_id = string.unpack("<I2", header, 1 + string.packsize("BBBBB I4 B I2 I2 i8 I2 I2 I2 I2"))
if (multiplex_id == 81) then
double_pulsar.state = vulns.STATE.VULN
else
stdnse.debug1("Machine is not vulnerable")
end
end
end
return report:make_output(double_pulsar)
end
|