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参数,以实现远程共享的管理