fscan/plugins/local/systeminfo.go
ZacharyZcR 4cd8ed5668 feat: 完成本地插件架构统一迁移
迁移所有本地插件到统一Plugin接口架构:
- socks5proxy/systemdservice: 网络代理和Linux服务持久化
- winregistry/winservice/winschtask/winstartup/winwmi: Windows持久化套件
- 所有插件消除BaseLocalPlugin继承,统一使用Plugin接口
- 保持原有功能完整性,支持跨平台编译标记
- 删除过度设计的继承体系,实现直接简洁实现
2025-08-26 14:39:53 +08:00

155 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package local
import (
"context"
"fmt"
"os"
"os/exec"
"runtime"
"strings"
"os/user"
"github.com/shadow1ng/fscan/common"
)
// SystemInfoPlugin 系统信息收集插件 - Linus式简化版本
//
// 设计哲学:纯信息收集,无攻击性功能
// - 删除复杂的继承体系
// - 收集基本系统信息
// - 跨平台支持,运行时适配
type SystemInfoPlugin struct {
name string
}
// NewSystemInfoPlugin 创建系统信息插件
func NewSystemInfoPlugin() *SystemInfoPlugin {
return &SystemInfoPlugin{
name: "systeminfo",
}
}
// GetName 实现Plugin接口
func (p *SystemInfoPlugin) GetName() string {
return p.name
}
// GetPorts 实现Plugin接口 - local插件不需要端口
func (p *SystemInfoPlugin) GetPorts() []int {
return []int{}
}
// Scan 执行系统信息收集 - 直接、简单、有效
func (p *SystemInfoPlugin) Scan(ctx context.Context, info *common.HostInfo) *ScanResult {
var output strings.Builder
output.WriteString("=== 系统信息收集 ===\n")
// 基本系统信息
output.WriteString(fmt.Sprintf("操作系统: %s\n", runtime.GOOS))
output.WriteString(fmt.Sprintf("架构: %s\n", runtime.GOARCH))
output.WriteString(fmt.Sprintf("CPU核心数: %d\n", runtime.NumCPU()))
// 主机名
if hostname, err := os.Hostname(); err == nil {
output.WriteString(fmt.Sprintf("主机名: %s\n", hostname))
}
// 当前用户
if currentUser, err := user.Current(); err == nil {
output.WriteString(fmt.Sprintf("当前用户: %s\n", currentUser.Username))
if currentUser.HomeDir != "" {
output.WriteString(fmt.Sprintf("用户目录: %s\n", currentUser.HomeDir))
}
}
// 工作目录
if workDir, err := os.Getwd(); err == nil {
output.WriteString(fmt.Sprintf("工作目录: %s\n", workDir))
}
// 临时目录
output.WriteString(fmt.Sprintf("临时目录: %s\n", os.TempDir()))
// 环境变量关键信息
if path := os.Getenv("PATH"); path != "" {
pathCount := len(strings.Split(path, string(os.PathListSeparator)))
output.WriteString(fmt.Sprintf("PATH变量条目: %d个\n", pathCount))
}
// 平台特定信息
platformInfo := p.getPlatformSpecificInfo()
if platformInfo != "" {
output.WriteString("\n=== 平台特定信息 ===\n")
output.WriteString(platformInfo)
}
return &ScanResult{
Success: true,
Output: output.String(),
Error: nil,
}
}
// getPlatformSpecificInfo 获取平台特定信息 - 运行时适配,不做预检查
func (p *SystemInfoPlugin) getPlatformSpecificInfo() string {
var info strings.Builder
switch runtime.GOOS {
case "windows":
// Windows版本信息
if output, err := p.runCommand("cmd", "/c", "ver"); err == nil {
info.WriteString(fmt.Sprintf("Windows版本: %s\n", strings.TrimSpace(output)))
}
// 域信息
if output, err := p.runCommand("cmd", "/c", "echo %USERDOMAIN%"); err == nil {
domain := strings.TrimSpace(output)
if domain != "" && domain != "%USERDOMAIN%" {
info.WriteString(fmt.Sprintf("用户域: %s\n", domain))
}
}
case "linux", "darwin":
// Unix系统信息
if output, err := p.runCommand("uname", "-a"); err == nil {
info.WriteString(fmt.Sprintf("系统内核: %s\n", strings.TrimSpace(output)))
}
// 发行版信息Linux
if runtime.GOOS == "linux" {
if output, err := p.runCommand("lsb_release", "-d"); err == nil {
info.WriteString(fmt.Sprintf("发行版: %s\n", strings.TrimSpace(output)))
} else if p.fileExists("/etc/os-release") {
info.WriteString("发行版: /etc/os-release 存在\n")
}
}
// whoami
if output, err := p.runCommand("whoami"); err == nil {
info.WriteString(fmt.Sprintf("当前用户(whoami): %s\n", strings.TrimSpace(output)))
}
}
return info.String()
}
// runCommand 执行命令 - 简单包装,无复杂错误处理
func (p *SystemInfoPlugin) runCommand(name string, args ...string) (string, error) {
cmd := exec.Command(name, args...)
output, err := cmd.Output()
return string(output), err
}
// fileExists 检查文件是否存在
func (p *SystemInfoPlugin) fileExists(path string) bool {
_, err := os.Stat(path)
return err == nil
}
// 注册插件
func init() {
RegisterLocalPlugin("systeminfo", func() Plugin {
return NewSystemInfoPlugin()
})
}