1.在linux中,使用:
sudotimeout75unshare-nstrace-f-qq-etrace=%network-o/tmp/net.trace ./木马程序可以查看木马的回连地址
2.如果是从 Wireshark 等工具中提取的、不带地址偏移的纯十六进制载荷,使用-r -p参数组合:
# 从Hex文件输出为二进制文件 xxd -r -p packet.txt packet.bin3.用系统函数查看程序函数表
readelf -S xx.exe
可以预先给程序建档:
¥file xxx $ md5sum xxx $ sha256sum xxx不适用插件情况下识别各类语言的main函数入口的通用特征:
Go runtime.main 通用范式(通用凡是 = 不变特征)
不管 Go 版本 1.17~1.26、是否 garble 混淆、普通程序 / 恶意样本,下面这些行为序列永远不变;
变量地址、变量名、if 里面的数字每个样本都变,不属于通用特征。
【通用不变特征,所有 Linux Go ELF】
定位到runtime_main(Go 运行时主函数)内部:
- 前面一大段:GC 初始化、
runtime_gcenable()、创建 / 关闭 channel、TLS__readfsqword(0xFFFFFFF8)、M/G 协程结构体初始化、cgo 处理。 - 存在一处 call 调用,调用完这个函数返回之后,固定顺序执行下面 3 个东西:
①runtime_runExitHooks()// 运行退出钩子
② 调用进程退出函数(内部 exit)
③ 无限死循环while(1),防止代码继续往下跑垃圾指令
被 call 的那个目标函数,就是用户
main.main。
伪代码范式(逻辑通用,变量名是示意)
// 在 runtime_main 里面 if( 各种编译模式判断 ){ call X; // X = main.main 用户入口 if( ... ){ runtime_runExitHooks(); call os_exit(); while(1); } }花括号里面的 if 条件、全局变量
byte_xxxx地址每个样本不一样;
但是调用 X 之后:runExitHooks → exit → while(1)这一串执行序列是铁律。