非常干货:Python 探针实现原理

从CVE-2024-38077漏洞原理到Python轻量级RCE扫描工具实战 远程代码执行(RCE)漏洞是网络安全领域的高危威胁,其原理在于攻击者能够通过网络在目标系统上执行任意代码,从而获得系统控制权。这类漏洞的技术价值在于其破坏性极强,常被用于数据窃取、横向移动和勒索攻击。在应用场景上,RCE漏洞的检测与防护是企业安全运维的核心工作,尤其对于Windows Server等广泛使用的服务器系统。本文聚焦于CVE-2024-38077这一具体的Windows远程桌面服务RCE漏洞,深入解析其触发原理与影响范围,并详细阐述如何基于Python开发一款轻量级、针对性的漏洞扫描工具。该工具 阅读详情

前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

PS:如有需要Python学习资料的小伙伴可以点击下方链接自行获取

Python免费学习资料、代码以及交流解答点击即可加入


 

本文呢,将简单讲述一下 Python 探针的实现原理。同时为了验证这个原理,我们也会一起来实现一个简单的统计指定函数执行时间的探针程序。

探针的实现主要涉及以下几个知识点:

  • sys.meta_path
  • sitecustomize.py

sys.meta_path

sys.meta_path 这个简单的来说就是可以实现 import hook 的功能, 当执行 import 相关的操作时,会触发 sys.meta_path 列表中定义的对象。关于 sys.meta_path 更详细的资料请查阅 python 文档中 sys.meta_path 相关内容以及 PEP 0302 。

sys.meta_path 中的对象需要实现一个 find_module 方法, 这个 find_module 方法返回 None 或一个实现了 load_module 方法的对象 (代码可以从 github 上下载 part1_) :

import sys

class MetaPathFinder:

    def find_module(self, fullname, path=None):
        print('find_module {}'.format(fullname))
        return MetaPathLoader()

class MetaPathLoader:

    def load_module(self, fullname):
        print('load_module {}'.format(fullname))
        sys.modules[fullname] = sys
        return sys

sys.meta_path.insert(0, MetaPathFinder())

if __name__ == '__main__':
    import http
    print(http)
    print(http.version_info)

load_module 方法返回一个 module 对象,这个对象就是 import 的 module 对象了。比如我上面那样就把 http 替换为 sys 这个 module 了。

$ python meta_path1.py
find_module http
load_module http
<module 'sys' (built-in)>
sys.version_info(major=3, minor=5, micro=1, releaselevel='final', serial=0)

通过 sys.meta_path 我们就可以实现 import hook 的功能:当 import 预定的 module 时,对这个 module 里的对象来个狸猫换太子, 从而实现获取函数或方法的执行时间等探测信息。

上面说到了狸猫换太子,那么怎么对一个对象进行狸猫换太子的操作呢?对于函数对象,我们可以使用装饰器的方式来替换函数对象(代码可以从 github 上下载 part2) :

import functools
import time

def func_wrapper(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print('start func')
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print('spent {}s'.format(end - start))
        return result
    return wrapper

def sleep(n):
    time.sleep(n)
    return n

if __name__ == '__main__':
    func = func_wrapper(sleep)
    print(func(3))

执行结果:

$ python func_wrapper.py
start func
spent 3.004966974258423s
3

下面我们来实现一个计算指定模块的指定函数的执行时间的功能(代码可以从 github 上下载 part3) 。

假设我们的模块文件是 hello.py:

import time

def sleep(n):
    time.sleep(n)
    return n

我们的 import hook 是 hook.py:

import functools
import importlib
import sys
import time

_hook_modules = {'hello'}

class MetaPathFinder:

    def find_module(self, fullname, path=None):
        print('find_module {}'.format(fullname))
        if fullname in _hook_modules:
            return MetaPathLoader()

class MetaPathLoader:

    def load_module(self, fullname):
        print('load_module {}'.format(fullname))
        # ``sys.modules`` 中保存的是已经导入过的 module
        if fullname in sys.modules:
            return sys.modules[fullname]

        # 先从 sys.meta_path 中删除自定义的 finder
        # 防止下面执行 import_module 的时候再次触发此 finder
        # 从而出现递归调用的问题
        finder = sys.meta_path.pop(0)
        # 导入 module
        module = importlib.import_module(fullname)

        module_hook(fullname, module)

        sys.meta_path.insert(0, finder)
        return module

sys.meta_path.insert(0, MetaPathFinder())

def module_hook(fullname, module):
    if fullname == 'hello':
        module.sleep = func_wrapper(module.sleep)

def func_wrapper(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print('start func')
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print('spent {}s'.format(end - start))
        return result
    return wrapper

测试代码:

>>> import hook
>>> import hello
find_module hello
load_module hello
>>>
>>> hello.sleep(3)
start func
spent 3.0029919147491455s
3
>>>

其实上面的代码已经实现了探针的基本功能。不过有一个问题就是上面的代码需要显示的 执行 import hook 操作才会注册上我们定义的 hook。

那么有没有办法在启动 python 解释器的时候自动执行 import hook 的操作呢?答案就是可以通过定义 sitecustomize.py 的方式来实现这个功能。

sitecustomize.py

简单的说就是,python 解释器初始化的时候会自动 import PYTHONPATH 下存在的 sitecustomize 和 usercustomize 模块:

实验项目的目录结构如下(代码可以从 github 上下载 part4) :

$ tree
.
├── sitecustomize.py
└── usercustomize.py

sitecustomize.py:

$ cat sitecustomize.py
print('this is sitecustomize')

usercustomize.py:

$ cat usercustomize.py
print('this is usercustomize')

把当前目录加到 PYTHONPATH 中,然后看看效果:

$ export PYTHONPATH=.
$ python
this is sitecustomize       <----
this is usercustomize       <----
Python 3.5.1 (default, Dec 24 2015, 17:20:27)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

可以看到确实自动导入了。所以我们可以把之前的探测程序改为支持自动执行 import hook (代码可以从 github 上下载 part5) 。
目录结构:

$ tree
.
├── hello.py
├── hook.py
├── sitecustomize.py

sitecustomize.py:

$ cat sitecustomize.py
import hook

结果:

$ export PYTHONPATH=.
$ python
find_module usercustomize
Python 3.5.1 (default, Dec 24 2015, 17:20:27)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
find_module readline
find_module atexit
find_module rlcompleter
>>>
>>> import hello
find_module hello
load_module hello
>>>
>>> hello.sleep(3)
start func
spent 3.005002021789551s
3

不过上面的探测程序其实还有一个问题,那就是需要手动修改 PYTHONPATH 。用过探针程序的朋友应该会记得, 使用 newrelic 之类的探针只需要执行一条命令就 可以了:newrelic-admin run-program python hello.py 实际上修改 PYTHONPATH 的操作是在newrelic-admin 这个程序里完成的。

下面我们也要来实现一个类似的命令行程序,就叫 agent.py 吧。

agent

还是在上一个程序的基础上修改。先调整一个目录结构,把 hook 操作放到一个单独的目录下, 方便设置 PYTHONPATH 后不会有其他的干扰(代码可以从 github 上下载 part6 )。

$ mkdir bootstrap
$ mv hook.py bootstrap/_hook.py
$ touch bootstrap/__init__.py
$ touch agent.py
$ tree
.
├── bootstrap
│   ├── __init__.py
│   ├── _hook.py
│   └── sitecustomize.py
├── hello.py
├── test.py
├── agent.py

bootstrap/sitecustomize.py 的内容修改为:

$ cat bootstrap/sitecustomize.py
import _hook

agent.py 的内容如下:

import os
import sys

current_dir = os.path.dirname(os.path.realpath(__file__))
boot_dir = os.path.join(current_dir, 'bootstrap')

def main():
    args = sys.argv[1:]
    os.environ['PYTHONPATH'] = boot_dir
    # 执行后面的 python 程序命令
    # sys.executable 是 python 解释器程序的绝对路径 ``which python``
    # >>> sys.executable
    # '/usr/local/var/pyenv/versions/3.5.1/bin/python3.5'
    os.execl(sys.executable, sys.executable, *args)

if __name__ == '__main__':
    main()

test.py 的内容为:

$ cat test.py
import sys
import hello

print(sys.argv)
print(hello.sleep(3))

使用方法:

$ python agent.py test.py arg1 arg2
find_module usercustomize
find_module hello
load_module hello
['test.py', 'arg1', 'arg2']
start func
spent 3.005035161972046s
3

至此,我们就实现了一个简单的 python 探针程序。当然,跟实际使用的探针程序相比肯定是有 很大的差距的,这篇文章主要是讲解一下探针背后的实现原理。

文中的代码:https://github.com/mozillazg/apm-python-agent-principl

DRAM测试仪器原理全解析:从芯片体检到量产测试 存储器测试是半导体产业链中确保芯片可靠性的关键环节,其核心在于通过自动测试设备(ATE)对DRAM等存储芯片进行全面的功能与参数验证。其工作原理是模拟芯片真实使用场景,通过高速数字信号发生、精密模拟测量及海量数据比对,对数十亿存储单元进行高效“体检”。这项技术的核心价值在于提升芯片良率、保障终端产品稳定性,并直接降低量产测试成本。在应用场景上,它贯穿于晶圆测试(CP)和成品测试(FT)阶段,尤其在DDR5、HBM等高速高带宽存储器测试中至关重要。本文以DRAM测试仪器为例,深入剖析其核心子系统,如引脚电子通 阅读详情

相关推荐

Python探针实现原理及后端代码

通过定义探针指标、收集数据、封装数据和传输数据,我们可以编写一个简单的探针,并将指标数据发送给后端进行处理。在Python中,我们可以通过编写一个探针来收集目标系统的关键指标,并将其报告给后端。收集指标数据:使用Python的相关库和模块,我们可以编写代码来收集探针指标数据。这些指标可以是系统的整体性能指标,如CPU使用率、内存占用等,也可以是特定应用程序的指标,如请求数量、响应时间等。传输数据:将封装好的指标数据传输给后端。下面是一个简单的Python后端代码示例,用于接收探针发送的指标数据并进行处理。

OyLinux的博客 476

sys.meta_path

sys.meta_path 写的很好

qq_40666620的博客 689

优快云 付费专栏深度干货:示波器单端信号底层原理、典型实例、应用场景全解|新手入门必懂的基础测量范式

本文系统讲解示波器单端信号的定义、电气本质、实物实例与工程应用。内容涵盖单端信号以公共地为唯一参考的核心特征、单端探头硬件结构、电源/GPIO/传感器/音频等典型单端信号,以及纹波测量、时序测试、总线排查等实战场景。同时深入分析地环路干扰等固有缺陷与禁用场景,并给出基于 PyVISA 的 Python 自动化采集完整示例,帮助读者从原理到实操全面掌握单端测量。

weixin_44520581的博客 29

python turtle代码示例-Python turtle.left方法代码示例

本文整理汇总了Python中turtle.left方法的典型用法代码示例。如果您正苦于以下问题:Python turtle.left方法的具体用法?Python turtle.left怎么用?Python turtle.left使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在模块turtle的用法示例。在下文中一共展示了turtle.left方法的...

weixin_39673184的博客 3191

模块加载时sys.meta_path的拦截机制如何实现?

通过注册自定义Finder和Loader,开发者可实现对模块导入过程的细粒度拦截。此机制在模块加密、远程加载、代码监控等场景中具有强大灵活性,但需谨慎处理性能、错误和安全性问题。实际应用中,结合importlibAPI(如)能更高效地控制模块生命周期。

ufxvf64186的博客 1052

Python 探针的实现原理

探针的实现主要涉及以下几个知识点: sys.meta_path sitecustomize.py sys.meta_path sys.meta_path 这个简单的来说就是可以实现 import hook 的功能, 当执行 import 相关的操作时,会触发 sys.meta_path 列表中定义的对象。 关于 sys.meta_path 更详细的资料请查阅 python 文档中 sys.meta_path 相关内容以及 PEP 0302 。 sys.meta_path 中的对象需要实现一个 find_module 方法, 这个 find_module 方法返回 None 或一个实现了 loa

python find函数实现原理_非常干货:Python 探针实现原理

△点击上方“Python猫”关注 ,回复“1”领取电子书 剧照 | 《棋魂》原文:https://segmentfault.com/a/1190000004889212大家好,我是猫哥。关于 Python 中探针的运用,我之前写过一篇《由浅入深:Python 中如何实现自动导入缺失的库?》,最近看到一篇文章专门写这个内容,特分享一下~~本文呢,将简单讲述一下 Python 探针的实现原理。同时为了...

weixin_39911007的博客 437

组合导航(八):INS/GPS组合导航

INS/GPS组合导航1 误差反馈1.1 开环INS/GPS架构1.2 闭环INS/GPS架构2 组合导航的类型2.1 松耦合 的INS/GPS组合导航2.2 紧耦合 的INS/GPS组合导航2.3 深度耦合的 INS/GPS组合导航3 INS方程的动态误差模型4 松耦合的INS/GPS组合导航模型4.1 系统模型4.2 测量模型4.3 INS/GPS松耦合总框图5 紧耦合的INS/GPS组合导航模型5.1 系统模型5.2 测量模型 INS/GPS组合导航 对比INS与GPS导航方法,二者都有其各自的优.

weixin_43793960的博客 3万+

python如何实现手眼定标_非常干货:Python 探针实现原理

多人学习python,不知道从何学起。很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。很多已经做案例的人,却不知道如何去学习更加高深的知识。那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!??¤QQ群:1057034340One old watch, like brief python原文:关于 Python 的导入机制,我以前写...

weixin_39812065的博客 269

网络设备心跳线带宽高导致虚拟化平台不稳定的问题处理

本文记录了网络设备心跳线带宽高导致虚拟化平台不稳定的问题处理一例。

forestqq的博客 2228

DeepSeek 框架和技术栈分析

DeepSeek 诞生于对更高效、更强大的深度学习计算和模型训练的追求。随着深度学习模型的规模不断增大,如大型语言模型(LLMs)和复杂的视觉模型,传统的框架在处理这些大规模模型时面临着性能瓶颈和资源利用效率低下的问题。DeepSeek 旨在解决这些问题,通过优化框架设计和采用先进的技术栈,实现更高效的模型训练和推理,同时降低计算成本。

yournameplease的专栏 1512

强化学习原理与python实现原理pdf_非常干货:Python 探针实现原理

点击上方“Python编程时光”,选择“加为星标”第一时间关注Python技术干货!原文:https://segmentfault.com/a/1190000004889212大家好,我是明哥。关于 Python 的导入机制,我以前写过一篇文章,非常详细,感兴趣的可以点击这个链接进行查看:深入探讨 Python 的 import 机制:实现远程导入模块另外,今天再给你推荐这篇文章,同样是...

weixin_39601088的博客 432

安装Openclaw[本地自动化AI助手]至windows【WSL2模式】系统 Openclaw for Windows

摘要:OpenClaw最佳兼容OpenAI系列模型,推荐使用ChatGPT API(需Auth鉴权),避免K*mi等模型导致的信用卡风险。Windows系统需满足WSL2支持条件(Win11或Win10 1903+版本)。安装需导入自签名根证书或跳过浏览器安全警告,通过离线包部署WSL发行版。使用时通过clawtoken命令获取网关认证令牌,并在浏览器完成设备配对。提供代购ChatGPT Plus账号服务(¥140/月),详细操作指南需加微信群获取文件。(150字)

qq_27246521的博客 456

python QTreeWidgetItem下面有几个子tree_非常干货:Python 探针实现原理

↑↑↑关注后"星标"简说Python人人都可以简单入门Python、爬虫、数据分析简说Python推荐来源:https://segmentfault.com/a/1190000004889212整理:Python编程时光Oneoldwatch,likebrief python原文:关于 Python 的导入机制,我以前写过一篇文章,非常详细,感兴趣的可以点击这个链接进行查看:深入...

weixin_39997300的博客 107

UNet改进(19):基于残差注意力模块Residual Attention的高效分割网络设计

本文提出一种结合注意力机制的改进UNet网络,通过引入残差注意力模块(ResidualAttentionBlock)增强医学图像分割性能。该网络在传统UNet的U型结构基础上,创新性地将轻量级注意力机制与残差连接相结合,在编码器-解码器各层级实现特征重标定。改进后的网络具有三方面优势:通过注意力机制自适应聚焦关键特征区域,利用残差连接缓解梯度消失问题,采用模块化设计灵活配置注意力位置。

2501_91516851的博客 780

【异常】出现“‘git‘ 不是内部或外部命令,也不是可运行的程序”的错误

出现“‘git’ 不是内部或外部命令,也不是可运行的程序”的错误通常意味着 Git 没有被正确安装在你的系统上,或者其可执行文件的路径没有被添加到系统的环境变量中。

奶爸的编程之路,也就一周冷个三天 1391

Pod核心精讲!云原生最小调度单元,吃透生命周期、探针、优雅停机,根治Java/Python容器线上异常

Pod 反复重启:优先查看存活探针失败、OOM 日志、代码启动报错Pod 启动成功但无法访问:99% 是就绪探针未通过,流量未接入AI 长任务频繁中断:未配置优雅停机、滚动更新策略不合理Pod 调度失败:资源 requests 超出节点剩余资源、节点标签/亲和策略不匹配Pod 是 K8s 最小调度单元,所有 Java、Python Agent 服务都基于 Pod 运行五大生命周期状态是快速定位 Pod 异常的核心依据三大探针各司其职:存活探针保自愈、就绪探针保流量、启动探针保慢启动服务稳定。

weixin_44661794的博客 131

如何使用PostgreSQL数据库进行数据仓库的ETL操作

本文旨在为数据工程师、数据库管理员和分析师提供使用PostgreSQL进行数据仓库ETL操作的全面指南。ETL流程的基本原理PostgreSQL在ETL中的独特优势实际ETL实现的技术细节性能优化和最佳实践常见问题的解决方案首先介绍ETL和PostgreSQL的基本概念然后深入探讨核心技术和实现方法接着提供实际案例和代码示例最后讨论优化技巧和未来趋势ETL:提取(Extract)、转换(Transform)、加载(Load)的缩写,描述数据从源系统移动到目标数据仓库的过程。

2502_91592937的博客 873

【干货】前方高能!如何保障Python应用的高性能

Python作为一种推崇“简单、优雅、明确”的面向对象语言,以其简捷明了的语法结构,丰富的类库,出色的易用性在互联网时代得到了广泛的应用。不论是国外的Facebook、Youtube、Instagram、Pinterest,还是国内的知乎、豆瓣,用Python开发的Web应用已经无处不在。 而随着云计算时代的到来,以及基于Python的云架构开源项目OpenStack的流行,越来越多的企业开

cloudwiseAPM的专栏 567

数据分析案例-2024年裁员数据集可视化分析

本实验数据集来源于Kaggle,原始数据集为2020-2024年裁员数据,共有3577条,12个变量,该数据集提供了不同公司的裁员信息。它包括以下几栏:Company:裁员发生的公司名称。Location_HQ:公司总部位置。Industry:公司所属的行业或部门。Laid_Off_Count:公司解雇的员工数量。Percentage:公司员工被解雇的百分比。Date:裁员发生的日期。Source:信息来源网址。Funds_Raised:公司募集资金的信息。

m0_64336780的博客 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

上一篇: 零基础学Python:数据容器
下一篇: 轻松导入和执行Python模块的3种技巧
酸菜鱼编程
博客等级 码龄6年 155粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值