diff --git a/lib/msf/core/exploit/smb/server/share.rb b/lib/msf/core/exploit/smb/server/share.rb index ec5b7ac4b7..90b1847a1d 100644 --- a/lib/msf/core/exploit/smb/server/share.rb +++ b/lib/msf/core/exploit/smb/server/share.rb @@ -29,11 +29,43 @@ module Msf include Msf::Exploit::Remote::SMB::Server - FLAGS2 = CONST::FLAGS2_UNICODE_STRINGS + - CONST::FLAGS2_EXTENDED_SECURITY + - CONST::FLAGS2_32_BIT_ERROR_CODES + + FLAGS = CONST::FLAGS_REQ_RES | CONST::FLAGS_CASE_SENSITIVE + + FLAGS2 = CONST::FLAGS2_UNICODE_STRINGS | + CONST::FLAGS2_EXTENDED_SECURITY | + CONST::FLAGS2_32_BIT_ERROR_CODES | CONST::FLAGS2_LONG_PATH_COMPONENTS + CAPABILITIES = CONST::CAP_UNIX_EXTENSIONS | + CONST::CAP_LARGE_WRITEX | + CONST::CAP_LARGE_READX | + CONST::CAP_PASSTHRU | + CONST::CAP_DFS | + CONST::CAP_NT_FIND | + CONST::CAP_LOCK_AND_READ | + CONST::CAP_LEVEL_II_OPLOCKS | + CONST::CAP_STATUS32 | + CONST::CAP_RPC_REMOTE_APIS | + CONST::CAP_NT_SMBS | + CONST::CAP_LARGE_FILES | + CONST::CAP_UNICODE | + CONST::CAP_RAW_MODE + + CREATE_MAX_ACCESS = CONST::SMB_READ_ACCESS | + CONST::SMB_WRITE_ACCESS | + CONST::SMB_APPEND_ACCESS | + CONST::SMB_READ_EA_ACCESS | + CONST::SMB_WRITE_EA_ACCESS | + CONST::SMB_EXECUTE_ACCESS | + CONST::SMB_DELETE_CHILD_ACCESS | + CONST::SMB_READ_ATTRIBUTES_ACCESS | + CONST::SMB_WRITE_ATTRIBUTES_ACCESS | + CONST::SMB_DELETE_ACCESS | + CONST::SMB_READ_CONTROL_ACCESS | + CONST::SMB_WRITE_DAC_ACCESS | + CONST::SMB_WRITE_OWNER_ACCESS | + CONST::SMB_SYNC_ACCESS + attr_accessor :unc attr_accessor :share attr_accessor :path_name diff --git a/lib/msf/core/exploit/smb/server/share/command/close.rb b/lib/msf/core/exploit/smb/server/share/command/close.rb index d90bbed815..9f10ed122b 100644 --- a/lib/msf/core/exploit/smb/server/share/command/close.rb +++ b/lib/msf/core/exploit/smb/server/share/command/close.rb @@ -17,7 +17,7 @@ module Msf smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_CLOSE - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 0 diff --git a/lib/msf/core/exploit/smb/server/share/command/negotiate.rb b/lib/msf/core/exploit/smb/server/share/command/negotiate.rb index 19506b3bb0..d800364903 100644 --- a/lib/msf/core/exploit/smb/server/share/command/negotiate.rb +++ b/lib/msf/core/exploit/smb/server/share/command/negotiate.rb @@ -21,11 +21,11 @@ module Msf smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 17 pkt['Payload'].v['Dialect'] = dialect - pkt['Payload'].v['SecurityMode'] = 2 # SHARE Security Mode + pkt['Payload'].v['SecurityMode'] = CONST::NEG_SECURITY_PASSWORD pkt['Payload'].v['MaxMPX'] = 50 pkt['Payload'].v['MaxVCS'] = 1 pkt['Payload'].v['MaxBuff'] = 4356 @@ -34,7 +34,7 @@ module Msf pkt['Payload'].v['SystemTimeHigh'] = hi pkt['Payload'].v['ServerTimeZone'] = 0x0 pkt['Payload'].v['SessionKey'] = 0 - pkt['Payload'].v['Capabilities'] = 0x0080f3fd + pkt['Payload'].v['Capabilities'] = CAPABILITIES pkt['Payload'].v['KeyLength'] = 8 pkt['Payload'].v['Payload'] = Rex::Text.rand_text_hex(8) diff --git a/lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb b/lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb index 5084c54c34..a85757ed92 100644 --- a/lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb +++ b/lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb @@ -38,8 +38,8 @@ module Msf pkt = CONST::SMB_CREATE_RES_PKT.make_struct smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX - pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 # OBJECT_NAME_NOT_FOUND - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['ErrorClass'] = CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 c.put(pkt.to_s) return @@ -48,7 +48,7 @@ module Msf pkt = CONST::SMB_CREATE_ANDX_RES_PKT.make_struct smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 42 pkt['Payload'].v['AndX'] = 0xff # no further commands @@ -68,10 +68,10 @@ module Msf pkt['Payload'].v['AllocHigh'] = 0 pkt['Payload'].v['EOFLow'] = eof pkt['Payload'].v['EOFHigh'] = 0 - pkt['Payload'].v['FileType'] = 0 - pkt['Payload'].v['IPCState'] = 0x7 + pkt['Payload'].v['FileType'] = CONST::SMB_RESOURCE_FILE_TYPE_DISK + pkt['Payload'].v['IPCState'] = 0x7 # Number maxim of instance a named pipe can have pkt['Payload'].v['IsDirectory'] = is_dir - pkt['Payload'].v['MaxAccess'] = 0x1f01ff + pkt['Payload'].v['MaxAccess'] = CREATE_MAX_ACCESS c.put(pkt.to_s) end end diff --git a/lib/msf/core/exploit/smb/server/share/command/read_andx.rb b/lib/msf/core/exploit/smb/server/share/command/read_andx.rb index 9da904eeb3..005bc139f3 100644 --- a/lib/msf/core/exploit/smb/server/share/command/read_andx.rb +++ b/lib/msf/core/exploit/smb/server/share/command/read_andx.rb @@ -23,7 +23,7 @@ module Msf smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_READ_ANDX - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 12 pkt['Payload'].v['AndX'] = 0xff # no more commands diff --git a/lib/msf/core/exploit/smb/server/share/command/session_setup_andx.rb b/lib/msf/core/exploit/smb/server/share/command/session_setup_andx.rb index 4ceaca07bb..7860096afd 100644 --- a/lib/msf/core/exploit/smb/server/share/command/session_setup_andx.rb +++ b/lib/msf/core/exploit/smb/server/share/command/session_setup_andx.rb @@ -25,13 +25,13 @@ module Msf smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 3 pkt['Payload'].v['AndX'] = 0x75 pkt['Payload'].v['Reserved1'] = 00 pkt['Payload'].v['AndXOffset'] = 96 - pkt['Payload'].v['Action'] = 0x1 # Logged in as Guest + pkt['Payload'].v['Action'] = CONST::SMB_SETUP_GUEST pkt['Payload'].v['Payload'] = Rex::Text.to_unicode('Unix', 'utf-16be') + "\x00\x00" + # Native OS # Samba signature Rex::Text.to_unicode('Samba 3.4.7', 'utf-16be') + "\x00\x00" + # Native LAN Manager # Samba signature diff --git a/lib/msf/core/exploit/smb/server/share/command/trans2.rb b/lib/msf/core/exploit/smb/server/share/command/trans2.rb index dfac8905f0..440391f804 100644 --- a/lib/msf/core/exploit/smb/server/share/command/trans2.rb +++ b/lib/msf/core/exploit/smb/server/share/command/trans2.rb @@ -40,7 +40,7 @@ module Msf pkt = CONST::SMB_TRANS_RES_PKT.make_struct smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['ErrorClass'] = 0xc0000225 # NT_STATUS_NOT_FOUND c.put(pkt.to_s) diff --git a/lib/msf/core/exploit/smb/server/share/information_level/find.rb b/lib/msf/core/exploit/smb/server/share/information_level/find.rb index b1762ce42f..45f3846ced 100644 --- a/lib/msf/core/exploit/smb/server/share/information_level/find.rb +++ b/lib/msf/core/exploit/smb/server/share/information_level/find.rb @@ -59,7 +59,7 @@ module Msf find_file.v['FileName'] = data pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 10 pkt['Payload'].v['ParamCountTotal'] = 10 @@ -108,7 +108,7 @@ module Msf # If its asking for a file, return file pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 10 pkt['Payload'].v['ParamCountTotal'] = 10 diff --git a/lib/msf/core/exploit/smb/server/share/information_level/query.rb b/lib/msf/core/exploit/smb/server/share/information_level/query.rb index 06aa51eb36..8c135cb643 100644 --- a/lib/msf/core/exploit/smb/server/share/information_level/query.rb +++ b/lib/msf/core/exploit/smb/server/share/information_level/query.rb @@ -12,8 +12,8 @@ module Msf pkt = CONST::SMB_TRANS_RES_PKT.make_struct smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 # OBJECT_NAME_NOT_FOUND - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['ErrorClass'] = CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 c.put(pkt.to_s) return @@ -35,7 +35,7 @@ module Msf smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 10 pkt['Payload'].v['ParamCountTotal'] = 2 @@ -73,8 +73,8 @@ module Msf attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY # File attributes => directory else pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 # OBJECT_NAME_NOT_FOUND - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['ErrorClass'] = CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND # OBJECT_NAME_NOT_FOUND + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 c.put(pkt.to_s) return @@ -95,7 +95,7 @@ module Msf query_path_info.v['ExtFileAttributes'] = attrib pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 10 pkt['Payload'].v['ParamCountTotal'] = 2 @@ -135,7 +135,7 @@ module Msf attrib = 1 # File attributes => directory else pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 # OBJECT_NAME_NOT_FOUND + pkt['Payload']['SMB'].v['ErrorClass'] = CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND # OBJECT_NAME_NOT_FOUND pkt['Payload']['SMB'].v['Flags1'] = 0x88 pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 c.put(pkt.to_s) @@ -156,7 +156,7 @@ module Msf smb_set_defaults(c, pkt) pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 - pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags1'] = FLAGS pkt['Payload']['SMB'].v['Flags2'] = FLAGS2 pkt['Payload']['SMB'].v['WordCount'] = 10 pkt['Payload'].v['ParamCountTotal'] = 2 diff --git a/lib/rex/proto/smb/constants.rb b/lib/rex/proto/smb/constants.rb index 2269253083..e1147b27e8 100644 --- a/lib/rex/proto/smb/constants.rb +++ b/lib/rex/proto/smb/constants.rb @@ -113,6 +113,16 @@ class Constants NT_TRANSACT_GET_USER_QUOTA = 7 # Get quota NT_TRANSACT_SET_USER_QUOTA = 8 # Set quota + # NT Flags bits - cifs6.txt section 3.1.1 + FLAGS_REQ_RES = 0x80 + FLAGS_NOTIFY = 0x40 + FLAGS_OP_LOCKS = 0x20 + FLAGS_PATH_NORMALIZED = 0x10 + FLAGS_CASE_SENSITIVE = 0x8 + FLAGS_RESERVED = 0x4 + FLAGS_POSTED = 0x2 + FLAGS_LOCK_SUPPORT = 0x1 + # NT Flags2 bits - cifs6.txt section 3.1.2 FLAGS2_LONG_PATH_COMPONENTS = 0x0001 FLAGS2_EXTENDED_ATTRIBUTES = 0x0002 @@ -126,6 +136,41 @@ class Constants FLAGS2_UNICODE_STRINGS = 0x8000 FLAGS2_WIN2K_SIGNATURE = 0xC852 + # SMB Negotiate Security Modes + NEG_SECURITY_SHARE = 1 + NEG_SECURITY_PASSWORD = 2 + + # SMB Setup Actions + SMB_SETUP_GUEST = 1 + SMB_SETUP_USE_LANMAN_KEY = 2 + + # SMB Negotiate Capabilities + # The server supports SMB_COM_READ_RAW and SMB_COM_WRITE_RAW + CAP_RAW_MODE = 0x0001 + # The server supports SMB_COM_READ_MPX and SMB_COM_WRITE_MPX + CAP_MPX_MODE = 0x0002 + # The server supports Unicode strings + CAP_UNICODE = 0x0004 + # The server supports large files with 64 bit offsets + CAP_LARGE_FILES = 0x0008 + # The server supports the SMBs particular to the NT LM 0.12 dialect + CAP_NT_SMBS = 0x0010 + # The sever supports remote API requests via RPC + CAP_RPC_REMOTE_APIS = 0x0020 + # The server can respond with 32 bit status codes in Status.Status + CAP_STATUS32 = 0x0040 + # The server supports level 2 oplocks + CAP_LEVEL_II_OPLOCKS = 0x0080 + # The server supports the SMB_COM_LOCK_AND_READ SMB + CAP_LOCK_AND_READ = 0x0100 + CAP_NT_FIND = 0x0200 + # This server is DFS aware + CAP_DFS = 0x1000 + CAP_PASSTHRU = 0x2000 + CAP_LARGE_READX = 0x4000 + CAP_LARGE_WRITEX = 0x8000 + CAP_UNIX_EXTENSIONS = 0x800000 + # Open Modes OPEN_MODE_CREAT = 0x10 # Create the file if file does not exists. Otherwise, operation fails. OPEN_MODE_EXCL = 0x00 # When used with SMB_O_CREAT, operation fails if file exists. Cannot be used with SMB_O_OPEN. @@ -154,6 +199,21 @@ class Constants CREATE_ACCESS_OVEREXIST = 0x04 # Overwrite existing file and fail if it does not exist CREATE_ACCESS_OVERCREATE = 0x05 # Overwrite existing file or create it if it does not exist + # Access Rights + SMB_READ_ACCESS = 1 + SMB_WRITE_ACCESS = 2 + SMB_APPEND_ACCESS = 4 + SMB_READ_EA_ACCESS = 8 + SMB_WRITE_EA_ACCESS = 0x10 + SMB_EXECUTE_ACCESS = 0x20 + SMB_DELETE_CHILD_ACCESS = 0x40 + SMB_READ_ATTRIBUTES_ACCESS = 0x80 + SMB_WRITE_ATTRIBUTES_ACCESS = 0x100 + SMB_DELETE_ACCESS = 0x10000 + SMB_READ_CONTROL_ACCESS = 0x20000 + SMB_WRITE_DAC_ACCESS = 0x40000 + SMB_WRITE_OWNER_ACCESS = 0x80000 + SMB_SYNC_ACCESS = 0x100000 # Wildcard NetBIOS name NETBIOS_REDIR = 'CACACACACACACACACACACACACACACAAA' @@ -176,7 +236,6 @@ class Constants # 13 = create_directory # 14 = session_setup - # SMB_COM_TRANSACTION2 SubCommands TRANS2_OPEN2 = 0 TRANS2_FIND_FIRST2 = 1 @@ -329,6 +388,14 @@ class Constants SMB_STATUS_ACCESS_DENIED = 0xC0000022 SMB_STATUS_LOGON_FAILURE = 0xC000006D SMB_STATUS_NO_SUCH_FILE = 0xC000000F + SMB_STATUS_OBJECT_NAME_NOT_FOUND = 0xc0000034 + + # SMB Resource types + SMB_RESOURCE_FILE_TYPE_DISK = 0x0000 + SMB_RESOURCE_FILE_TYPE_BYTE_MODE_PIPE = 0x0001 + SMB_RESOURCE_FILE_TYPE_MESSAGE_MODE_PIPE = 0x0002 + SMB_RESOURCE_FILE_TYPE_PRINTER = 0x0003 + SMB_RESOURCE_FILE_TYPE_COMM_DEVICE = 0x0004 # SMB Dialect Compatibility DIALECT = {}