44CON议题解析:使用PowerShell掌控活动目录

2015-09-25 267548人围观 ,发现 9 个不明物体 头条

本文特约作者:丝绸之路

0×00 议题介绍

本议题的演讲人是DAn Solutions 公司的CTO——肖恩·梅特卡夫,他拥有多项微软认证,也是微软近20年的咨询顾问,曾设计并实施了涉及Active Directory、Exchange、SharePoint以及网络与系统安全的解决方案。

本议题讨论的内容并不是关于活动目录和PowerShell的教程,其目的是激发大家去思考如何使活动目录更好的工作,并且本次议题将会带来大量的PowerShell示例代码,至于怎么用取决于你。

议题的议程如下:

通过PowerShell与活动目录对接
与AD相关的PowerShell Cmdlets
林 & 域的发现
有用的AD Cmdlets
计算机,用户和组
有趣儿的AD配置数据
服务帐户
域控制器 & 全局编录器
域控制器复制能力
提示与技巧

注:整个议题的内容主要是在阐述如何使用PowerShell来管理AD以及 DC、GC等内网常见的服务模块,从正面来看,有助于网络管理员更好更快的管理内网服务,反过来看,作为一个入侵者,也能够使用本议题所讲的内容快速了解内网的服务从而进一步的快速准确的渗透内网。

0×01 POWERSHELL & ACTIVE DIRECTORY

POWERSHELL:

Windows PowerShell是微软公司为Windows环境所开发的壳程序(shell)及脚本语言技术,采用的是命令行界面。这项全新的技术提供了丰富的控制与自动化的系统管理能力。cmdlet是Windows PowerShell的指令,发音念法为command-let。这相当于DOS或其他壳程序的内置指令,指令名称的格式都是以连字号(-)隔开的一对动词和名词,并且通常都是单数名词;例如在线查询说明的cmdlet指令为get-help,名称的动词部分大致有get、set、add、remove等等(字母都不分大小写)。

PowerShell v1版本支持了NET,ADSI等管理模型。

PowerShell v2版本在 PowerShell Active Directory 模块做了一些更新,如下:

• Import-module servermanager;
add-windowsfeature rsat-ad-tools
• Import-module servermanager;
add-windowsfeature rsat-ad-PowerShell

.NET

.NET框架(.NET Framework)是由微软开发,一个致力于敏捷软件开发、快速应用开发、平台无关性和网络透明化的软件开发平台。.NET是微软为2000年代对服务器和桌面型软件工程迈出的第一步。.NET包含许多有助于互联网和内部网应用迅捷开发的技术。.NET框架是以一种采用系统虚拟机运行的编程平台,以通用语言运行库(Common Language Runtime)为基础,支持多种语言的开发。应用程序虚拟机将提供安全,内存管理和异常处理等服务,框架类库(FCL)和通用语言运行时(CLR)共同组成了.NET框架。

与活动目录有关的.NET:

• 获取当前域:
    [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
    [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().Name
• 获取计算机的站点:
    [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite()
• 列出域中所有的域控制器:
    [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers
• 获取AD域模式:
    [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainMode
• 列出AD FSMO:
    ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).SchemaRoleOwner
    ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).NamingRoleOwner
    ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).InfrastructureRoleOwner
    ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).PdcRoleOwner
    ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).RidRoleOwner
• 获取AD林名称:
    [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Name
• 获取AD林中的站点列表:
    [array] $ADSites = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites
• 获取AD林中的域:
    [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Domains
• 获取AD林中的全局编录器:
    [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().GlobalCatalogs
• 获取AD林模式:
    [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().ForestMode
• 获取AD林中的根域:
    [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().RootDomain

古老的ADSI:

活动目录服务接口(ADSI)是一个用于访问不同网络提供程序目录服务特性的COM接口的集合。ADSI用户分布式计算环境为管理网络资源呈现一个单一的目录服务接口。管理员和开发者可以使用ADSI服务列举并管理目录服务的资源,不管哪种网络包含了这种资源。

ADSI示例代码:

 $UserID = “JoeUser”
 $root = [ADSI]''
 $searcher = new-object System.DirectoryServices.DirectorySearcher($root)
 $searcher.filter = "(&(objectClass=user)(sAMAccountName= $UserID))"
 $user = $searcher.findall()
 $user

POWERSHELL 中与AD相关的模块:

•将AD Web 服务(ADWS)运行在域控制器上(TCP 9389):

    Get-ADDomainController –Discover –Service “ADWS”

•在域控制器上通过HTTP 传输 SOAP XML 消息

•与AD相关的Cmdlet示例代码:

0×02 与AD相关的PowerShell Cmdlets

可以使用下列命令列出可用的Cmdlsets

 Get-Module -ListAvailable
 Get-Command -module ActiveDirectory

• PowerShell中与 AD 模块有关的 Cmdlets:

     Windows Server 2008 R2: 76 个 cmdlets    
     Windows Server 2012: 135 个 cmdlets
     Windows Server 2012 R2: 147 个 cmdlets

以下是在WINDOWS SERVER 2008 R2上常用的Cmdlets:

• Get/Set-ADForest
• Get/Set-ADDomain
• Get/Set-ADDomainController
• Get/Set-ADUser
• Get/Set-ADComputer
• Get/Set-ADGroup
• Get/Set-ADGroupMember
• Get/Set-ADObject
• Get/Set-ADOrganizationalUnit
• Enable-ADOptionalFeature
• Disable/Enable-ADAccount
• Move-ADDirectoryServerOperationMasterRole
• New-ADUser
• New-ADComputer
• New-ADGroup
• New-ADObject
• New-ADOrganizationalUnit

下面是在WINDOWS SERVER 2012+上新提供的Cmdlets(部分):

• *-ADResourcePropertyListMember
• *-ADAuthenticationPolicy
• *-ADAuthenticationPolicySilo
• *-ADCentralAccessPolicy
• *-ADCentralAccessRule
• *-ADResourceProperty
• *-ADResourcePropertyList
• *-ADResourcePropertyValueType
• *-ADDCCloneConfigFile
• *-ADReplicationAttributeMetadata
• *-ADReplicationConnection
• *-ADReplicationFailure
• *-ADReplicationPartnerMetadata
• *-ADReplicationQueueOperation
• *-ADReplicationSite
• *-ADReplicationSiteLink
• *-ADReplicationSiteLinkBridge
• *-ADReplicationSubnet
• *-ADReplicationUpToDatenessVectorTable
• Sync-ADObject

0×03 发现AD的几种方式

GET-ADROOTDSE:

GET-ADFOREST:

GET-ADDOMAIN:

GET-ADDOMAINCONTROLLER:

GET-ADCOMPUTER:

0×04 计算机,用户和组的管理操作

快速统计AD 中计算机的数量:

示例代码:

$Time = (Measure-Command `{[array] $AllComputers = Get-ADComputer -filter * -properties Name,CanonicalName,Enabled,passwordLastSet,SAMAccountName,LastLogonTimeStamp,DistinguishedName,OperatingSystem}).TotalMinutes
$AllComputersCount = $AllComputers.Count
Write-Output “There were $AllComputersCount Computers discovered in $DomainDNS in $Time minutes… `r ”

找出不活跃的计算机:

获取用户信息 GET-ADUSER:

AD域用户统计:

示例代码:

Import-Module ActiveDirectory
$DomainDNS = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
[array]$AllUsers = Get-ADUser -filter * -properties Name,DistinguishedName,Enabled,LastLogonDate,LastLogonTimeStamp,LockedOut,msExchHomeServerName,SAMAccountName
$AllUsersCount = $AllUsers.Count
Write-Output “There were $AllUsersCount user objects discovered in $ADDomainDNSRoot … ”
 
[array]
$DisabledUsers = $AllUsers | Where-Object { $_.Enabled -eq $False }
$DisabledUsersCount = $DisabledUsers.Count
 
[array] $EnabledUsers = $AllUsers | Where-Object { $_.Enabled -eq $True }
$EnabledUsersCount = $EnabledUsers.Count
Write-Output “There are $EnabledUsersCount Enabled users and there are $DisabledUsersCount Disabled users in $DomainDNS ”

找出不活跃的用户帐号:

找出使用了ANP的用户:

•Ambiguos 名称解析(ANR)被Outlook用于寻找用户

Import-Module ActiveDirectory

Get-ADObject -LDAPFilter { (&(ObjectClass=User)(ANR=Thor) ) }

• ANR 查询 将与如下有索引的属性进行对比:

• sAMAccountName
• displayName
• Name (cn)
• givenName (first name)
• sn (surname aka last name)
• legacyExchangeDN
• proxyAddresses (Exchange attribute)

获取和设置 AD 属性

•查找所有用户并显示 $AttributeName

• Get-ADUser -filter * -SearchBase $SourceOU -properties *,$AttributeName

•查找所有$AttributeName = $AttributeValue的用户

• Get-ADUser -filter { $_.”$AttributeName” -eq $AttributeValue } -properties $AttributeName

•查找所有$AttributeName存在值的用户

• Get-ADUser -filter { $AttributeName –like “*” } –prop $AttributeName

•更新指定用户$User 的指定属性名称$AttributeName 为 "$AttributeValue"

• Set-ADUser $User -replace @{ "$AttributeName" = "$AttributeValue" }

获取指定组的信息 GET-ADGROUP:

获取AD 域用户组的统计信息:

[array]$AllADGroups = Get-ADGroup -Filter * -Properties *
$AllADGroupsCount = $AllADGroups.Count
Write-Output “There are $AllADGroupsCount Total groups in AD `r ”
 
[array]$ADUniversalGroups = $AllADGroups | Where {$_.GroupScope -eq “Universal” }
[int]$ADUniversalGroupsCount = $ADUniversalGroups.Count
Write-Output “There are $ADUniversalGroupsCount Universal groups in AD ”
 
[array]$ADSecurityGroups = $AllADGroups | Where {$_.GroupCategory -eq “Security” }
$ADSecurityGroupsCount = $ADSecurityGroups.Count
Write-Output “There are $ADSecurityGroupsCount Security groups in AD ”

获取AD组中的成员 GET-ADGROUPMEMBER:

获取登录时间的同步间隔:

获取 AD 实例化日期:

获取AD 密码策略:

获取 AD 墓碑生存周期:

0×05 AD的配置——回收站

• 要求林的功能模式为Windows Server 2008 R2

• 开启回收站 (作为企业管理员):

Enable-ADOptionalFeature –Identity ‘CN=Recycle Bin Feature,CN=Optional Features,CN=Directory
Service,CN=Windows NT,CN=Services,CN=Configuration,DC=DOMAIN,DC=COM’ –Scope ForestOrConfigurationSet –Target ‘DOMAIN.COM’

• 查找所有已删除的用户:

$DeletedUsers = Get-ADObject -SearchBase “CN=Deleted Objects,DC=DOMAIN,DC=COM” -Filter {ObjectClass -eq “user”} -IncludeDeletedObjects -Properties lastKnownParent

• 恢复所有已删除的用户:

$DeletedUsers | Restore-ADObject

• 恢复在指定日期被删除的用户:

$ChangeDate = Get-Date (“1/1/2015″)
Get-ADObject -Filter { (whenChanged -eq $changeDate) -and (isDeleted -eq $true) -and (name -ne “Deleted Objects”) -and (ObjectClass -eq “user”) } -IncludeDeletedObjects -Properties * | RestoreADObject

获取域的相对标识符(RID)状态:

列举域的信任关系:

获取AD 站点:

备份域的组策略对象(GPO):

Import-module GroupPolicy
Backup-GPO –All –Domain “mlab.adsecurity.org” –Path “c:\GPOBackup”

0×06 获取服务账户

下面是获取MSSQL服务的服务帐户:

更多详细的脚本清单可以在这找到:

https://github.com/PyroTek3/PowerShell-AD-Recon/blob/master/Find-PSServiceAccounts

使用“SQL”发现AD中的服务:

SQL SERVER服务器的清单:

完整的脚本代码可以在这找到:

https://github.com/PyroTek3/PowerShell-AD-Recon/blob/master/Discover-PSMSSQLServers

0×07 域控制器(DC) &  全局编录器(GC)

发现域控制器:

• 发现域中的主域控制器(PDC):

Get-ADDomainController –Discover –ForceDiscover –Service “PrimaryDC” –DomainName “lab.adsecurity.org”

• 发现站点中的域控制器:

Get-ADDomainController –Discover –Site “HQ”

• 查找所有为全局编录器(GC)只读的域控制器:

Get-ADDomainController –filter `{ (isGlobalCatalog –eq $True) –AND (isReadOnly –eq $True) }

发现全局编录器(GC):

• 林全局编录器:

import-module ActiveDirectory
$ADForest = Get-ADForest
$ADForestGlobalCatalogs = $ADForest.GlobalCatalogs

• 获取域中是全局编录器的域控制器:

import-module ActiveDirectory
$DCsNotGCs = Get-ADDomainController -filter { IsGlobalCatalog -eq $True}

• 获取域中不是全局编录器的域控制器:

import-module ActiveDirectory
$DCsNotGCs = Get-ADDomainController -filter { IsGlobalCatalog -eq $False }

活动目录数据库的完整性检查:

Write-Output "Checking the NTDS database for errors (semantic database analysis) `r "
Stop-Service ntds -force
$NTDSdbChecker = ntdsutil "activate instance ntds" "semantic database analysis" "verbose on" "Go" q q
Start-Service ntds
Write-Output "Results of Active Directory database integrity check: `r "
$NTDSdbChecker

查找灵活单一主机操作(FSMOS):

• 活动目录 Cmdlets

Import-Module ActiveDirectory
(Get-ADForest).SchemaMaster
(Get-ADForest).DomainNamingMaster
(Get-ADDomain).InfrastructureMaster
(Get-ADDomain).PDCEmulator
(Get-ADDomain).RIDMaster

• .Net 获取方法

([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).SchemaRoleOwner
([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).NamingRoleOwner
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).InfrastructureRoleOwner
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).PdcRoleOwner
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).RidRoleOwner

迁移FSMOS:

•另外一种使用PowerShell把FSMO角色从一个域控制器迁移到另一个域控制器的办法:

get-command -module activedirectory -noun *Master*

• 迁移 FSMO 角色:

Move-ADDirectoryServerOperationMasterRole -Identity $DCName -OperationMasterRole RIDMaster
Move-ADDirectoryServerOperationMasterRole -Identity $DCName -OperationMasterRole DomainNamingMaster
Move-ADDirectoryServerOperationMasterRole -Identity $DCName -OperationMasterRole PDCEmulator

• 抓取FSMO角色:

Move-ADDirectoryServerOperationMasterRole -Identity $DCName -OperationMasterRole PDCEmulator –
FORCE

0×08 域控制器复制能力

活动目录管理工具——Repadmin与POWERSHELL的对比如下:

以下是Windows Server 2012上关于活动目录复制的Cmdlets:

GET-ADREPLICATIONPARTNERMETADATA:

GET-ADREPLICATIONPARTNERFAILURE:

GET-ADREPLICATIONUPTODATENESSVECTORTABLE:

0×09 提示与技巧

• 至少每周执行一次备份GPO的计划任务

• ADSI的属性是区别大小写的

• 属性中如果有空格或特殊字符需要用引号括起来:

 $Object.“Property with spaces”

• PowerShell远程管理使用5985(http)和5986(https)端口

• 不要在组策略偏好设置中使用凭证 (MS14-025)

0x0A 译者总结

看完了整个议题的内容,读者可能会认为此议题没有讨论或者提出任何新的思路或者技术,甚至与“黑客技术”毫不沾边,但是这并不意味着这样的议题毫无价。在Windows Server 2008和Windows Server 2012逐渐普及的形势下,掌握有关PowerShell,AD,DC等知识是很有必要的,“Know it than hack it”,在存在域的内网中,域控是入侵者的必争之地,如何快速找到域控,如何拿下域控权限又如何对域控进行持久化的控制,都是在掌握了相关知识之后才能解决的。还是引用原议题中的那句话——“how it's used is up to you! :=)”

* 作者:丝绸之路,本文属FreeBuf原创奖励计划文章,未经许可禁止转载

相关推荐
发表评论

已有 9 条评论

取消
Loading...

文章目录

    特别推荐

    推荐关注

    官方公众号

    聚焦企业安全

    填写个人信息

    姓名
    电话
    邮箱
    公司
    行业
    职位
    css.php