这个 Sliver 扩展的编写主要是一次学习练习,用以了解 Sliver 如何处理扩展。
我要感谢整个 Sliver 团队在这个公开植入框架上所做的工作。 特别感谢 @rkervell 回答了许多我关于 Sliver 如何处理其扩展的问题。
基本上,它使用原始输入。这相对于其他常见的键盘记录方法既有利也有弊。
我喜欢它的原因在于,它不需要注入到其他二进制文件中,也不需要频繁轮询某个调用而可能错过结果。
这段代码一部分是我自己的作品,一部分是互联网上找到的各种示例的整合。
使用 Visual Studio 2019 打开解决方案文件,并构建 x86 和 x64 版本。
在这个扩展有可能被收录到 armory 之前,可以在 Windows 系统上构建它。然后将生成的 $(solutiondir)\bin 文件夹放到 sliver 客户端上,并运行 extensions install <path to folder> 来安装扩展。你可能需要重启,或者也可以运行 extensions load <path to folder>。
raw_keylogger <cmdid>
以下 cmdid 均有效:
0 = stop
1 = start
2 = get keystrokes
如果一切顺利,运行效果会像这样:

Sliver 的 API 包含以下两个主要部分:
typedef int (*goCallback)(const char*, int);
extern "C" {
__declspec(dllexport) int __cdecl entrypoint(char* argsBuffer, uint32_t bufferSize, goCallback callback);
}
植入体将调用 .json 文件中定义的 "entrypoint"。它指向你的入口点函数(不一定要叫这个名字,只需遵循该签名即可)。
goCallback 是一个用于向 Go 返回输出的函数。它的调用方式类似 callback(string, string_length)。
在编写扩展时,目前 "name" 和 "command_name" 必须保持一致,否则植入体将在每次调用时重新加载你的扩展。
截至撰写本文时,非 BOF 扩展不支持强类型参数,因此命令行中命令名称之后提供的所有内容都会以字符串形式下发。你必须从那里开始在扩展的原生代码端处理它。