fox-it/skrapa

GitHub: fox-it/skrapa

一个零依赖的跨平台 Python 库,用于扫描 Windows 和 Linux 进程内存,支持按内存属性过滤和 YARA 规则匹配。

Stars: 66 | Forks: 5

# Skrapa Skrapa 是一个零依赖且可定制的 Python 库,用于扫描 Windows 和 Linux 进程内存。 # 目录 - [安装](#installation) - [快速入门](#quickstart) - [工作原理](#how-it-works) - [用法](#usage) - [扫描 PID](#scanning-a-pid) - [使用 YARA 扫描](#scan-using-yara) - [页面过滤器](#page-filters) - [功能](#features) ## 安装 可以使用 `pip` 进行安装: ``` $ pip install skrapa ``` 您也可以通过安装 `yara` 变体来包含 YARA 支持: ``` $ pip install skrapa[yara] ``` ## 快速入门 安装库后,使用给定的进程 ID 开始扫描: ``` python examples/scan_pid.py --pid 8320 --hex 0000488B0557F402004833C448894424 --protect PAGE_EXECUTE_READ --alloc-protect PAGE_EXECUTE_WRITECOPY --type MEM_IMAGE --state MEM_COMMIT ``` ## 工作原理 Skrapa 与传统意义上的内存扫描略有不同,它允许您根据特定的内存属性进行过滤,这可以大大减少扫描进程内存所需的时间。 在 Windows 和 Linux 平台上,分配给特定进程的内存区域各自拥有一组权限。这些权限基本上可以归结为我们熟知且喜爱的权限:`READ`、`WRITE` 和 `EXECUTE`。在进程内存中,这些权限可以组合使用,因为当我们希望从该内存区域执行代码时,某些进程内存需要既可读又可执行。 该 API 旨在保持透明,因此无论脚本是针对 Windows 还是 Linux 编写的都没有关系(唯一的例外是某个仅在 Windows 上可用的权限)。 ## 用法 ### 扫描 PID 让我们尝试在 Windows 上扫描十六进制模式 `0000488B0557F402004833C448894424`。为了加快扫描过程,我们假设该模式所在的区域设置了以下内存权限: + Protect: `PAGE_EXECUTE_READ` + Allocation Protect: `PAGE_EXECUTE_WRITECOPY` + Type: `MEM_IMAGE` + State: `MEM_COMMIT` 任何未设置这些权限的内存区域都将被排除在匹配过程之外,从而提高扫描速度。此类扫描的样板代码如下所示: ``` from skrapa import AccessProtectionType, HexPattern, MemoryAttributes, scan_pid mem_attributes = MemoryAttributes( protect=AccessProtectionType.PAGE_EXECUTE_READ, allocation_protect=AccessProtectionType.PAGE_EXECUTE_WRITECOPY, type=AllocationType.MEM_IMAGE, state=AllocationType.MEM_COMMIT, ) for hit in scan_pid(pid=8320, patterns=HexPattern("0000488B0557F402004833C448894424"), attributes=mem_attributes): print(hit) ``` 对于模式上的每次命中,我们可以查看属于该进程的不同属性: + Process name: `hit.process.name` + Process path: `hit.process.path` + Process architecture: `hit.process.architecture` 或者对于相关的内存区域: + Memory region start: `hit.region_start` + Memory region size: `hit.region_size` + Memory region end: `hit.region_start + hit.region_size` + Address of the match: `hit.address` 我们可以从模式匹配的起始位置读取 128 个字节,因为我们可能知道该模式之后会有一些有趣的信息: ``` from skrapa import read_process_memory match_content = read_process_memory(pid=8320, address=hit.address, size=128) ``` 然后,您可以对这些字节进行任何所需的后处理。 ### 使用 YARA 扫描 注意:要使用 Skrapa 的 YARA 功能,您需要安装 `yara-python`。您可以手动安装,或者运行 `pip install skrapa[yara]`。 我们继续利用 YARA 在 `notepad.exe` 的进程内存中查找模式。在 Skrapa 中使用 YARA 规则非常简单,只需指向包含您要在进程内存中匹配的规则的 YARA 文件即可。我们在本示例中使用的 YARA 规则是: ``` rule l33t_notepad_rule { strings: $ = { 00 00 48 8B 05 57 F4 02 00 48 33 C4 48 89 44 24 } condition: any of them } ``` 我们可以使用上面的 YARA 规则在进程内存中查找该模式: ``` from skrapa import AccessProtectionType, MemoryAttributes, scan_pid try: import yara except ImportError: logging.error("YARA Python module not found, install it with: pip install yara-python") exit(1) mem_attributes = MemoryAttributes( protect=AccessProtectionType.PAGE_EXECUTE_READ, allocation_protect=AccessProtectionType.PAGE_EXECUTE_WRITECOPY, type=AllocationType.MEM_IMAGE, state=AllocationType.MEM_COMMIT, ) patterns = yara.compile( source="rule l33t_notepad { strings: $ = {0000488B0557F402004833C448894424} condition: any of them }" ) for hit in scan_pid(pid=8320, patterns=patterns, attributes=mem_attributes): print(hit) ``` 上述扫描结果的使用方式与前面展示的示例完全相同。如果您更愿意从指定文件加载 YARA,可以将 `yara.compile` 调用中的 `source=` 参数替换为 `filepath=`。 ### 页面过滤器 Skrapa 允许用户通过使用回调函数来定义更复杂的内存过滤条件。回调函数还可用于在尝试匹配给定模式之前检查内存区域的大小。 在本例中,我们将定义以下 `page_filter` 函数,它将首先检查: + 给定区域是否大于 `0x300000` 且小于 `0x400000` + 给定区域是否未设置 `PAGE_NOACCESS` 保护属性 + 给定区域是否设置了 `PAGE_READWRITE` 保护属性 请注意,在使用上述 `page_filter` 定义时,我们将不提供任何内存属性,而是在函数中定义每个条件: ``` from skrapa import AccessProtectionType, HexPattern, MemoryAttributes, scan_pid def page_filter(pageinfo) -> bool: return ( 0x300000 > pageinfo.size <= 0x400000 and pageinfo.attributes.protect.name != "PAGE_NOACCESS" and pageinfo.attributes.protect.name == "PAGE_READWRITE" ) mem_attributes = MemoryAttributes(protect=None, allocation_protect=None, type=None, state=None) for hit in scan_pid(pid=8320, patterns=HexPattern("0000488B0557F402004833C448894424"), attributes=mem_attributes, page_filter=page_filter): print(hit) ``` 现在,只有满足 `page_filter` 条件时,我们才会收到命中。 查看 `examples/` 文件夹以快速上手! ## 功能 + 支持 x86 和 x64 Windows 及 Linux 平台; + 按名称或 PID 扫描单个进程,或扫描整个内存空间; + 支持 YARA 签名; + 支持用于更复杂条件的页面过滤器;
标签:DNS信息、DNS暴力破解, Linux内存, PAGE_EXECUTE_READ, SecList, Windows内存, YARA规则, 云资产清单, 内存取证, 内存扫描, 内存搜索, 内存权限, 十六进制模式, 后渗透, 攻击路径可视化, 数字取证, 流量嗅探, 网络安全审计, 自动化脚本, 进程内存, 逆向工具, 逆向工程, 零依赖, 黑客工具