半自动化批量剖析AgentTesla最新变体的方法探究--最终获取大量SMTP、FTP账号信息
字数 1028 2025-08-24 16:48:07

AgentTesla最新变体半自动化批量分析方法教学文档

一、背景与目标

AgentTesla是一种流行的远控木马,具有多种变体和数据窃取方式。本文档将详细介绍如何半自动化批量分析AgentTesla最新变体,最终提取SMTP、FTP等关键配置信息。

分析目标

  1. 提取解密后的PE文件
  2. 获取关键功能信息:
    • 配置信息
    • 下载功能地址
    • 数据窃取方式(Web Panel/SMTP/FTP)

二、内存提取PE文件方法

方法对比

思路一:基于解密算法

  • 问题:解密算法复杂,涉及多个样本文件代码,易触发异常
  • 问题:需要动态调试获取解密密钥,工作量未减少

思路二:提取进程内存中所有PE文件

  • 问题:提取大量无关PE文件
  • 问题:PE文件重复
  • 问题:PE文件头正常但内容异常

思路三:通过WriteProcessMemory断点提取(推荐)

  • 原理:利用进程替换技术中的WriteProcessMemory函数
  • 步骤:
    1. 使用OD调试AgentTesla样本
    2. 在WriteProcessMemory函数下断点
    3. 中断后查看lpBuffer参数(指向PE文件载荷)
    4. 提取内存块

从内存片段还原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样本

  1. 安装环境:

    • 安装.NET SDK 6.0
    • 安装ilspycmd:dotnet tool install --global ilspycmd
  2. 使用命令:

    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

  • 可直接使用压缩软件解压实现解密

五、最终成果

通过上述半自动化分析方法,可以高效地:

  1. 批量处理大量AgentTesla样本
  2. 提取关键配置信息
  3. 获取大量SMTP、FTP账号信息

六、关键点总结

  1. 内存提取:优先使用WriteProcessMemory断点法
  2. 反编译工具:ilspycmd是批量处理的关键
  3. 配置提取:利用配置项结构固定的特点
  4. 自动化脚本:Go语言实现高效批量处理
  5. 解密算法:部分变体可使用特定算法解密

通过这套方法,分析人员可以大幅提高AgentTesla样本的分析效率,快速获取关键威胁情报。

AgentTesla最新变体半自动化批量分析方法教学文档 一、背景与目标 AgentTesla是一种流行的远控木马,具有多种变体和数据窃取方式。本文档将详细介绍如何半自动化批量分析AgentTesla最新变体,最终提取SMTP、FTP等关键配置信息。 分析目标 提取解密后的PE文件 获取关键功能信息: 配置信息 下载功能地址 数据窃取方式(Web Panel/SMTP/FTP) 二、内存提取PE文件方法 方法对比 思路一:基于解密算法 问题 :解密算法复杂,涉及多个样本文件代码,易触发异常 问题 :需要动态调试获取解密密钥,工作量未减少 思路二:提取进程内存中所有PE文件 问题 :提取大量无关PE文件 问题 :PE文件重复 问题 :PE文件头正常但内容异常 思路三:通过WriteProcessMemory断点提取(推荐) 原理:利用进程替换技术中的WriteProcessMemory函数 步骤: 使用OD调试AgentTesla样本 在WriteProcessMemory函数下断点 中断后查看lpBuffer参数(指向PE文件载荷) 提取内存块 从内存片段还原PE文件 使用Go语言编写脚本实现自动化提取: 三、自动化提取配置信息 方法对比 思路一:基于16进制特征 问题 :只能提取变量值,无法对应变量名 思路二:反编译后分析(推荐) 工具:ilspycmd(ILSpy命令行版本) 批量反编译.NET样本 安装环境: 安装.NET SDK 6.0 安装ilspycmd: dotnet tool install --global ilspycmd 使用命令: 配置信息结构特点 不同样本的配置信息项顺序和名称基本相同 自动化提取脚本 四、多阶段解密算法(可选) 解密SimpleLogin.dll 解密Gamma.dll 可直接使用压缩软件解压实现解密 五、最终成果 通过上述半自动化分析方法,可以高效地: 批量处理大量AgentTesla样本 提取关键配置信息 获取大量SMTP、FTP账号信息 六、关键点总结 内存提取 :优先使用WriteProcessMemory断点法 反编译工具 :ilspycmd是批量处理的关键 配置提取 :利用配置项结构固定的特点 自动化脚本 :Go语言实现高效批量处理 解密算法 :部分变体可使用特定算法解密 通过这套方法,分析人员可以大幅提高AgentTesla样本的分析效率,快速获取关键威胁情报。