--- -- A minimal RDP (Remote Desktop Protocol) library. Currently has functionality to determine encryption -- and cipher support. -- -- -- @author Patrik Karlsson -- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html -- local nmap = require("nmap") local stdnse = require("stdnse") local string = require "string" _ENV = stdnse.module("rdp", stdnse.seeall) -- Server Core Data 2.2.1.4.2 PROTO_VERSION = { [0x00080001] = " RDP 4.0 server", [0x00080004] = " RDP 5.x, 6.x, 7.x, or 8.x server", [0x00080005] = " RDP 10.0 server", [0x00080006] = " RDP 10.1 server", [0x00080007] = " RDP 10.2 server", [0x00080008] = " RDP 10.3 server", [0x00080009] = " RDP 10.4 server", [0x0008000A] = " RDP 10.5 server", [0x0008000B] = " RDP 10.6 server", [0x0008000C] = " RDP 10.7 server", } Packet = { TPKT = { new = function(self, data) local o = { data = tostring(data), version = 3 } setmetatable(o, self) self.__index = self return o end, __tostring = function(self) return string.pack(">BBI2", self.version, self.reserved or 0, (self.data and #self.data + 4 or 4)) ..self.data end, parse = function(data) local tpkt = Packet.TPKT:new() local pos tpkt.version, tpkt.reserved, tpkt.length, pos = string.unpack(">BBI2", data) tpkt.data = data:sub(pos) return tpkt end }, ITUT = { new = function(self, code, data) local o = { data = tostring(data), code = code } setmetatable(o, self) self.__index = self return o end, parse = function(data) local itut = Packet.ITUT:new() local pos itut.length, itut.code, pos = string.unpack("BB", data) if ( itut.code == 0xF0 ) then -- X.224 - Data TPDU (DT) itut.eot, pos = string.unpack("B", data, pos) elseif ( itut.code == 0xD0 ) then -- X.224 - Connection Confirm (CC) itut.dstref, itut.srcref, itut.class, pos = string.unpack(">I2I2B", data, pos) end itut.data = data:sub(pos) return itut end, __tostring = function(self) local len, eot if self.code == 0xF0 then eot = "\x80" len = 2 else eot = "" len = #self.data + 1 end local data = string.pack("BB", len, self.code or 0) .. eot .. self.data return data end, }, ConfCreateResponse = { new = function(self, data) local o = {} setmetatable(o, self) self.__index = self return o end, parse = function(data) local ccr = Packet.ConfCreateResponse:new() local pos = 67 while data:len() > pos do block_type, block_len = string.unpack("I2I2B", 0x0000, -- dst reference 0x0000, -- src reference 0x00) -- class and options .. ("Cookie: %s\r\n"):format(cookie) if ( self.proto ) then data = data .. string.pack("