本文中涉及到的项目:github.com/kN6jq/fingerScan
Table of Contents
Open Table of Contents
Hex view 提取
用ImHex打开,搜索字符串,浏览了,发现存在类似指纹字符串,如下图所示:

这种指纹提取比较简单,根据指纹内容的格式,找到规则开始的部分,写脚本提取就好了:

如果读者对提取感兴趣,还可以尝试提取下这个指纹识别工具 P1finger中的指纹,相对于本文的案例fingerScan而言,P1finger的仓库中默认不存在指纹列表,这会使得你更享受提取成功所带来的成就感。
Runtime 提取
如果拿到的Go二进制程序存在符号表,可以在关键函数处打断点,通过动态调试的方式拿到相关数据数据。
GDB 调试
以fingerScan 为例,先定位到json.Unmarshal符号表的地址,为0x51e520,如下所示:
go tool nm finger_scan_64 |grep unmarsha -i|grep json

接着使用GDB 进行调试, 并在符号地址处打个断点:
gdb fringer_scan_64
(gdb) b *0x51e520

打完断点后, 运行程序,当执行到断点处,使用命令
(gdb) display data
打印出json.Unmarshal()的第一个参数的值,结果如下图所示:

实际上json.Unmarshal()的第一个参数的值的地址存在rax 寄存器中:

通过display 命令可以看到 data 相关的信息,其中包括长度以及内存的起始地址,接下来我们直接将内存中data的值给dump出来:
dump memory fingerprint.out $rax $rax+6057050


IDA调试
ida同理,先找到json.Unmarshal的位置,在关键信息处打个断点:

接着使用Wingdb 进行调试,当运行到断点处,去查看rax寄存器指向的地址,发现就存储着指纹信息:



由于不知道偏移是多少rax + ?, 所以需要去写脚本去遍历才能把内存给dump下来。
但是不会。。。。。
总结
如果拿到的Go可执行文件存在符号表的话,可以试着用这种方法来提取一下,简单又有趣。
当然,如果使用了 ldflags='-s -w' 就没办法使用这种方式了。比如P1finger.
另外
波特师傅提到了几个常见调试的函数,如下:
regexp.MustCompile
os.Open
base64.StdEncoding.DecodeString
hex.DecodeString
aes.NewCipher
听说能抓到xray 中的一些正则,不过还没去实验。。。