147 lines
5.2 KiB
Plaintext
147 lines
5.2 KiB
Plaintext
|
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
|