Python 是一种解释型语言,没有编译过程,发布程序的同时就相当于公开了源码,这也是其作为开源语言的一个特性。但在某些场景下,我们的源码是不想被别人看到的,例如开发商业软件、编写 0day 漏洞 POC/EXP、免杀 shellcode 等。

多人学习python,不知道从何学起。

很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。

很多已经做案例的人,却不知道如何去学习更加高深的知识。

那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!??¤

QQ群:1057034340

以免杀为例,如果打包的源码没做任何处理,安全研究人员在捕获到样本后连分析的过程都省掉了,直接通过源码锁定特征,很快免杀就会失效,这显然不是我们想看到的。因此对源码做相应的保护还是有必要的。

注:本文代码只为介绍源码保护方法,不涉及免杀姿势。

目前保护 Python 代码主要有以下几种方式:

  • 对代码进行混淆以降低源码可读性

  • 将 py 文件编译为二进制 pyc 文件

  • 使用 Pyinstaller 打包源码为二进制可执行文件

  • 使用 PyArmor 加密脚本

  • 将 py/pyc 文件使用 AES 加密为 pye 文件

  • 将 py 文件转为 c 文件后编译为动态链接库文件

代码混淆

代码混淆是指在不改变代码逻辑的情况下,对代码结构进行变换,通过一些带有混淆性质的命名、注释等,使代码变得晦涩难懂,从而达到保护代码的作用。这里提供两种代码混淆的方式:

代码混淆库 pyobfuscate

pyobfuscate 会对代码中用户定义的类、函数、变量等进行重命名、更改代码缩进(默认1)、移除注释、添加不影响逻辑的代码语句,最终起到混淆的作用。不过 pyobfuscate 使用 Python2 编写,无法解析 Python3 中的 f-string 等特殊语法,因此使用前需要将源码进行一定程度的修改,当然也可以直接修改 pyobfuscate 库,增加对 Python3 版本的支持。

样例 (对 malicious.py 文件进行混淆):

python2 pyobfuscate.py malicious.py > malicious_obfuscated.py

效果如下图所示,左侧为一段从云端获取 shellcode 加载进内存执行的代码,右图为其混淆后的结果。

可以看出代码虽然进行了一定程度的变换,但代码结构基本还是原来的样子,并不能很有效的增加破解难度。

利用 AST 混淆源码

AST,即抽象语法树,它可以将源代码以树状结构表示。Python 内置了 ast 模块,该模块通过内置函数 compile() 和 parse() 将  Python 源代码解析为 AST,之后可以利用 ast 模块内的方法对 ast 节点进行相应的操作,混淆处理后使用 codegen 库将 AST 重新生成为 Python 源码。

样例:

python2 astobf.py malicious.py > malicious_astobfed.py

效果如下图所示,AST 混淆后的代码略有修改,以保证 Python3 下脚本可正常执行。

混淆后的代码使用 __import__ 动态导入模块、使用 getattr 调用类方法,这样就可以以字符串方式传入模块名和方法名,借由字符串翻转拼接、数字计算等方式达到混淆目的,相比之下,AST 方式的混淆效果明显要优于 pyobfuscate 库。

编译为 pyc 文件

pyc 文件是 Python 的字节码文件,其存在的意义在于每次调用模块时,不用重新对该模块进行解释,从而提高效率,减少性能损耗。但是在运行一个单独的脚本时,该脚本是不会被编译为 pyc 文件的,这是由于 Python 的解释器认为只有导入的包才会被不断复用,才有编译的价值。不过 Python 提供了 py_compile 库和 compileall 程序用于手动编译 py 文件。

py_compile

import py_compile py_compile.compile(file="malicious.py")

compileall

python -m compileall ./

编译为字节码文件后,确实没办法直接读取源码了,但是 Python 有 uncompyle6 这么一个跨版本反编译器,可以将 Python 字节码转换回等效的 Python 源代码。

python -m pip install uncompyle6 uncompyle6 malicious.cpython-37.pyc > malicious_Decompiled.py

而且 pyc 还有一个弊端,就是它依赖于 Python 解释器的版本,使用某版本解释器编译的 pyc 文件必须使用相同版本解释器运行才能正常工作, 所以实际上将 py 文件编译为 pyc 文件的实用性并不是很大。

打包为独立可执行程序

通过将 Python 文件打包为独立可执行程序也是一种保护源码的方式。Windows 平台下 ,有 Pyinstaller 、 py2exe 和 cx_Freeze 等多种打包程序可以使用,以 Pyinstaller 为例,打包 malicious.py 命令如下:

python -m pip install pyinstaller pyinstaller -Fw -i myicon.ico malicious.py

-F 表示生成单文件,-w 表示隐藏控制台窗口,-i 表示为生成的 exe 文件添加图标。

Python 打包的 exe 程序并不是将文件编译为真正的机器码,而是将脚本编译为 pyc 后连同依赖文件、当前的 Python 解释器一同打包起来,根据命令参数生成文件夹或打包成单独的可执行文件。之后运行 exe 时,实际运行的是一个引导加载程序,引导加载程序会创建一个临时的 Python 环境,通过解释器副本来执行 pyc 文件。

由于这种运行方式的特殊性,Pyinstaller 打包的 exe 文件也是可以被还原出源码的。使用 pyinstxtractor 解包 exe:

python pyinstxtractor.py malicious.exe

解包后的文件夹内包含了 malicious.pyc 文件,之后使用 uncompyle6 反编译该文件就可以拿到源码。所以将 Python 打包为 exe 只相当于在编译为 pyc 的基础上添加了一步打包操作,同样不能很有效的对源码进行保护。

使用 PyArmor 加密代码

PyArmor 是一个用于加密和保护 Python 脚本的工具。它能够在运行时刻保护 Python 脚本的二进制代码不被泄露,设置加密后 Python 源代码的有效期限,绑定加密后的 Python 源代码到硬盘、网卡等硬件设备。

它的保障机制主要包括:

  • 加密编译后的代码块,保护模块中的字符串和常量

  • 在脚本运行时候动态加密和解密每一个函数(代码块)的二进制代码

  • 代码块执行完成之后清空堆栈局部变量

  • 通过授权文件限制加密后脚本的有效期和设备环境

PyArmor 的工作原理相对复杂,有兴趣的朋友可以参考官方的说明文档:

https://pyarmor.readthedocs.io/。

使用 PyArmor 默认加密方式加密 malicious.py:

pyarmor obfuscate malicious.py

加密后的文件前两行代码是引导代码,用于加载 pytransform 动态链接库和添加三个内置函数到 builtins 模块,之后调用 __pyarmor__ 导入加密模块执行加密代码。加密后的文件目录还有一个名叫 pytransform 的运行辅助包,它是解密文件所必须的,因此打包加密文件时需要同时将运行辅助包打包进去。

pyinstaller -Fw --add-data "pytransform;pytransform" malicious.py

PyArmor 使用分片式技术来保护 Python 脚本。所谓分片保护,就是单独加密每一个函数,在运行脚本的时候,只有当前调用的函数被解密,其他函数都没有解密。而一旦函数执行完成,就又会重新加密。这种方式相对于混淆来说,效果明显要好的多。

加密为 pye 文件

pyconcrete 是另一个 python 的文件加密库,安装它需要提供一个密钥,用于之后对源码文件进行加密,同时由于过程中涉及 .c 文件的编译,因此 Windows 下需要安装 VC++ build tools,Linux 下需要安装 GCC。

解压出 pyconcrete 库源码后,使用 setup 进行安装。

python setup.py install

安装成功后复制 pyconcrete-admin.py 文件到项目文件夹就可以使用了。

pyconcrete 可以将源码文件夹下所有 py/pyc 文件通过 AES128 加密为 pye 文件,该文件无法被正常的 Pyhon 解释器解释,需要使用 pyconcrete 程序加载运行。当然也可以将函数定义部分提出来作为库文件单独加密,函数调用部分独立出来作为一个入口,如下,将 malicious.py 文件拆分为 malicious_func.py 和 malicious_enter.py。

对 malicious_func.py 文件单独加密。

python pyconcrete-admin.py compile --source=malicious_func.py --pye

加密后在只有 malicious_enter.py 和 malicious_func.pye 两个文件的情况下运行 malicious_enter.py 文件,脚本是可以在本地正常运行的,因为解释器在导入 pye 文件时会自动调用环境变量中的 pyconcrete 进行解密。

如果想将其打包为 exe 在其他机器上运行,还需要进行一些修改:

  1. 修改 malicious_enter.py 文件,在首部导入 pyconcrete,以及加密脚本中需要用到的库,这是为了在调用 Pyinstaller 时,将 pyconcrete 解密程序和脚本依赖的库同时打包进 exe。pyconcrete 库需要在其他库之前导入,它会自动和其他模块挂钩,在其目录寻找 pye 文件,然后通过 _pyconcrete.pyd 对 pye 文件进行解密。

  2. Pyinstaller 不会将 pye 文件主动打包进 exe,需要在打包时通过 --add-data 添加。

这样打包出的 exe 就可以执行了。

使用 pyconcrete 加密的源码在运行时会调用 _pyconcrete.pyd 文件进行解密,该文件内存储了用于解密源码的密钥。由于其密钥隐藏在二进制数据中,无法通过十六进制编辑器直接看到,因此想要解密源码,就必须对 _pyconcrete.pyd 文件进行逆向分析,提取密钥。

编译为 pyd 文件

上面提到的 pyd 文件是 Python 的动态链接库,类似 Windows 下的 DLL 和 Linux 下的 SO,它是 Cython 结合 C 的编译器编译而来,涉及 C 的编译, 因此同样需要 VC++ build tools 或 GCC。

实际上,Cython 是一门单独的语言,专门用来写 Python 的 C 扩展。原本是为了解决 Python 语言的效率问题,但由于其有专门的转换器可以将 .py 文件转换为 .c 文件 (自动加入大量 C-Python API ) 后编译为 pyd,因此也可以利用这个特点来保护 Python 源码,下面为编译方法:

pyd 的文件为库文件,所以也需要一个 py 文件进行调用,这里还是使用 malicious_enter.py 和 malicious_func.py 作为示例。

创建一个 py 文件,用于将 malicious_func.py 编译为 pyd。

# -*- coding: utf-8 -*- from distutils.core import setup from Cython.Build import cythonize setup(     ext_modules = cythonize(['malicious_func.py',]),     )

cythonize 方法会将 malicious_func.py 的 Python 代码转换为 Cython 代码,之后调用 setup 将 .c 文件编译为 pyd。

python build_pyd.py build_ext --inplace

可以直接运行。

也可以打包为 exe,Pyinstaller 会自动将 pyd 文件作为依赖导入。

编译为 pyd 后,想要了解源码的逻辑就必须通过逆向来分析,相较于从 _pyconcrete.pyd 中提取密钥解密 pye,这种直接将完整逻辑代码编译为二进制文件的方式更不容易被逆向出来,逻辑写的越复杂,逆向分析的代价就越高。

最后, 上面说的这些 Python 源码保护方法其实正常情况下很少会用得到,既然使用了 Python,一般也不会有人刻意去隐藏自己的代码。不过对于安全领域,这些方法还是有一定价值的。拿免杀来说,复杂的加解密流程,配合上面某些方法,说不定就能很好的隐藏自己的特征,养出一匹低调的马儿。

未完待续...

360BugCloud开源漏洞响应平台,国内自主议价漏洞收录模式开拓者! 聚焦收录未被披露的开源以及通用组件高危漏洞,致力于维护开源软件和供应链安全。平台采用入驻邀请制,只面向成功提交未被披露漏洞的安全研究员开放。 360BugCloud开源漏洞响应平台首创“自主议价”模式及“第三方专家评审”机制,先议价后交洞,仅需提交漏洞影响力描述即可进行议价,让安全研究员完全掌握漏洞提交主动权,高额奖金上不封顶,让漏洞价值得到充分保障与肯定。

步轻松实现在360BugCloud提交漏洞

Python 源码混淆与加密相关推荐

  1. 【Python基础】加密你的Python源码顺便再打个包如何?

    本篇为专属于"交通科研Lab"志愿者系列推文活动,为大家带来交通高校硕博们原创推文.为作者点赞,欢迎大家关注交流!!! 点击蓝字 关注我们 成为一个智慧.快乐和富有的人. --王宇 ...

  2. python源码加密实现

    本文参考如何保护你的 Python 代码对其想法进行实现. 源码地址:spython@github RAYENCRY rayencry使用AES算法对指定目录中的Python源码加密. 内容 背景 安 ...

  3. 对python源码进行编译,加密python脚本

    对python源码进行编译 1.生成.pyc文件 import py_compile py_compile.compile('hello.py') 2.优化源码文件 python -O -m py_c ...

  4. python 字节码_简单入门python字节码混淆

    前言 我就是小菜鸡本鸡了,不是很会写东西,请各位大佬多多见谅.本文基于python2.7,因为python3并不是很懂. python文件如果要发布的话,有时候还是难免想保护一下自己的源码,有些人就直 ...

  5. essential c++源码_Goldenmask - 一键化保护你的 Python 源码

    项目地址: https://github.com/youngquan/goldenmask​github.com Goldenmask 直译为金色的罩子,灵感来自"金钟罩"的&qu ...

  6. 【工具】iOS代码混淆工具-iOS源码混淆

    最新更新记录 V2.0.3(2022年12月11日)更新内容: 1.新增导入映射列表的逻辑: 2.优化修复其他混淆逻辑: 3.更新地址 - github 主要功能 ZFJObsLib是专业的iOS源码 ...

  7. python编译器源码_编译python源码

    广告关闭 回望2020,你在技术之路上,有什么收获和成长么?对于未来,你有什么期待么?云+社区年度征文,各种定制好礼等你! 尝试通过源码自己编译 python,使用的系统是 ubuntu14.04 l ...

  8. Python源码学习:多线程实现机制

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 本文分析Python中的多线程机制,主要通过一个多线程的脚本来分析多线程的基本操作与 ...

  9. Python源码学习:Python类机制分析-用户自定义类

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 上一文,分析了Python在启动初始化时,对内置类的一个基本的初始化流程,本文就简析 ...

  10. Python源码学习:Python类机制分析

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 本文主要分析Python中类时如何实现的,在Python中,一切都是对象:任何对象都 ...

最新文章

  1. Python 位运算符
  2. JavaScript 中运算符的优先级
  3. eye--创建单位矩阵
  4. 怎么让图片手机上排列_荣耀手机系列档次怎么排列?
  5. 【Elasticsearch】es如何停用节点
  6. webbrowser控件 加载为空白_OA系统公文控件升级操作说明
  7. 对包含HttpContext.Current.Cache的代码进行单元测试
  8. 子组件触发父组件的方法
  9. rdkitpython | 通过反应获得断键位点与类型
  10. SVN工具添加忽略上传文件和取消忽略文件
  11. 什么是大数据系统架构
  12. 一行代码统计文本中指定字符串出现的次数
  13. 50项谷歌SEO优化清单(做谷歌优化必看)
  14. 苹果8p手机的指纹解锁为什么会失灵呢?怎么解决
  15. 【编程初学者】创建自己的开源项目1-创建远程代码仓库
  16. 特殊教育学校计算机教学心得,特教老师心得体会
  17. android化学制图软件,化学工具箱最新版
  18. 知识产权公证业务构成
  19. 《从0到1-全面深刻理解MySQL系列》- 最详细的MySQL安装流程(Window版)
  20. python读取雷达基数据_重磅更新!读取CINRAD雷达基数据的Python模块

热门文章

  1. IOS日历控件JTCalendar
  2. 2019年“深圳杯”数学建模挑战赛B题解题思路(一)
  3. 用计算机从85加到98的和是,2018年职称计算机考试题库及答案
  4. 英特尔®以太网700系列的动态设备个性化
  5. cmd imp导入dmp文件_dmp文件导入抽取方法(示例代码)
  6. 码栈搭建自动化应用(可视化模式)
  7. linux简易离线词典下载手机版,Linux离线查询字典的方法
  8. 基于SSM高校教师教务信息管理系统
  9. PIE工程师是做什么的
  10. 什么是弱密码,如何避免