From 1f0d11d93ef1c24dad2f27e72becb800ba3f5b0f Mon Sep 17 00:00:00 2001 From: tongque <2863528786@qq.com> Date: Mon, 14 Apr 2025 15:37:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=BF=9C=E7=A8=8B?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E8=A7=A3=E6=9E=90=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=89=AB=E6=8F=8F=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Common/Flag.go | 125 +++++++++++++++++++++++++++++++++++++------ RPC/service/fscan.go | 10 ++++ 2 files changed, 118 insertions(+), 17 deletions(-) diff --git a/Common/Flag.go b/Common/Flag.go index f82abac..e92cf81 100644 --- a/Common/Flag.go +++ b/Common/Flag.go @@ -5,10 +5,98 @@ import ( "fmt" "os" "strings" + "sync" "github.com/fatih/color" ) +var flagInitOnce sync.Once + +// defineFlags 用于本地 CLI 注册全局 flag.CommandLine 的 flag +func defineFlags(info *HostInfo) { + flagInitOnce.Do(func() { + defineFlagsForSet(flag.CommandLine, info) + }) +} + +// 通用 flag 注册逻辑,支持 flag.CommandLine 和新建 FlagSet(用于远程) +func defineFlagsForSet(fs *flag.FlagSet, info *HostInfo) { + // 目标配置参数 + fs.StringVar(&info.Host, "h", "", GetText("flag_host")) + fs.StringVar(&ExcludeHosts, "eh", "", GetText("flag_exclude_hosts")) + fs.StringVar(&Ports, "p", MainPorts, GetText("flag_ports")) + fs.StringVar(&HostsFile, "hf", "", GetText("flag_hosts_file")) + fs.StringVar(&PortsFile, "pf", "", GetText("flag_ports_file")) + + // 扫描控制参数 + fs.StringVar(&ScanMode, "m", "All", GetText("flag_scan_mode")) + fs.IntVar(&ThreadNum, "t", 10, GetText("flag_thread_num")) + fs.Int64Var(&Timeout, "time", 3, GetText("flag_timeout")) + fs.IntVar(&ModuleThreadNum, "mt", 10, GetText("flag_module_thread_num")) + fs.Int64Var(&GlobalTimeout, "gt", 180, GetText("flag_global_timeout")) + fs.IntVar(&LiveTop, "top", 10, GetText("flag_live_top")) + fs.BoolVar(&DisablePing, "np", false, GetText("flag_disable_ping")) + fs.BoolVar(&UsePing, "ping", false, GetText("flag_use_ping")) + fs.BoolVar(&EnableFingerprint, "fingerprint", false, GetText("flag_enable_fingerprint")) + fs.BoolVar(&LocalMode, "local", false, GetText("flag_local_mode")) + + // 认证与凭据参数 + fs.StringVar(&Username, "user", "", GetText("flag_username")) + fs.StringVar(&Password, "pwd", "", GetText("flag_password")) + fs.StringVar(&AddUsers, "usera", "", GetText("flag_add_users")) + fs.StringVar(&AddPasswords, "pwda", "", GetText("flag_add_passwords")) + fs.StringVar(&UsersFile, "userf", "", GetText("flag_users_file")) + fs.StringVar(&PasswordsFile, "pwdf", "", GetText("flag_passwords_file")) + fs.StringVar(&HashFile, "hashf", "", GetText("flag_hash_file")) + fs.StringVar(&HashValue, "hash", "", GetText("flag_hash_value")) + fs.StringVar(&Domain, "domain", "", GetText("flag_domain")) + fs.StringVar(&SshKeyPath, "sshkey", "", GetText("flag_ssh_key")) + + // Web扫描参数 + fs.StringVar(&TargetURL, "u", "", GetText("flag_target_url")) + fs.StringVar(&URLsFile, "uf", "", GetText("flag_urls_file")) + fs.StringVar(&Cookie, "cookie", "", GetText("flag_cookie")) + fs.Int64Var(&WebTimeout, "wt", 5, GetText("flag_web_timeout")) + fs.StringVar(&HttpProxy, "proxy", "", GetText("flag_http_proxy")) + fs.StringVar(&Socks5Proxy, "socks5", "", GetText("flag_socks5_proxy")) + + // POC测试参数 + fs.StringVar(&PocPath, "pocpath", "", GetText("flag_poc_path")) + fs.StringVar(&Pocinfo.PocName, "pocname", "", GetText("flag_poc_name")) + fs.BoolVar(&PocFull, "full", false, GetText("flag_poc_full")) + fs.BoolVar(&DnsLog, "dns", false, GetText("flag_dns_log")) + fs.IntVar(&PocNum, "num", 20, GetText("flag_poc_num")) + + // Redis利用参数 + fs.StringVar(&RedisFile, "rf", "", GetText("flag_redis_file")) + fs.StringVar(&RedisShell, "rs", "", GetText("flag_redis_shell")) + fs.BoolVar(&DisableRedis, "noredis", false, GetText("flag_disable_redis")) + fs.StringVar(&RedisWritePath, "rwp", "", GetText("flag_redis_write_path")) + fs.StringVar(&RedisWriteContent, "rwc", "", GetText("flag_redis_write_content")) + fs.StringVar(&RedisWriteFile, "rwf", "", GetText("flag_redis_write_file")) + + // 暴力破解控制参数 + fs.BoolVar(&DisableBrute, "nobr", false, GetText("flag_disable_brute")) + fs.IntVar(&MaxRetries, "retry", 3, GetText("flag_max_retries")) + + // 输出与显示控制参数 + fs.StringVar(&Outputfile, "o", "result.txt", GetText("flag_output_file")) + fs.StringVar(&OutputFormat, "f", "txt", GetText("flag_output_format")) + fs.BoolVar(&DisableSave, "no", false, GetText("flag_disable_save")) + fs.BoolVar(&Silent, "silent", false, GetText("flag_silent_mode")) + fs.BoolVar(&NoColor, "nocolor", false, GetText("flag_no_color")) + fs.StringVar(&LogLevel, "log", LogLevelSuccess, GetText("flag_log_level")) + fs.BoolVar(&ShowProgress, "pg", false, GetText("flag_show_progress")) + fs.BoolVar(&ShowScanPlan, "sp", false, GetText("flag_show_scan_plan")) + fs.BoolVar(&SlowLogOutput, "slow", false, GetText("flag_slow_log_output")) + + // 其他参数 + fs.StringVar(&Shellcode, "sc", "", GetText("flag_shellcode")) + fs.StringVar(&Language, "lang", "zh", GetText("flag_language")) + fs.StringVar(&ApiAddr, "api", "", GetText("flag_api")) + fs.StringVar(&SecretKey, "secret", "", GetText("flag_api_key")) +} + func Banner() { // 定义暗绿色系 colors := []color.Attribute{ @@ -56,8 +144,7 @@ func Banner() { c.Printf(" Fscan Version: %s\n\n", version) } -// Flag 解析命令行参数并配置扫描选项 -func Flag(Info *HostInfo) { +func Flag(info *HostInfo) { Banner() // ═════════════════════════════════════════════════ @@ -157,42 +244,48 @@ func Flag(Info *HostInfo) { // 解析命令行参数 parseCommandLineArgs() - - // 设置语言 SetLanguage() } -// parseCommandLineArgs 处理来自环境变量和命令行的参数 +func FlagFromRemote(info *HostInfo, argString string) error { + if strings.TrimSpace(argString) == "" { + return fmt.Errorf("参数为空") + } + args, err := parseEnvironmentArgs(argString) + if err != nil { + return fmt.Errorf("远程参数解析失败: %v", err) + } + + fs := flag.NewFlagSet("remote", flag.ContinueOnError) + defineFlagsForSet(fs, info) + + if err := fs.Parse(args); err != nil { + return fmt.Errorf("参数解析失败: %v", err) + } + return nil +} + func parseCommandLineArgs() { - // 首先检查环境变量中的参数 envArgsString := os.Getenv("FS_ARGS") if envArgsString != "" { - // 解析环境变量参数 (跨平台支持) envArgs, err := parseEnvironmentArgs(envArgsString) if err == nil && len(envArgs) > 0 { flag.CommandLine.Parse(envArgs) - os.Unsetenv("FS_ARGS") // 使用后清除环境变量 + os.Unsetenv("FS_ARGS") return } - // 如果环境变量解析失败,继续使用命令行参数 } - - // 解析命令行参数 flag.Parse() } -// parseEnvironmentArgs 安全地解析环境变量中的参数 func parseEnvironmentArgs(argsString string) ([]string, error) { if strings.TrimSpace(argsString) == "" { return nil, fmt.Errorf("empty arguments string") } - - // 使用更安全的参数分割方法 var args []string var currentArg strings.Builder inQuote := false quoteChar := ' ' - for _, char := range argsString { switch { case char == '"' || char == '\'': @@ -213,10 +306,8 @@ func parseEnvironmentArgs(argsString string) ([]string, error) { currentArg.WriteRune(char) } } - if currentArg.Len() > 0 { args = append(args, currentArg.String()) } - return args, nil } diff --git a/RPC/service/fscan.go b/RPC/service/fscan.go index 5d2aa29..a4d3a08 100644 --- a/RPC/service/fscan.go +++ b/RPC/service/fscan.go @@ -5,6 +5,7 @@ import ( "time" "github.com/shadow1ng/fscan/Common" + "github.com/shadow1ng/fscan/Core" pb "github.com/shadow1ng/fscan/RPC/lib" ) @@ -24,6 +25,15 @@ func (s *FscanService) StartScan(ctx context.Context, req *pb.StartScanRequest) Common.LogDebug("接收到扫描请求,目标: " + req.Arg + ", " + req.Secret) // TODO: 在此处实现实际的扫描逻辑,例如调用扫描器、创建任务、存储任务状态等。 // 可以异步执行扫描逻辑,并生成一个唯一的 taskID 进行标识。 + var info Common.HostInfo + if err := Common.FlagFromRemote(&info, req.Arg); err != nil { + return nil, err + } + if err := Common.Parse(&info); err != nil { + return nil, err + } + Common.LogDebug("解析参数成功,目标: " + info.Host + ", " + info.Ports) + go Core.Scan(info) // 建议异步执行 return &pb.StartScanResponse{ TaskId: "task_123456", // TODO: 返回真实生成的 taskID