半自动化批量剖析AgentTesla最新变体的方法探究--最终获取大量SMTP、FTP账号信息
字数 1028 2025-08-24 16:48:07
AgentTesla最新变体半自动化批量分析方法教学文档
一、背景与目标
AgentTesla是一种流行的远控木马,具有多种变体和数据窃取方式。本文档将详细介绍如何半自动化批量分析AgentTesla最新变体,最终提取SMTP、FTP等关键配置信息。
分析目标
- 提取解密后的PE文件
- 获取关键功能信息:
- 配置信息
- 下载功能地址
- 数据窃取方式(Web Panel/SMTP/FTP)
二、内存提取PE文件方法
方法对比
思路一:基于解密算法
- 问题:解密算法复杂,涉及多个样本文件代码,易触发异常
- 问题:需要动态调试获取解密密钥,工作量未减少
思路二:提取进程内存中所有PE文件
- 问题:提取大量无关PE文件
- 问题:PE文件重复
- 问题:PE文件头正常但内容异常
思路三:通过WriteProcessMemory断点提取(推荐)
- 原理:利用进程替换技术中的WriteProcessMemory函数
- 步骤:
- 使用OD调试AgentTesla样本
- 在WriteProcessMemory函数下断点
- 中断后查看lpBuffer参数(指向PE文件载荷)
- 提取内存块
从内存片段还原PE文件
使用Go语言编写脚本实现自动化提取:
package main
import (
"crypto/sha256"
"debug/pe"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
)
func main() {
hashs := []string{}
files, err := WalkDir("C:\\Users\\admin\\Desktop\\新建文件夹", "")
if err != nil {
fmt.Println("Error:", err.Error())
}
for _, onefile := range files {
SearchPE(onefile, &hashs)
}
}
func SearchPE(file_in string, hashs *[]string) {
output_dir := "./output/"
_, fileName := filepath.Split(file_in)
data, err := ioutil.ReadFile(file_in)
if err != nil {
fmt.Println("Error reading file:", err)
return
}
reg := regexp.MustCompile("This program cannot be run in DOS mode")
offsets := reg.FindAllIndex(data, -1)
for _, offset := range offsets {
buffer := append([]byte{}, data[offset[0]-0x4e:]...)
Writefile("tmp", string(buffer))
size := getfilesize("tmp")
buffer1 := append([]byte{}, buffer[:size]...)
hash := HashData_sha256(buffer1)
if !ContainsAny(hash, *hashs) && strings.HasSuffix(hex.EncodeToString(buffer1), "00000000000000000000000000000000") {
*hashs = append(*hashs, hash)
Writefile(output_dir+fileName+"offset_0x"+strconv.FormatInt(int64(offset[0]-0x4e), 16), string(buffer1))
}
os.Remove("tmp")
}
}
三、自动化提取配置信息
方法对比
思路一:基于16进制特征
- 问题:只能提取变量值,无法对应变量名
思路二:反编译后分析(推荐)
- 工具:ilspycmd(ILSpy命令行版本)
批量反编译.NET样本
-
安装环境:
- 安装.NET SDK 6.0
- 安装ilspycmd:
dotnet tool install --global ilspycmd
-
使用命令:
ilspycmd -o "./output" "assembly.dll"
配置信息结构特点
- 不同样本的配置信息项顺序和名称基本相同
自动化提取脚本
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
)
func main() {
files, err := WalkDir("C:\\Users\\admin\\Desktop\\test", "")
if err != nil {
fmt.Println("Error:", err.Error())
}
for _, onefile := range files {
fileName := filepath.Base(onefile)
fileExt := filepath.Ext(onefile)
decompiledfile := strings.Split(fileName, fileExt)[0] + ".decompiled.cs"
if !CheckPathIsExist("./output/" + decompiledfile) {
CmdRun(`C:\\Users\\admin\\.dotnet\\tools\\ilspycmd.exe -o ./output/ ` + onefile)
}
if CheckPathIsExist("./output/" + decompiledfile) {
fmt.Println("*" + fileName + " URL*")
SearchURLs("./output/" + decompiledfile)
fmt.Println("*" + fileName + " Config*")
SearchConfig("./output/" + decompiledfile)
fmt.Println()
}
}
}
func SearchURLs(onefile string) {
content, err := ioutil.ReadFile(onefile)
if err != nil {
fmt.Printf("无法读取文件:%v\n", err)
return
}
re := regexp.MustCompile(`(http://|https://)[^\s]+`)
matches := re.FindAllString(string(content), -1)
for _, match := range matches {
if strings.Contains(match, `"`) {
fmt.Println(strings.Split(match, `"`)[0])
} else {
fmt.Println(match)
}
}
}
四、多阶段解密算法(可选)
解密SimpleLogin.dll
package main
import (
"fmt"
"io"
"io/ioutil"
"os"
)
func main() {
file_in := "C:\\Users\\admin\\Desktop\\新建文件夹\\off"
array, err := ioutil.ReadFile(file_in)
if err != nil {
fmt.Println("Error reading file:", err)
return
}
num := len(array)
first := "J9EZ6H5428445"
second := "C755C8RZH"
first_second := first + second
for i, data := range array {
num2 := i % 22
b := first_second[num2]
num3 := (i + 1) % num
num4 := int(data ^ b)
num5 := num4 - int(array[num3]) + 256
array[i] = byte(num5 & 255)
}
Writefile(file_in+"_dec_SimpleLogin.dll", string(array))
}
解密Gamma.dll
- 可直接使用压缩软件解压实现解密
五、最终成果
通过上述半自动化分析方法,可以高效地:
- 批量处理大量AgentTesla样本
- 提取关键配置信息
- 获取大量SMTP、FTP账号信息
六、关键点总结
- 内存提取:优先使用WriteProcessMemory断点法
- 反编译工具:ilspycmd是批量处理的关键
- 配置提取:利用配置项结构固定的特点
- 自动化脚本:Go语言实现高效批量处理
- 解密算法:部分变体可使用特定算法解密
通过这套方法,分析人员可以大幅提高AgentTesla样本的分析效率,快速获取关键威胁情报。