feat: 增加远程参数解析功能并重构扫描逻辑

This commit is contained in:
tongque 2025-04-14 15:37:54 +08:00
parent a3c5092f9b
commit 1f0d11d93e
2 changed files with 118 additions and 17 deletions

View File

@ -5,10 +5,98 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"sync"
"github.com/fatih/color" "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() { func Banner() {
// 定义暗绿色系 // 定义暗绿色系
colors := []color.Attribute{ colors := []color.Attribute{
@ -56,8 +144,7 @@ func Banner() {
c.Printf(" Fscan Version: %s\n\n", version) c.Printf(" Fscan Version: %s\n\n", version)
} }
// Flag 解析命令行参数并配置扫描选项 func Flag(info *HostInfo) {
func Flag(Info *HostInfo) {
Banner() Banner()
// ═════════════════════════════════════════════════ // ═════════════════════════════════════════════════
@ -157,42 +244,48 @@ func Flag(Info *HostInfo) {
// 解析命令行参数 // 解析命令行参数
parseCommandLineArgs() parseCommandLineArgs()
// 设置语言
SetLanguage() 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() { func parseCommandLineArgs() {
// 首先检查环境变量中的参数
envArgsString := os.Getenv("FS_ARGS") envArgsString := os.Getenv("FS_ARGS")
if envArgsString != "" { if envArgsString != "" {
// 解析环境变量参数 (跨平台支持)
envArgs, err := parseEnvironmentArgs(envArgsString) envArgs, err := parseEnvironmentArgs(envArgsString)
if err == nil && len(envArgs) > 0 { if err == nil && len(envArgs) > 0 {
flag.CommandLine.Parse(envArgs) flag.CommandLine.Parse(envArgs)
os.Unsetenv("FS_ARGS") // 使用后清除环境变量 os.Unsetenv("FS_ARGS")
return return
} }
// 如果环境变量解析失败,继续使用命令行参数
} }
// 解析命令行参数
flag.Parse() flag.Parse()
} }
// parseEnvironmentArgs 安全地解析环境变量中的参数
func parseEnvironmentArgs(argsString string) ([]string, error) { func parseEnvironmentArgs(argsString string) ([]string, error) {
if strings.TrimSpace(argsString) == "" { if strings.TrimSpace(argsString) == "" {
return nil, fmt.Errorf("empty arguments string") return nil, fmt.Errorf("empty arguments string")
} }
// 使用更安全的参数分割方法
var args []string var args []string
var currentArg strings.Builder var currentArg strings.Builder
inQuote := false inQuote := false
quoteChar := ' ' quoteChar := ' '
for _, char := range argsString { for _, char := range argsString {
switch { switch {
case char == '"' || char == '\'': case char == '"' || char == '\'':
@ -213,10 +306,8 @@ func parseEnvironmentArgs(argsString string) ([]string, error) {
currentArg.WriteRune(char) currentArg.WriteRune(char)
} }
} }
if currentArg.Len() > 0 { if currentArg.Len() > 0 {
args = append(args, currentArg.String()) args = append(args, currentArg.String())
} }
return args, nil return args, nil
} }

View File

@ -5,6 +5,7 @@ import (
"time" "time"
"github.com/shadow1ng/fscan/Common" "github.com/shadow1ng/fscan/Common"
"github.com/shadow1ng/fscan/Core"
pb "github.com/shadow1ng/fscan/RPC/lib" 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) Common.LogDebug("接收到扫描请求,目标: " + req.Arg + ", " + req.Secret)
// TODO: 在此处实现实际的扫描逻辑,例如调用扫描器、创建任务、存储任务状态等。 // TODO: 在此处实现实际的扫描逻辑,例如调用扫描器、创建任务、存储任务状态等。
// 可以异步执行扫描逻辑,并生成一个唯一的 taskID 进行标识。 // 可以异步执行扫描逻辑,并生成一个唯一的 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{ return &pb.StartScanResponse{
TaskId: "task_123456", // TODO: 返回真实生成的 taskID TaskId: "task_123456", // TODO: 返回真实生成的 taskID