SMB(Server Message Block)服务器消息块协议
SMB
协议被广泛应用于计算机间的文件共享,打印服务和网络浏览以及基于网络的进程间通讯。在Windows平台上,SMB协议常会与基于TCPIP的NetBIOS协议一起使用,用到的相关端口为UPD的137/138以及TCP的137/139,但是NetBIOS不再支持Window Vista、Window Server 2008以及更新的版本,不过SMB可以不依赖单独的通讯协议而直接通过TCP/445端口进行通讯。
Port 139:SMB协议原生使用端口139基于NetBIOS进行通讯。NetBIOS是一种用于Windows计算机间基于网络通讯的传输层协议。
Port 445:端口445被用于直接基于TCP/IP的微软网络访问,该技术不再依赖NetBIOS协议。最新版的SMB服务使用该端口进行通讯。
SMBShare和SMBWitness
SMBShare
和SMBWitness
模块于Windows 8和Winows Server 2012开始被提供,并在Powershell 3.0以及更新版本中被自动加载。这两个模块能够大大提升文件共享工作的效率并降低其复杂度。在低于上述版本的系统上,可以使用Windows Management Instrumentation
(WMI)来管理文件共享。
在window平台中,上述两种方法均可在不基于图形化的场景下,完成对文件共享的管理工作。
使用WMI来管理文件共享
在使用WMI模块来管理文件共享之前,验证一下是否WMI Provider
是否已经在系统中安装。如下命令以及返回信息说明WMI模块在当前系统已经安装。如果返回为空则说明未安装WMI,需要下载并安装Windows Management Framework 3.0
。在Windows 7 SP1 和Server 2008 R2 SP1上面可用。
注意,以下所有演示用到的主机均在同一个域中,所使用的帐号都有administrator权限
PS C:\Windows\system32> Get-WmiObject -Class __Namespace -Namespace root | ? {$_.name -eq 'WMI'}
__GENUS : 2
__CLASS : __NAMESPACE
__SUPERCLASS : __SystemClass
__DYNASTY : __SystemClass
__RELPATH : __NAMESPACE.Name="WMI"
__PROPERTY_COUNT : 1
__DERIVATION : {__SystemClass}
__SERVER : TS1
__NAMESPACE : ROOT
__PATH : \\TS1\ROOT:__NAMESPACE.Name="WMI"
Name : WMI
PSComputerName : TS1
- 使用WMI来枚举当前系统已存在的共享
Win32_Share
存在与root\cimv2的WMI名称空间中,其中的WMI对象便是在windows系统之上共享的磁盘、打印机、系统默认共享以及其他共享设备。可以使用下面的命令查询
PS C:\Windows\system32> Get-WmiObject -Class win32_share | ft -AutoSize -Wrap
Name Path Description
---- ---- -----------
ADMIN$ C:\Windows Remote Admin
C$ C:\ Default share
IPC$ Remote IPC
test C:\Users\huzx\documents\test
也可以使用Get-WMIObject
命令来查询远程主机上的共享信息,如下
PS C:\Windows\system32> Get-WmiObject -ComputerName dc -Class win32_share | ft -AutoSize -Wrap
Name Path Description
---- ---- -----------
ADMIN$ C:\Windows 远程管理
C$ C:\ 默认共享
E$ E:\ 默认共享
IPC$ 远程 IPC
NETLOGON C:\Windows\SYSVOL\sysvol\buffallos.com\SCRIPTS Logon server share
SYSVOL C:\Windows\SYSVOL\sysvol Logon server share
test c:\test
test1 c:\test1 smbshare test1
- 使用WMI来创建新的共享
利用WMI来创建共享,其实是利用Win32_Share
这个类的方法来创建,而不是这个类下面的实例;所谓类就是Win32_Shared
本身,而实例就是Get-WMIObject -Class Win32_Share
所得到的所有对象。(如仍然不明白,请百度WMI)
可以使用Get-WMIObject
命令的-List参数来获取类本身,如下命令将会创建一个名为test3
的本地共享
PS C:\Windows\system32> new-item -Path c:\ -Name test2 -ItemType directory
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2/26/2021 4:54 PM test2
PS C:\Windows\system32> (Get-WmiObject -List -Class win32_share).create("c:\test3","test3",0)
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 0
PSComputerName :
如上,新建的对象实例,ReturnValue为0,说明创建成功,若想更方便的查询ReturnValue的值,可以将所创建的共享保存成变量后再查询,如下
PS C:\Windows\system32>$retObj= (Get-WmiObject -List -Class win32_share).create("c:\test3","test3",0)
PS C:\Windows\system32>$retObj.ReturnValue
查看新建的共享
PS C:\Windows\system32> Get-WmiObject -Class win32_share | ? {$_.name -eq 'test3'} | ft -AutoSize -Wrap
Name Path Description
---- ---- -----------
test3 c:\test3
ReturnValue值的不同含义
- 0 - 创建成功
- 2 - 访问被拒绝
- 8 - 未知错误
- 9 - 名称不可用
- 10 - 等级不可用
- 21 - 参数错误
- 22 - 重复的共享
- 23 - 路径重定向
- 24 - 未知的设备或目录
- 25 - 网络名称未找到
使用WMI创建共享的语法如下
(Get-WmiObject -List -Class win32_share).create(PATH,NAME,SHARETYPE)
具体参数可以通过以下命令来查询PS C:\Windows\system32> ([wmiclass]'win32_share').Create.OverloadDefinitions System.Management.ManagementBaseObject Create(System.String Path, System.String Name, System.UInt32 Type, System.UInt32 MaximumAllowed, System.String Description, System.String Password, System.Management.ManagementObject#Win32_SecurityDescriptor Access)
参数:
PATH:共享的路径,为目标主机本地的绝对路径
NAME:自定义共享名称
SHARETYPE:共享资源的类型共享资源的类型:
- 0 = Disk Drive
- 1 = Print Queue
- 2 = Device * 3 = IPC
- 2147483648 = Disk Drive Admin
- 2147483649 = Print Queue Admin
- 2147483650 = Device Admin
- 2147483651 = IPC Admin
可选参数:
- MaximumAllowed:定义同时访问该共享资源的最大用户数
- Description: 共享资源的描述信息
- Password:为共享资源设置密码
- Acess:定义用户访问权限的安全描述符。一个安全描述符包括权限类型信息,所有者(用户或者组),对资源有什么访问权限
- 使用WMI来创建远程共享
Get-WMIObject
命令原生支持远程主机的WMI管理,只需添加-ComputerName
参数,如下
PS C:\Windows\system32> new-item -Path //dc/c$ -Name test3 -ItemType directory
Directory: \\dc\c$
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2/26/2021 7:10 PM test3
PS C:\Windows\system32> $share=Get-WmiObject win32_share -List -ComputerName dc
PS C:\Windows\system32> $share.create("c:\test3","test3",0)
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 0
PSComputerName :
PS C:\Windows\system32> Get-WmiObject -ComputerName dc -Class win32_share | ? {$_.name -eq 'test3'}
Name Path Description
---- ---- -----------
test3 c:\test3
- 使用WMI删除共享
使用WMI删除共享,由于删除操作是对已有存在的某个共享操作,因此要用到win32_share
对应的具体的实例的delete方法,如下,将把前面建立的本地共享删掉
PS C:\Windows\system32> $share=Get-WmiObject -Class win32_share | ? {$_.name -eq 'test3'}
PS C:\Windows\system32> $share
Name Path Description
---- ---- -----------
test3 c:\test3
PS C:\Windows\system32> $share.Delete()
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 0
PSComputerName :
PS C:\Windows\system32> Get-WmiObject win32_share
Name Path Description
---- ---- -----------
ADMIN$ C:\Windows Remote Admin
C$ C:\ Default share
IPC$ Remote IPC
test C:\Users\huzx\documents\test
- 使用WMI来配置共享的访问权限
在Windows中,权限由安全描述符来管理(SDs)。安全描述符包含所有与共享或者其它对象相关的访问控制信息。当用户尝试访问某个对象时,Windows使用对象的安全描述符来决定用户是否可以访问这个对象。
安全描述符中,自定义的访问控制列表(DACL)是用于访问控制的。DACL包含访问控制条目(ACEs),一条访问控制条目包含以下内容:
- 定义当前ACE条目行为是
Allow
还是deny
- 用户或者组的sid
- 当前ACE条目
Allow
或Deny
的对象,表示为访问掩码
可以通过get-acl
命令列出ACL
PS C:\Windows\system32> $share=Get-WmiObject -ComputerName dc -Class win32_share | ? {$_.name -eq 'test3'}
PS C:\Windows\system32> $share
Name Path Description
---- ---- -----------
test3 c:\test3
PS C:\Windows\system32> $share | get-acl | fl *
PSPath : Microsoft.PowerShell.Core\FileSystem::C:\test3
PSParentPath : Microsoft.PowerShell.Core\FileSystem::C:\
PSChildName : test3
PSDrive : C
PSProvider : Microsoft.PowerShell.Core\FileSystem
CentralAccessPolicyId :
CentralAccessPolicyName :
Path : Microsoft.PowerShell.Core\FileSystem::C:\test3
Owner : BUILTIN\Administrators
Group : buffallos\Domain Users
Access : {System.Security.AccessControl.FileSystemAccessRule, System.Security.AccessControl.FileSystemAccessRule, System.Security.AccessControl.FileSystemAccessRule,
System.Security.AccessControl.FileSystemAccessRule...}
Sddl : O:BAG:DUD:AI(A;OICIID;FA;;;BA)(A;OICIID;FA;;;SY)(A;OICIID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)
AccessToString : BUILTIN\Administrators Allow FullControl
NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Users Allow ReadAndExecute, Synchronize
NT AUTHORITY\Authenticated Users Allow Modify, Synchronize
NT AUTHORITY\Authenticated Users Allow -536805376
AuditToString :
AccessRightType : System.Security.AccessControl.FileSystemRights
AccessRuleType : System.Security.AccessControl.FileSystemAccessRule
AuditRuleType : System.Security.AccessControl.FileSystemAuditRule
AreAccessRulesProtected : False
AreAuditRulesProtected : False
AreAccessRulesCanonical : True
AreAuditRulesCanonical : True
使用WMI配置安全描述符(SDs)需要用到Set-Acl
命令,此命令将与Microsoft .NET Framework classes
共同完成SDs的配置。比如,访问权限(Accessrules)将用到System.Security.AccessControl.FileSystemAccessFule
class,这个类有一个构建access rule
的函数,接受一下参数
- 一个包含访问资源的目标用户的信息的对象(IdentityReference)
- 一种文件访问权限类型值,即定义目标用户分配什么样子的访问权限(FileSystemRight)
- 访问控制类型,即
Allow
或者Deny
(AccessControlType)
为易于理解,请看下面的例子:
PS C:\Windows\system32> $acl = get-acl -Path //dc/c$/test3
PS C:\Windows\system32> $permission = "buffallos\adminhuzx","FullControl","Allow"
PS C:\Windows\system32> $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
PS C:\Windows\system32> $acl.SetAccessRule($accessRule)
PS C:\Windows\system32> $acl | Set-Acl '\\dc\c$\test3'
我们来分析一下上面的过程都做了什么?
PS C:\Windows\system32> $acl = get-acl -Path //dc/c$/test3
使用Get-Acl
检索目录\\dc\c$\test3
当前的ACL信息。ACL
包含有多条ACE
,每条ACE
都描述某个用> 户或组对所应用的资源有何种访问权限。PS C:\Windows\system32> $permission = "buffallos\adminhuzx","FullControl","Allow"
设定文件访问控制权限(FileSystemRule)构造函数所需要的三个参数值,它可接受下面三个参数:
- 当前构造函数将应用到的用户(user)
- 当前构造函数所定义的权限类型,比如创建、列出目录等
- 当前构造函数所定义的权限的访问控制类型,
Allow
或者Deny
PS C:\Windows\system32> $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
使用构建函数构建文件权限
PS C:\Windows\system32> $acl.SetAccessRule($accessRule)
在原来ACL
基础上,添加新的ACE
PS C:\Windows\system32> $acl | Set-Acl '\\dc\c$\test3'
将修改后的ACL
应用到目录上
下面是应用完新ACL
后使用Get-ACL
检索出来的信息,可以看到有关新ACE
已被应用
PS C:\Windows\system32> get-acl -Path '\\dc\c$\test3' | ft -AutoSize -wrap
Directory: \\dc\c$
Path Owner Access
---- ----- ------
test3 BUILTIN\Administrators buffallos\adminhuzx Allow FullControl
NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
BUILTIN\Users Allow ReadAndExecute, Synchronize
BUILTIN\Users Allow AppendData
BUILTIN\Users Allow CreateFiles
CREATOR OWNER Allow 268435456
使用SMBShare
和SMBWitness
模块来管理文件共享
使用之前,先导入相应模块
Import-Module SmbShare
Import-Module SmbWitness
- 使用
SMB
模块枚举当前共享
PS C:\Windows\system32> Invoke-Command -ComputerName dc -ScriptBlock {Get-SmbShare}
Name ScopeName Path Description PSComputerName
---- --------- ---- ----------- --------------
ADMIN$ * C:\Windows 远程管理 dc
C$ * C:\ 默认共享 dc
E$ * E:\ 默认共享 dc
IPC$ * 远程 IPC dc
NETLOGON * C:\Windows\SYSVOL\sysvol\buffallos.com\SCRIPTS Logon server share dc
SYSVOL * C:\Windows\SYSVOL\sysvol Logon server share dc
test * c:\test dc
test1 * c:\test1 smbshare test1 dc
test3 * c:\test3 dc
- 使用
SMB
模块创建本地共享
可以使用New-SmbShare
命令来创建本地共享,至少提供共享名称和路径
PS C:\Windows\system32> New-SmbShare -Name "test4" -Path "c:\"
Name ScopeName Path Description
---- --------- ---- -----------
test4 * c:\
PS C:\Windows\system32> Get-SmbShare
Name ScopeName Path Description
---- --------- ---- -----------
ADMIN$ * C:\Windows Remote Admin
C$ * C:\ Default share
IPC$ * Remote IPC
test * C:\Users\huzx\documents\test
test4 * c:\
可以定义共享的描述信息和预定义权限,例如
PS C:\Windows\system32> new-item -Path c:\ -name test6 -ItemType directory
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/1/2021 10:54 AM test6
PS C:\Windows\system32> New-SmbShare -Name "test6" -Path "c:\test6" -Description "Test6 shared" -FullAccess buffallos\adminhuzx -ReadAccess everyone
Name ScopeName Path Description
---- --------- ---- -----------
test6 * c:\test6 Test6 shared
PS C:\Windows\system32> Get-SmbShareAccess -Name test6
Name ScopeName AccountName AccessControlType AccessRight
---- --------- ----------- ----------------- -----------
test6 * buffallos\adminhuzx Allow Full
test6 * Everyone Allow Read
```PS C:\Windows\system32> Get-SmbShareAccess -Name test6
Name ScopeName AccountName AccessControlType AccessRight
---- --------- ----------- ----------------- -----------
test6 * buffallos\adminhuzx Allow Full
test6 * Everyone Allow Read
- 使用
SMB
模块创建远程共享
使用New-SMBShare
有两种方法可以实现远程共享的创建
- 使用
-Cimsession
参数
PS C:\Windows\system32> New-Item -Path //dc/c$ -name test6 -ItemType directory Directory: \\dc\c$ Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 3/1/2021 1:34 PM test6 PS C:\Windows\system32> New-SmbShare -Name test6 -CimSession DC -Path c:\test6 -FullAccess "buffallos\adminhuzx" -ChangeAccess everyone -Description "Test6 on DC" Name ScopeName Path Description PSComputerName ---- --------- ---- ----------- -------------- test6 * c:\test6 Test6 on DC DC PS C:\Windows\system32> get-smbshare -Name test6 -CimSession dc | ft -AutoSize -wrap Name ScopeName Path Description PSComputerName ---- --------- ---- ----------- -------------- test6 * c:\test6 Test6 on DC dc PS C:\Windows\system32> Get-SmbShareAccess -Name test6 -CimSession dc Name ScopeName AccountName AccessControlType AccessRight PSComputerName ---- --------- ----------- ----------------- ----------- -------------- test6 * buffallos\adminhuzx Allow Full dc test6 * Everyone Allow Change dc
- 使用
PowerShell
的Invoke-Command
命令
PS C:\Windows\system32> Invoke-Command -ComputerName dc -ScriptBlock {new-item -Path c:\ -Name test7 -ItemType directory;New-SmbShare -Name "Test7" -Path c:\test7 -FullAccess "buffallos\adminhuzx" -ChangeAccess everyone -Description "Test7 on DC"} Directory: C:\ Mode LastWriteTime Length Name PSComputerName ---- ------------- ------ ---- -------------- d----- 3/1/2021 1:44 PM test7 dc PresetPathAcl : System.Security.AccessControl.DirectorySecurity PSComputerName : dc RunspaceId : 2258cb4b-7968-4a03-a66b-1fe80e8ba5ee AvailabilityType : NonClustered CachingMode : Manual CATimeout : 0 ConcurrentUserLimit : 0 ContinuouslyAvailable : False CurrentUsers : 0 Description : Test7 on DC EncryptData : False FolderEnumerationMode : Unrestricted Name : Test7 Path : c:\test7 Scoped : False ScopeName : * SecurityDescriptor : O:SYG:SYD:(A;;FA;;;S-1-5-21-1922697842-2877171228-2226451015-1107)(A;;0x1301bf;;;WD) ShadowCopy : False ShareState : Online ShareType : FileSystemDirectory SmbInstance : Default Special : False Temporary : False Volume : \\?\Volume{d524dd8e-0000-0000-0000-501f00000000}\ LeasingMode : PS C:\Windows\system32> Get-SmbShare -Name test7 -CimSession dc | ft -AutoSize -Wrap Name ScopeName Path Description PSComputerName ---- --------- ---- ----------- -------------- Test7 * c:\test7 Test7 on DC dc PS C:\Windows\system32> Get-SmbShareAccess -Name test7 -CimSession DC Name ScopeName AccountName AccessControlType AccessRight PSComputerName ---- --------- ----------- ----------------- ----------- -------------- Test7 * buffallos\adminhuzx Allow Full DC Test7 * Everyone Allow Change DC
- 使用
SMBShare
模块删除共享
删除共享可以使用Remove-SmbShare
后面直接跟共享名即可
PS C:\Windows\system32> Remove-SmbShare -Name test6
PS C:\Windows\system32> Get-SmbShare
Name ScopeName Path Description
---- --------- ---- -----------
ADMIN$ * C:\Windows Remote Admin
C$ * C:\ Default share
IPC$ * Remote IPC
test * C:\Users\huzx\documents\test
test4 * c:\
test5 * c:\
要删除远程主机上的共享,只需使用-Cimsession
指定主机名称即可
PS C:\Windows\system32> Get-SmbShare -CimSession dc
Name ScopeName Path Description PSComputerName
---- --------- ---- ----------- --------------
ADMIN$ * C:\Windows 远程管理 dc
C$ * C:\ 默认共享 dc
E$ * E:\ 默认共享 dc
IPC$ * 远程 IPC dc
NETLOGON * C:\Windows\SYSVOL\sysvol\buffallos.com\SCRIPTS Logon server share dc
SYSVOL * C:\Windows\SYSVOL\sysvol Logon server share dc
test * c:\test dc
test1 * c:\test1 smbshare test1 dc
test3 * c:\test3 dc
test6 * c:\test6 Test6 on DC dc
Test7 * c:\test7 Test7 on DC dc
PS C:\Windows\system32> Remove-SmbShare -CimSession dc -Name test6
PS C:\Windows\system32> Get-SmbShare -CimSession dc
Name ScopeName Path Description PSComputerName
---- --------- ---- ----------- --------------
ADMIN$ * C:\Windows 远程管理 dc
C$ * C:\ 默认共享 dc
E$ * E:\ 默认共享 dc
IPC$ * 远程 IPC dc
NETLOGON * C:\Windows\SYSVOL\sysvol\buffallos.com\SCRIPTS Logon server share dc
SYSVOL * C:\Windows\SYSVOL\sysvol Logon server share dc
test * c:\test dc
test1 * c:\test1 smbshare test1 dc
test3 * c:\test3 dc
Test7 * c:\test7 Test7 on DC dc
5.使用SMBShare
模块来配置访问权限
由上面的创建共享的例子看到,New-SMBShare
可以通过参数进行预设置权限,相关参数:
- -FullAccess
- -ChangeAccess
- -ReadAccess
- -NoAccess
见文知义,上面的参数都很好理解;但是更为精细的权限分配却无能为力,这个时候咱们就可以使用Grant-SMBShareAccess
命令来设置权限。为完成权限的分配,该命令有两个参数:
- -AccountName 需要分配权限的用户或者组
- -AccessRight 需要分配给目标用户或组什么权限,可以接受的值为
Full
,Change
和Read
PS C:\Windows\system32> Get-SmbShareAccess -name test
Name ScopeName AccountName AccessControlType AccessRight
---- --------- ----------- ----------------- -----------
test * Everyone Allow Read
PS C:\Windows\system32> Grant-SmbShareAccess -name test -AccountName "buffallos\adminhuzx" -AccessRight Full
Name ScopeName AccountName AccessControlType AccessRight
---- --------- ----------- ----------------- -----------
test * Everyone Allow Read
test * buffallos\adminhuzx Allow Full
若需要吊销某个用户的权限,可以使用Revoke-SmbShareAccess
命令
PS C:\Windows\system32> Grant-SmbShareAccess -name test -AccountName "buffallos\adminhuzx" -AccessRight Full
Name ScopeName AccountName AccessControlType AccessRight
---- --------- ----------- ----------------- -----------
test * Everyone Allow Read
test * buffallos\adminhuzx Allow Full
PS C:\Windows\system32> Revoke-SmbShareAccess -Name test -AccountName "buffallos\adminhuzx"
Name ScopeName AccountName AccessControlType AccessRight
---- --------- ----------- ----------------- -----------
test * Everyone Allow Read
Grant-SmbShareAccess
与Revoke-SmbShareaccess
同样拥有-CimSession
参数,以实现远程共享的管理