闲聊几句
说是框架,其实我更愿意称之为插件。设计之初,基本思想就是把每一个功能单独成一个函数,作为不需要依赖的插件去调用,同时又具有高度的灵活性、随机性。
虽然是免杀框架,但是设计初版的时候为了验证免杀的效果,我已经把样本在各种各样的沙箱上传了,这就导致初版很快就标记。之后,痛定思痛,做了一个违背摸鱼的决定,全面重构了所有代码,所以第二版就诞生了。
转眼之间,项目发布已经五个月了,冲着能续费会员的想法,来记录一下这一路的知识点。
文件指纹
先看一组代码对比
package main
import "fmt"
func main() {
fmt.Println("1")
}
package main
import "fmt"
func main() {
fmt.Println("2")
}
那么一样的代码,再次编译
可见,只要代码改动一个字符就能使文件指纹进行改变。那么第一步文件指纹随机,就是免杀特征的开始。
随机指纹
要实现随机指纹其实也很简单,只要做到让代码随机即可,简单来说就是让变量名随机化。恰好,Golang的template库,https://pkg.go.dev/text/template,就是专门为模板渲染提供了很多好用的功能。
使用方法也非常简单,定义对应的结构体,设计好模板,Go渲染!
type Inventory struct {
Material string
Count uint
}
sweaters := Inventory{"wool", 17}
tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
if err != nil { panic(err) }
err = tmpl.Execute(os.Stdout, sweaters)
if err != nil { panic(err) }
模板设计
模板设计要考虑的事情有点多了,先看一个结构体
type Data struct {
CipherText string // 保存加密文本的变量名
PlainText string // 保存解密文本的变量名
DecryptMethod string // 解密方法
Pokemon interface{} // Pokemon Shellcode
Loader interface{} // loader
SandBox interface{} // 反沙箱模块
Local interface{} // 本地加载模块
Remote interface{} // 远程加载模块
Args interface{} // 参数加载模块
Compressor interface{} // 压缩算法模块
Apart interface{} // 分离加载模块
Dynamic interface{} // 动态数据
}
结构体从模块的维度来设计,目前支持的模块还比较少(泛型已经不少了,完蛋)。
先从简单一点的来开始:
- 随机变量名
- Loader
- 本地加载
随机变量名非常好解决,一个随机函数搞定,当然项目里面有很多奇奇怪怪的随机函数也很正常,哈哈哈
func RStrings() string {
rand.New(rand.NewSource(time.Now().UnixNano()))
b := make([]rune, rand.Intn(16)+2)
for i := range b {
b[i] = letters[random.Intn(len(letters))]
}
return string(b)
}
加载器,如果你只看到这,并且不催更的话,我的建议是Github上很多单独的Loader都可以直接下载然后写一个Python脚本处理一下随机变量名就可以啦。
如果你想深入了解加载器的原理,下次一定。
本地加载,顾名思义就是内嵌ShellCode了。内嵌为了过静态查杀就要进行加密,当然加密模块这是后话。
如果你问我加密后的 mht 会不会被发现:
总结
写一个加载器只需要两个条件:1、ShellCode 2、加载函数。
涉及到的其他,都是为了这两个部分服务的。
下次投稿就来简单聊聊,随机渲染的事情吧。
请登录后查看评论内容