mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-07-13 12:52:44 +08:00
feat: i18n
This commit is contained in:
parent
eb8cda3b7f
commit
3dde342d65
@ -936,6 +936,8 @@ var (
|
||||
JsonFormat bool // JSON格式输出
|
||||
LogLevel string // 日志输出级别
|
||||
ShowProgress bool // 是否显示进度条
|
||||
|
||||
Language string // 语言
|
||||
)
|
||||
|
||||
var (
|
||||
|
144
Common/Flag.go
144
Common/Flag.go
@ -58,115 +58,81 @@ func Flag(Info *HostInfo) {
|
||||
Banner()
|
||||
|
||||
// 目标配置
|
||||
flag.StringVar(&Info.Host, "h", "", "指定目标主机,支持以下格式:\n"+
|
||||
" - 单个IP: 192.168.11.11\n"+
|
||||
" - IP范围: 192.168.11.11-255\n"+
|
||||
" - 多个IP: 192.168.11.11,192.168.11.12")
|
||||
flag.StringVar(&ExcludeHosts, "eh", "", "排除指定主机范围,支持CIDR格式,如: 192.168.1.1/24")
|
||||
flag.StringVar(&Ports, "p", MainPorts, "指定扫描端口,支持以下格式:\n"+
|
||||
"端口格式:\n"+
|
||||
" - 单个端口: 22\n"+
|
||||
" - 端口范围: 1-65535\n"+
|
||||
" - 多个端口: 22,80,3306\n\n"+
|
||||
"预定义端口组(别名):\n"+
|
||||
" - main: 常用端口 (21,22,23,80,81,135,139,443,445,1433,1521,3306,5432,6379,7001,8000,8080,8089,9000,9200,11211,27017)\n"+
|
||||
" - service: 服务端口 (21,22,23,135,139,445,1433,1521,2222,3306,3389,5432,6379,9000,11211,27017)\n"+
|
||||
" - db: 数据库端口 (1433,1521,3306,5432,6379,11211,27017)\n"+
|
||||
" - web: Web服务端口 (包含常见的 80-90,443,800-1080,2000-8000,8080-9000,9090-10000 等Web端口)\n"+
|
||||
" - all: 全部端口 (1-65535)\n\n"+
|
||||
"示例:\n"+
|
||||
" -p main 扫描常用端口\n"+
|
||||
" -p web 扫描Web端口\n"+
|
||||
" -p 80,443 扫描指定端口\n"+
|
||||
" -p 1-1000 扫描1-1000端口范围\n"+
|
||||
"默认使用 main 端口组")
|
||||
flag.StringVar(&AddPorts, "pa", "", "在默认端口基础上额外添加端口,如: -pa 3389")
|
||||
flag.StringVar(&ExcludePorts, "pn", "", "排除指定端口,如: -pn 445")
|
||||
flag.StringVar(&Info.Host, "h", "", GetText("flag_host"))
|
||||
flag.StringVar(&ExcludeHosts, "eh", "", GetText("flag_exclude_hosts"))
|
||||
flag.StringVar(&Ports, "p", MainPorts, GetText("flag_ports"))
|
||||
|
||||
// 认证配置
|
||||
flag.StringVar(&AddUsers, "usera", "", "在默认用户列表基础上添加自定义用户名")
|
||||
flag.StringVar(&AddPasswords, "pwda", "", "在默认密码列表基础上添加自定义密码")
|
||||
flag.StringVar(&Username, "user", "", "指定单个用户名")
|
||||
flag.StringVar(&Password, "pwd", "", "指定单个密码")
|
||||
flag.StringVar(&Domain, "domain", "", "指定域名(仅用于SMB协议)")
|
||||
flag.StringVar(&SshKeyPath, "sshkey", "", "指定SSH私钥文件路径(默认为id_rsa)")
|
||||
flag.StringVar(&AddUsers, "usera", "", GetText("flag_add_users"))
|
||||
flag.StringVar(&AddPasswords, "pwda", "", GetText("flag_add_passwords"))
|
||||
flag.StringVar(&Username, "user", "", GetText("flag_username"))
|
||||
flag.StringVar(&Password, "pwd", "", GetText("flag_password"))
|
||||
flag.StringVar(&Domain, "domain", "", GetText("flag_domain"))
|
||||
flag.StringVar(&SshKeyPath, "sshkey", "", GetText("flag_ssh_key"))
|
||||
|
||||
// 扫描配置
|
||||
flag.StringVar(&ScanMode, "m", "All", "指定扫描模式:\n"+
|
||||
"预设扫描模式(大写开头):\n"+
|
||||
" - All: 全量扫描,包含所有可用插件\n"+
|
||||
" - Basic: 基础扫描,包含 web/ftp/ssh/smb/findnet\n"+
|
||||
" - Database: 数据库扫描,包含 mysql/mssql/redis/mongodb/postgres/oracle/memcached\n"+
|
||||
" - Web: Web服务扫描,包含 web/fcgi\n"+
|
||||
" - Service: 常见服务扫描,包含 ftp/ssh/telnet/smb/rdp/vnc/netbios\n"+
|
||||
" - Vul: 漏洞扫描,包含 ms17010/smbghost/smb2\n"+
|
||||
" - Port: 端口扫描模式\n"+
|
||||
" - ICMP: ICMP存活探测\n"+
|
||||
" - Local: 本地信息收集\n\n"+
|
||||
"单个插件模式(小写):\n"+
|
||||
" Web类: web, fcgi\n"+
|
||||
" 数据库类: mysql, mssql, redis, mongodb, postgres, oracle, memcached\n"+
|
||||
" 服务类: ftp, ssh, telnet, smb, rdp, vnc, netbios\n"+
|
||||
" 漏洞类: ms17010, smbghost, smb2\n"+
|
||||
" 其他: findnet, wmiexec, localinfo")
|
||||
//flag.BoolVar(&UseSynScan, "sS", false, "使用SYN扫描替代TCP全连接扫描(需要root/管理员权限)")
|
||||
flag.IntVar(&ThreadNum, "t", 60, "设置扫描线程数")
|
||||
flag.Int64Var(&Timeout, "time", 3, "设置连接超时时间(单位:秒)")
|
||||
flag.IntVar(&LiveTop, "top", 10, "仅显示指定数量的存活主机")
|
||||
flag.BoolVar(&DisablePing, "np", false, "禁用主机存活探测")
|
||||
flag.BoolVar(&UsePing, "ping", false, "使用系统ping命令替代ICMP探测")
|
||||
flag.StringVar(&Command, "c", "", "指定要执行的系统命令(支持ssh和wmiexec)")
|
||||
flag.BoolVar(&SkipFingerprint, "skip", false, "跳过端口指纹识别")
|
||||
flag.StringVar(&ScanMode, "m", "All", GetText("flag_scan_mode"))
|
||||
flag.IntVar(&ThreadNum, "t", 60, GetText("flag_thread_num"))
|
||||
flag.Int64Var(&Timeout, "time", 3, GetText("flag_timeout"))
|
||||
flag.IntVar(&LiveTop, "top", 10, GetText("flag_live_top"))
|
||||
flag.BoolVar(&DisablePing, "np", false, GetText("flag_disable_ping"))
|
||||
flag.BoolVar(&UsePing, "ping", false, GetText("flag_use_ping"))
|
||||
flag.StringVar(&Command, "c", "", GetText("flag_command"))
|
||||
flag.BoolVar(&SkipFingerprint, "skip", false, GetText("flag_skip_fingerprint"))
|
||||
|
||||
// 文件配置
|
||||
flag.StringVar(&HostsFile, "hf", "", "从文件中读取目标主机列表")
|
||||
flag.StringVar(&UsersFile, "userf", "", "从文件中读取用户名字典")
|
||||
flag.StringVar(&PasswordsFile, "pwdf", "", "从文件中读取密码字典")
|
||||
flag.StringVar(&HashFile, "hashf", "", "从文件中读取Hash字典")
|
||||
flag.StringVar(&PortsFile, "portf", "", "从文件中读取端口列表")
|
||||
flag.StringVar(&HostsFile, "hf", "", GetText("flag_hosts_file"))
|
||||
flag.StringVar(&UsersFile, "userf", "", GetText("flag_users_file"))
|
||||
flag.StringVar(&PasswordsFile, "pwdf", "", GetText("flag_passwords_file"))
|
||||
flag.StringVar(&HashFile, "hashf", "", GetText("flag_hash_file"))
|
||||
flag.StringVar(&PortsFile, "portf", "", GetText("flag_ports_file"))
|
||||
|
||||
// Web配置
|
||||
flag.StringVar(&TargetURL, "u", "", "指定目标URL")
|
||||
flag.StringVar(&URLsFile, "uf", "", "从文件中读取URL列表")
|
||||
flag.StringVar(&Cookie, "cookie", "", "设置HTTP请求Cookie")
|
||||
flag.Int64Var(&WebTimeout, "wt", 5, "设置Web请求超时时间(单位:秒)")
|
||||
flag.StringVar(&HttpProxy, "proxy", "", "设置HTTP代理服务器")
|
||||
flag.StringVar(&Socks5Proxy, "socks5", "", "设置Socks5代理(用于TCP连接,将影响超时设置)")
|
||||
flag.StringVar(&TargetURL, "u", "", GetText("flag_target_url"))
|
||||
flag.StringVar(&URLsFile, "uf", "", GetText("flag_urls_file"))
|
||||
flag.StringVar(&Cookie, "cookie", "", GetText("flag_cookie"))
|
||||
flag.Int64Var(&WebTimeout, "wt", 5, GetText("flag_web_timeout"))
|
||||
flag.StringVar(&HttpProxy, "proxy", "", GetText("flag_http_proxy"))
|
||||
flag.StringVar(&Socks5Proxy, "socks5", "", GetText("flag_socks5_proxy"))
|
||||
|
||||
// 本地扫描配置
|
||||
flag.BoolVar(&LocalMode, "local", false, "启用本地信息收集模式")
|
||||
flag.BoolVar(&LocalMode, "local", false, GetText("flag_local_mode"))
|
||||
|
||||
// POC配置
|
||||
flag.StringVar(&PocPath, "pocpath", "", "指定自定义POC文件路径")
|
||||
flag.StringVar(&Pocinfo.PocName, "pocname", "", "指定要使用的POC名称,如: -pocname weblogic")
|
||||
flag.BoolVar(&PocFull, "full", false, "启用完整POC扫描(如测试shiro全部100个key)")
|
||||
flag.BoolVar(&DnsLog, "dns", false, "启用dnslog进行漏洞验证")
|
||||
flag.IntVar(&PocNum, "num", 20, "设置POC扫描并发数")
|
||||
flag.StringVar(&PocPath, "pocpath", "", GetText("flag_poc_path"))
|
||||
flag.StringVar(&Pocinfo.PocName, "pocname", "", GetText("flag_poc_name"))
|
||||
flag.BoolVar(&PocFull, "full", false, GetText("flag_poc_full"))
|
||||
flag.BoolVar(&DnsLog, "dns", false, GetText("flag_dns_log"))
|
||||
flag.IntVar(&PocNum, "num", 20, GetText("flag_poc_num"))
|
||||
|
||||
// Redis利用配置
|
||||
flag.StringVar(&RedisFile, "rf", "", "指定Redis写入的SSH公钥文件")
|
||||
flag.StringVar(&RedisShell, "rs", "", "指定Redis写入的计划任务内容")
|
||||
flag.BoolVar(&DisableRedis, "noredis", false, "禁用Redis安全检测")
|
||||
flag.StringVar(&RedisFile, "rf", "", GetText("flag_redis_file"))
|
||||
flag.StringVar(&RedisShell, "rs", "", GetText("flag_redis_shell"))
|
||||
flag.BoolVar(&DisableRedis, "noredis", false, GetText("flag_disable_redis"))
|
||||
|
||||
// 暴力破解配置
|
||||
flag.BoolVar(&DisableBrute, "nobr", false, "禁用密码暴力破解")
|
||||
flag.IntVar(&MaxRetries, "retry", 3, "设置最大重试次数")
|
||||
flag.BoolVar(&DisableBrute, "nobr", false, GetText("flag_disable_brute"))
|
||||
flag.IntVar(&MaxRetries, "retry", 3, GetText("flag_max_retries"))
|
||||
|
||||
// 其他配置
|
||||
flag.StringVar(&RemotePath, "path", "", "指定FCG/SMB远程文件路径")
|
||||
flag.StringVar(&HashValue, "hash", "", "指定要破解的Hash值")
|
||||
flag.StringVar(&Shellcode, "sc", "", "指定MS17漏洞利用的shellcode")
|
||||
flag.BoolVar(&EnableWmi, "wmi", false, "启用WMI协议扫描")
|
||||
flag.StringVar(&RemotePath, "path", "", GetText("flag_remote_path"))
|
||||
flag.StringVar(&HashValue, "hash", "", GetText("flag_hash_value"))
|
||||
flag.StringVar(&Shellcode, "sc", "", GetText("flag_shellcode"))
|
||||
flag.BoolVar(&EnableWmi, "wmi", false, GetText("flag_enable_wmi"))
|
||||
|
||||
// 输出配置
|
||||
flag.StringVar(&Outputfile, "o", "result.txt", "指定结果输出文件名")
|
||||
flag.StringVar(&OutputFormat, "f", "txt", "指定输出格式 (txt/json/csv)")
|
||||
flag.BoolVar(&DisableSave, "no", false, "禁止保存扫描结果")
|
||||
flag.BoolVar(&Silent, "silent", false, "启用静默扫描模式(减少屏幕输出)")
|
||||
flag.BoolVar(&NoColor, "nocolor", false, "禁用彩色输出显示")
|
||||
flag.BoolVar(&JsonFormat, "json", false, "以JSON格式输出结果")
|
||||
flag.StringVar(&LogLevel, "log", LogLevelSuccess, "日志输出级别(ALL/SUCCESS/ERROR/INFO/DEBUG)")
|
||||
flag.BoolVar(&ShowProgress, "pg", false, "开启进度条显示")
|
||||
flag.StringVar(&Outputfile, "o", "result.txt", GetText("flag_output_file"))
|
||||
flag.StringVar(&OutputFormat, "f", "txt", GetText("flag_output_format"))
|
||||
flag.BoolVar(&DisableSave, "no", false, GetText("flag_disable_save"))
|
||||
flag.BoolVar(&Silent, "silent", false, GetText("flag_silent_mode"))
|
||||
flag.BoolVar(&NoColor, "nocolor", false, GetText("flag_no_color"))
|
||||
flag.BoolVar(&JsonFormat, "json", false, GetText("flag_json_format"))
|
||||
flag.StringVar(&LogLevel, "log", LogLevelSuccess, GetText("flag_log_level"))
|
||||
flag.BoolVar(&ShowProgress, "pg", false, GetText("flag_show_progress"))
|
||||
|
||||
flag.StringVar(&Language, "lang", "en", GetText("flag_language"))
|
||||
|
||||
flag.Parse()
|
||||
|
||||
SetLanguage()
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
// output.go
|
||||
|
||||
package Common
|
||||
|
||||
import (
|
||||
@ -48,25 +46,25 @@ type ScanResult struct {
|
||||
|
||||
// InitOutput 初始化输出系统
|
||||
func InitOutput() error {
|
||||
LogDebug("开始初始化输出系统")
|
||||
LogDebug(GetText("output_init_start"))
|
||||
|
||||
// 验证输出格式
|
||||
switch OutputFormat {
|
||||
case "txt", "json", "csv":
|
||||
// 有效的格式
|
||||
default:
|
||||
return fmt.Errorf("不支持的输出格式: %s", OutputFormat)
|
||||
return fmt.Errorf(GetText("output_format_invalid"), OutputFormat)
|
||||
}
|
||||
|
||||
// 验证输出路径
|
||||
if Outputfile == "" {
|
||||
return fmt.Errorf("输出文件路径不能为空")
|
||||
return fmt.Errorf(GetText("output_path_empty"))
|
||||
}
|
||||
|
||||
dir := filepath.Dir(Outputfile)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
LogDebug(fmt.Sprintf("创建输出目录失败: %v", err))
|
||||
return fmt.Errorf("创建输出目录失败: %v", err)
|
||||
LogDebug(GetText("output_create_dir_failed", err))
|
||||
return fmt.Errorf(GetText("output_create_dir_failed", err))
|
||||
}
|
||||
|
||||
manager := &OutputManager{
|
||||
@ -75,12 +73,12 @@ func InitOutput() error {
|
||||
}
|
||||
|
||||
if err := manager.initialize(); err != nil {
|
||||
LogDebug(fmt.Sprintf("初始化输出管理器失败: %v", err))
|
||||
return fmt.Errorf("初始化输出管理器失败: %v", err)
|
||||
LogDebug(GetText("output_init_failed", err))
|
||||
return fmt.Errorf(GetText("output_init_failed", err))
|
||||
}
|
||||
|
||||
ResultOutput = manager
|
||||
LogDebug("输出系统初始化完成")
|
||||
LogDebug(GetText("output_init_success"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -89,52 +87,52 @@ func (om *OutputManager) initialize() error {
|
||||
defer om.mu.Unlock()
|
||||
|
||||
if om.isInitialized {
|
||||
LogDebug("输出管理器已经初始化,跳过")
|
||||
LogDebug(GetText("output_already_init"))
|
||||
return nil
|
||||
}
|
||||
|
||||
LogDebug(fmt.Sprintf("正在打开输出文件: %s", om.outputPath))
|
||||
LogDebug(GetText("output_opening_file", om.outputPath))
|
||||
file, err := os.OpenFile(om.outputPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
LogDebug(fmt.Sprintf("打开输出文件失败: %v", err))
|
||||
return fmt.Errorf("打开输出文件失败: %v", err)
|
||||
LogDebug(GetText("output_open_file_failed", err))
|
||||
return fmt.Errorf(GetText("output_open_file_failed", err))
|
||||
}
|
||||
om.file = file
|
||||
|
||||
switch om.outputFormat {
|
||||
case "csv":
|
||||
LogDebug("初始化CSV写入器")
|
||||
LogDebug(GetText("output_init_csv"))
|
||||
om.csvWriter = csv.NewWriter(file)
|
||||
headers := []string{"Time", "Type", "Target", "Status", "Details"}
|
||||
if err := om.csvWriter.Write(headers); err != nil {
|
||||
LogDebug(fmt.Sprintf("写入CSV头失败: %v", err))
|
||||
LogDebug(GetText("output_write_csv_header_failed", err))
|
||||
file.Close()
|
||||
return fmt.Errorf("写入CSV头失败: %v", err)
|
||||
return fmt.Errorf(GetText("output_write_csv_header_failed", err))
|
||||
}
|
||||
om.csvWriter.Flush()
|
||||
case "json":
|
||||
LogDebug("初始化JSON编码器")
|
||||
LogDebug(GetText("output_init_json"))
|
||||
om.jsonEncoder = json.NewEncoder(file)
|
||||
om.jsonEncoder.SetIndent("", " ")
|
||||
case "txt":
|
||||
LogDebug("初始化文本输出")
|
||||
LogDebug(GetText("output_init_txt"))
|
||||
default:
|
||||
LogDebug(fmt.Sprintf("不支持的输出格式: %s", om.outputFormat))
|
||||
LogDebug(GetText("output_format_invalid", om.outputFormat))
|
||||
}
|
||||
|
||||
om.isInitialized = true
|
||||
LogDebug("输出管理器初始化完成")
|
||||
LogDebug(GetText("output_init_complete"))
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveResult 保存扫描结果
|
||||
func SaveResult(result *ScanResult) error {
|
||||
if ResultOutput == nil {
|
||||
LogDebug("输出系统未初始化")
|
||||
return fmt.Errorf("输出系统未初始化")
|
||||
LogDebug(GetText("output_not_init"))
|
||||
return fmt.Errorf(GetText("output_not_init"))
|
||||
}
|
||||
|
||||
LogDebug(fmt.Sprintf("正在保存结果 - 类型: %s, 目标: %s", result.Type, result.Target))
|
||||
LogDebug(GetText("output_saving_result", result.Type, result.Target))
|
||||
return ResultOutput.saveResult(result)
|
||||
}
|
||||
|
||||
@ -143,8 +141,8 @@ func (om *OutputManager) saveResult(result *ScanResult) error {
|
||||
defer om.mu.Unlock()
|
||||
|
||||
if !om.isInitialized {
|
||||
LogDebug("输出管理器未初始化")
|
||||
return fmt.Errorf("输出管理器未初始化")
|
||||
LogDebug(GetText("output_not_init"))
|
||||
return fmt.Errorf(GetText("output_not_init"))
|
||||
}
|
||||
|
||||
var err error
|
||||
@ -156,14 +154,14 @@ func (om *OutputManager) saveResult(result *ScanResult) error {
|
||||
case "csv":
|
||||
err = om.writeCsv(result)
|
||||
default:
|
||||
LogDebug(fmt.Sprintf("不支持的输出格式: %s", om.outputFormat))
|
||||
return fmt.Errorf("不支持的输出格式: %s", om.outputFormat)
|
||||
LogDebug(GetText("output_format_invalid", om.outputFormat))
|
||||
return fmt.Errorf(GetText("output_format_invalid", om.outputFormat))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
LogDebug(fmt.Sprintf("保存结果失败: %v", err))
|
||||
LogDebug(GetText("output_save_failed", err))
|
||||
} else {
|
||||
LogDebug(fmt.Sprintf("成功保存结果 - 类型: %s, 目标: %s", result.Type, result.Target))
|
||||
LogDebug(GetText("output_save_success", result.Type, result.Target))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@ -179,13 +177,13 @@ func (om *OutputManager) writeTxt(result *ScanResult) error {
|
||||
details = strings.Join(pairs, ", ")
|
||||
}
|
||||
|
||||
txt := fmt.Sprintf("[%s] [%s] Target: %s, Status: %s, Details: {%s}\n",
|
||||
txt := GetText("output_txt_format",
|
||||
result.Time.Format("2006-01-02 15:04:05"),
|
||||
result.Type,
|
||||
result.Target,
|
||||
result.Status,
|
||||
details,
|
||||
)
|
||||
) + "\n"
|
||||
_, err := om.file.WriteString(txt)
|
||||
return err
|
||||
}
|
||||
@ -218,30 +216,30 @@ func (om *OutputManager) writeCsv(result *ScanResult) error {
|
||||
// CloseOutput 关闭输出系统
|
||||
func CloseOutput() error {
|
||||
if ResultOutput == nil {
|
||||
LogDebug("输出系统未初始化,无需关闭")
|
||||
LogDebug(GetText("output_no_need_close"))
|
||||
return nil
|
||||
}
|
||||
|
||||
LogDebug("正在关闭输出系统")
|
||||
LogDebug(GetText("output_closing"))
|
||||
ResultOutput.mu.Lock()
|
||||
defer ResultOutput.mu.Unlock()
|
||||
|
||||
if !ResultOutput.isInitialized {
|
||||
LogDebug("输出管理器未初始化,无需关闭")
|
||||
LogDebug(GetText("output_no_need_close"))
|
||||
return nil
|
||||
}
|
||||
|
||||
if ResultOutput.csvWriter != nil {
|
||||
LogDebug("刷新CSV写入器缓冲区")
|
||||
LogDebug(GetText("output_flush_csv"))
|
||||
ResultOutput.csvWriter.Flush()
|
||||
}
|
||||
|
||||
if err := ResultOutput.file.Close(); err != nil {
|
||||
LogDebug(fmt.Sprintf("关闭文件失败: %v", err))
|
||||
return fmt.Errorf("关闭文件失败: %v", err)
|
||||
LogDebug(GetText("output_close_failed", err))
|
||||
return fmt.Errorf(GetText("output_close_failed", err))
|
||||
}
|
||||
|
||||
ResultOutput.isInitialized = false
|
||||
LogDebug("输出系统已关闭")
|
||||
LogDebug(GetText("output_closed"))
|
||||
return nil
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ func ParseUser() error {
|
||||
// 处理直接指定的用户名列表
|
||||
if Username != "" {
|
||||
usernames = strings.Split(Username, ",")
|
||||
LogInfo(fmt.Sprintf("加载用户名: %d 个", len(usernames)))
|
||||
LogInfo(GetText("no_username_specified", len(usernames)))
|
||||
}
|
||||
|
||||
// 从文件加载用户名列表
|
||||
@ -47,12 +47,12 @@ func ParseUser() error {
|
||||
usernames = append(usernames, user)
|
||||
}
|
||||
}
|
||||
LogInfo(fmt.Sprintf("从文件加载用户名: %d 个", len(users)))
|
||||
LogInfo(GetText("load_usernames_from_file", len(users)))
|
||||
}
|
||||
|
||||
// 去重处理
|
||||
usernames = RemoveDuplicate(usernames)
|
||||
LogInfo(fmt.Sprintf("用户名总数: %d 个", len(usernames)))
|
||||
LogInfo(GetText("total_usernames", len(usernames)))
|
||||
|
||||
// 更新用户字典
|
||||
for name := range Userdict {
|
||||
@ -74,7 +74,7 @@ func ParsePass(Info *HostInfo) error {
|
||||
}
|
||||
}
|
||||
Passwords = pwdList
|
||||
LogInfo(fmt.Sprintf("加载密码: %d 个", len(pwdList)))
|
||||
LogInfo(GetText("load_passwords", len(pwdList)))
|
||||
}
|
||||
|
||||
// 从文件加载密码列表
|
||||
@ -89,7 +89,7 @@ func ParsePass(Info *HostInfo) error {
|
||||
}
|
||||
}
|
||||
Passwords = pwdList
|
||||
LogInfo(fmt.Sprintf("从文件加载密码: %d 个", len(passes)))
|
||||
LogInfo(GetText("load_passwords_from_file", len(passes)))
|
||||
}
|
||||
|
||||
// 处理哈希文件
|
||||
@ -108,10 +108,10 @@ func ParsePass(Info *HostInfo) error {
|
||||
HashValues = append(HashValues, line)
|
||||
validCount++
|
||||
} else {
|
||||
LogError(fmt.Sprintf("无效的哈希值: %s (长度!=32)", line))
|
||||
LogError(GetText("invalid_hash", line))
|
||||
}
|
||||
}
|
||||
LogInfo(fmt.Sprintf("加载有效哈希值: %d 个", validCount))
|
||||
LogInfo(GetText("load_valid_hashes", validCount))
|
||||
}
|
||||
|
||||
// 处理直接指定的URL列表
|
||||
@ -126,7 +126,7 @@ func ParsePass(Info *HostInfo) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
LogInfo(fmt.Sprintf("加载URL: %d 个", len(URLs)))
|
||||
LogInfo(GetText("load_urls", len(URLs)))
|
||||
}
|
||||
|
||||
// 从文件加载URL列表
|
||||
@ -145,7 +145,7 @@ func ParsePass(Info *HostInfo) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
LogInfo(fmt.Sprintf("从文件加载URL: %d 个", len(urls)))
|
||||
LogInfo(GetText("load_urls_from_file", len(urls)))
|
||||
}
|
||||
|
||||
// 从文件加载主机列表
|
||||
@ -168,7 +168,7 @@ func ParsePass(Info *HostInfo) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
LogInfo(fmt.Sprintf("从文件加载主机: %d 个", len(hosts)))
|
||||
LogInfo(GetText("load_hosts_from_file", len(hosts)))
|
||||
}
|
||||
|
||||
// 从文件加载端口列表
|
||||
@ -186,7 +186,7 @@ func ParsePass(Info *HostInfo) error {
|
||||
}
|
||||
}
|
||||
Ports = newport.String()
|
||||
LogInfo("从文件加载端口配置")
|
||||
LogInfo(GetText("load_ports_from_file"))
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -197,7 +197,7 @@ func Readfile(filename string) ([]string, error) {
|
||||
// 打开文件
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
LogError(fmt.Sprintf("打开文件失败 %s: %v", filename, err))
|
||||
LogError(GetText("open_file_failed", filename, err))
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
@ -218,11 +218,11 @@ func Readfile(filename string) ([]string, error) {
|
||||
|
||||
// 检查扫描过程中是否有错误
|
||||
if err := scanner.Err(); err != nil {
|
||||
LogError(fmt.Sprintf("读取文件错误 %s: %v", filename, err))
|
||||
LogError(GetText("read_file_failed", filename, err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
LogInfo(fmt.Sprintf("读取文件成功 %s: %d 行", filename, lineCount))
|
||||
LogInfo(GetText("read_file_success", filename, lineCount))
|
||||
return content, nil
|
||||
}
|
||||
|
||||
@ -243,22 +243,17 @@ func ParseInput(Info *HostInfo) error {
|
||||
if modes == 0 {
|
||||
// 无参数时显示帮助
|
||||
flag.Usage()
|
||||
return fmt.Errorf("请指定扫描参数")
|
||||
return fmt.Errorf(GetText("specify_scan_params"))
|
||||
} else if modes > 1 {
|
||||
return fmt.Errorf("参数 -h、-u、-local 不能同时使用")
|
||||
return fmt.Errorf(GetText("params_conflict"))
|
||||
}
|
||||
|
||||
// 处理爆破线程配置
|
||||
if BruteThreads <= 0 {
|
||||
BruteThreads = 1
|
||||
LogInfo(fmt.Sprintf("暴力破解线程数: %d", BruteThreads))
|
||||
LogInfo(GetText("brute_threads", BruteThreads))
|
||||
}
|
||||
|
||||
//if DisableSave {
|
||||
// IsSave = false
|
||||
// LogInfo("已启用临时保存模式")
|
||||
//}
|
||||
|
||||
// 处理端口配置
|
||||
if Ports == MainPorts {
|
||||
Ports += "," + WebPorts
|
||||
@ -270,7 +265,7 @@ func ParseInput(Info *HostInfo) error {
|
||||
} else {
|
||||
Ports += "," + AddPorts
|
||||
}
|
||||
LogInfo(fmt.Sprintf("额外端口: %s", AddPorts))
|
||||
LogInfo(GetText("extra_ports", AddPorts))
|
||||
}
|
||||
|
||||
// 处理用户名配置
|
||||
@ -280,7 +275,7 @@ func ParseInput(Info *HostInfo) error {
|
||||
Userdict[dict] = append(Userdict[dict], users...)
|
||||
Userdict[dict] = RemoveDuplicate(Userdict[dict])
|
||||
}
|
||||
LogInfo(fmt.Sprintf("额外用户名: %s", AddUsers))
|
||||
LogInfo(GetText("extra_usernames", AddUsers))
|
||||
}
|
||||
|
||||
// 处理密码配置
|
||||
@ -288,7 +283,7 @@ func ParseInput(Info *HostInfo) error {
|
||||
passes := strings.Split(AddPasswords, ",")
|
||||
Passwords = append(Passwords, passes...)
|
||||
Passwords = RemoveDuplicate(Passwords)
|
||||
LogInfo(fmt.Sprintf("额外密码: %s", AddPasswords))
|
||||
LogInfo(GetText("extra_passwords", AddPasswords))
|
||||
}
|
||||
|
||||
// 处理Socks5代理配置
|
||||
@ -303,10 +298,10 @@ func ParseInput(Info *HostInfo) error {
|
||||
|
||||
_, err := url.Parse(Socks5Proxy)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Socks5代理格式错误: %v", err)
|
||||
return fmt.Errorf(GetText("socks5_proxy_error", err))
|
||||
}
|
||||
DisablePing = true
|
||||
LogInfo(fmt.Sprintf("Socks5代理: %s", Socks5Proxy))
|
||||
LogInfo(GetText("socks5_proxy", Socks5Proxy))
|
||||
}
|
||||
|
||||
// 处理HTTP代理配置
|
||||
@ -323,20 +318,20 @@ func ParseInput(Info *HostInfo) error {
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(HttpProxy, "socks") && !strings.HasPrefix(HttpProxy, "http") {
|
||||
return fmt.Errorf("不支持的代理类型")
|
||||
return fmt.Errorf(GetText("unsupported_proxy"))
|
||||
}
|
||||
|
||||
_, err := url.Parse(HttpProxy)
|
||||
if err != nil {
|
||||
return fmt.Errorf("代理格式错误: %v", err)
|
||||
return fmt.Errorf(GetText("proxy_format_error", err))
|
||||
}
|
||||
LogInfo(fmt.Sprintf("HTTP代理: %s", HttpProxy))
|
||||
LogInfo(GetText("http_proxy", HttpProxy))
|
||||
}
|
||||
|
||||
// 处理Hash配置
|
||||
if HashValue != "" {
|
||||
if len(HashValue) != 32 {
|
||||
return fmt.Errorf("Hash长度必须为32位")
|
||||
return fmt.Errorf(GetText("hash_length_error"))
|
||||
}
|
||||
HashValues = append(HashValues, HashValue)
|
||||
}
|
||||
@ -346,7 +341,7 @@ func ParseInput(Info *HostInfo) error {
|
||||
for _, hash := range HashValues {
|
||||
hashByte, err := hex.DecodeString(hash)
|
||||
if err != nil {
|
||||
LogError(fmt.Sprintf("Hash解码失败: %s", hash))
|
||||
LogError(GetText("hash_decode_failed", hash))
|
||||
continue
|
||||
}
|
||||
HashBytes = append(HashBytes, hashByte)
|
||||
|
@ -13,15 +13,8 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ParseIPErr = errors.New("主机解析错误\n" +
|
||||
"支持的格式: \n" +
|
||||
"192.168.1.1 (单个IP)\n" +
|
||||
"192.168.1.1/8 (8位子网)\n" +
|
||||
"192.168.1.1/16 (16位子网)\n" +
|
||||
"192.168.1.1/24 (24位子网)\n" +
|
||||
"192.168.1.1,192.168.1.2 (IP列表)\n" +
|
||||
"192.168.1.1-192.168.255.255 (IP范围)\n" +
|
||||
"192.168.1.1-255 (最后一位简写范围)")
|
||||
var ParseIPErr = errors.New(GetText("parse_ip_error"))
|
||||
|
||||
|
||||
// ParseIP 解析IP地址配置
|
||||
func ParseIP(host string, filename string, nohosts ...string) (hosts []string, err error) {
|
||||
@ -32,7 +25,7 @@ func ParseIP(host string, filename string, nohosts ...string) (hosts []string, e
|
||||
host = hostport[0]
|
||||
hosts = ParseIPs(host)
|
||||
Ports = hostport[1]
|
||||
LogInfo(fmt.Sprintf("已解析主机端口组合,端口设置为: %s", Ports))
|
||||
LogInfo(GetText("host_port_parsed", Ports))
|
||||
}
|
||||
} else {
|
||||
// 解析主机地址
|
||||
@ -42,10 +35,10 @@ func ParseIP(host string, filename string, nohosts ...string) (hosts []string, e
|
||||
if filename != "" {
|
||||
fileHosts, err := Readipfile(filename)
|
||||
if err != nil {
|
||||
LogError(fmt.Sprintf("读取主机文件失败: %v", err))
|
||||
LogError(GetText("read_host_file_failed", err))
|
||||
} else {
|
||||
hosts = append(hosts, fileHosts...)
|
||||
LogInfo(fmt.Sprintf("从文件加载额外主机: %d 个", len(fileHosts)))
|
||||
LogInfo(GetText("extra_hosts_loaded", len(fileHosts)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -72,13 +65,13 @@ func ParseIP(host string, filename string, nohosts ...string) (hosts []string, e
|
||||
}
|
||||
hosts = newHosts
|
||||
sort.Strings(hosts)
|
||||
LogInfo(fmt.Sprintf("已排除指定主机: %d 个", len(excludeHosts)))
|
||||
LogInfo(GetText("hosts_excluded", len(excludeHosts)))
|
||||
}
|
||||
}
|
||||
|
||||
// 去重处理
|
||||
hosts = RemoveDuplicate(hosts)
|
||||
LogInfo(fmt.Sprintf("最终有效主机数量: %d", len(hosts)))
|
||||
LogInfo(GetText("final_valid_hosts", len(hosts)))
|
||||
|
||||
// 检查解析结果
|
||||
if len(hosts) == 0 && len(HostPort) == 0 && (host != "" || filename != "") {
|
||||
@ -123,7 +116,7 @@ func parseIP(ip string) []string {
|
||||
default:
|
||||
testIP := net.ParseIP(ip)
|
||||
if testIP == nil {
|
||||
LogError(fmt.Sprintf("无效的IP格式: %s", ip))
|
||||
LogError(GetText("invalid_ip_format", ip))
|
||||
return nil
|
||||
}
|
||||
return []string{ip}
|
||||
@ -134,13 +127,13 @@ func parseIP(ip string) []string {
|
||||
func parseIP2(host string) []string {
|
||||
_, ipNet, err := net.ParseCIDR(host)
|
||||
if err != nil {
|
||||
LogError(fmt.Sprintf("CIDR格式解析失败: %s, %v", host, err))
|
||||
LogError(GetText("cidr_parse_failed", host, err))
|
||||
return nil
|
||||
}
|
||||
|
||||
ipRange := IPRange(ipNet)
|
||||
hosts := parseIP1(ipRange)
|
||||
LogInfo(fmt.Sprintf("解析CIDR %s -> IP范围 %s", host, ipRange))
|
||||
LogInfo(GetText("parse_cidr_to_range", host, ipRange))
|
||||
return hosts
|
||||
}
|
||||
|
||||
@ -154,7 +147,7 @@ func parseIP1(ip string) []string {
|
||||
if len(ipRange[1]) < 4 {
|
||||
endNum, err := strconv.Atoi(ipRange[1])
|
||||
if testIP == nil || endNum > 255 || err != nil {
|
||||
LogError(fmt.Sprintf("IP范围格式错误: %s", ip))
|
||||
LogError(GetText("ip_range_format_error", ip))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -164,7 +157,7 @@ func parseIP1(ip string) []string {
|
||||
prefixIP := strings.Join(splitIP[0:3], ".")
|
||||
|
||||
if startNum > endNum || err1 != nil || err2 != nil {
|
||||
LogError(fmt.Sprintf("IP范围无效: %d-%d", startNum, endNum))
|
||||
LogError(GetText("invalid_ip_range", startNum, endNum))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -172,14 +165,14 @@ func parseIP1(ip string) []string {
|
||||
allIP = append(allIP, prefixIP+"."+strconv.Itoa(i))
|
||||
}
|
||||
|
||||
LogInfo(fmt.Sprintf("生成IP范围: %s.%d - %s.%d", prefixIP, startNum, prefixIP, endNum))
|
||||
LogInfo(GetText("generate_ip_range", prefixIP, startNum, prefixIP, endNum))
|
||||
} else {
|
||||
// 处理完整IP范围格式
|
||||
splitIP1 := strings.Split(ipRange[0], ".")
|
||||
splitIP2 := strings.Split(ipRange[1], ".")
|
||||
|
||||
if len(splitIP1) != 4 || len(splitIP2) != 4 {
|
||||
LogError(fmt.Sprintf("IP格式错误: %s", ip))
|
||||
LogError(GetText("ip_format_error", ip))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -188,7 +181,7 @@ func parseIP1(ip string) []string {
|
||||
ip1, err1 := strconv.Atoi(splitIP1[i])
|
||||
ip2, err2 := strconv.Atoi(splitIP2[i])
|
||||
if ip1 > ip2 || err1 != nil || err2 != nil {
|
||||
LogError(fmt.Sprintf("IP范围无效: %s-%s", ipRange[0], ipRange[1]))
|
||||
LogError(GetText("invalid_ip_range", ipRange[0], ipRange[1]))
|
||||
return nil
|
||||
}
|
||||
start[i], end[i] = ip1, ip2
|
||||
@ -205,7 +198,7 @@ func parseIP1(ip string) []string {
|
||||
allIP = append(allIP, ip)
|
||||
}
|
||||
|
||||
LogInfo(fmt.Sprintf("生成IP范围: %s - %s", ipRange[0], ipRange[1]))
|
||||
LogInfo(GetText("generate_ip_range", ipRange[0], ipRange[1]))
|
||||
}
|
||||
|
||||
return allIP
|
||||
@ -225,7 +218,7 @@ func IPRange(c *net.IPNet) string {
|
||||
end := bcst.String()
|
||||
|
||||
result := fmt.Sprintf("%s-%s", start, end)
|
||||
LogInfo(fmt.Sprintf("CIDR范围: %s", result))
|
||||
LogInfo(GetText("cidr_range", result))
|
||||
return result
|
||||
}
|
||||
|
||||
@ -233,7 +226,7 @@ func IPRange(c *net.IPNet) string {
|
||||
func Readipfile(filename string) ([]string, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
LogError(fmt.Sprintf("打开文件失败 %s: %v", filename, err))
|
||||
LogError(GetText("open_file_failed", filename, err))
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
@ -253,7 +246,7 @@ func Readipfile(filename string) ([]string, error) {
|
||||
port := strings.Split(text[1], " ")[0]
|
||||
num, err := strconv.Atoi(port)
|
||||
if err != nil || num < 1 || num > 65535 {
|
||||
LogError(fmt.Sprintf("忽略无效端口: %s", line))
|
||||
LogError(GetText("invalid_port", line))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -261,20 +254,20 @@ func Readipfile(filename string) ([]string, error) {
|
||||
for _, host := range hosts {
|
||||
HostPort = append(HostPort, fmt.Sprintf("%s:%s", host, port))
|
||||
}
|
||||
LogInfo(fmt.Sprintf("解析IP端口组合: %s", line))
|
||||
LogInfo(GetText("parse_ip_port", line))
|
||||
} else {
|
||||
hosts := ParseIPs(line)
|
||||
content = append(content, hosts...)
|
||||
LogInfo(fmt.Sprintf("解析IP地址: %s", line))
|
||||
LogInfo(GetText("parse_ip_address", line))
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
LogError(fmt.Sprintf("读取文件错误: %v", err))
|
||||
LogError(GetText("read_file_error", err))
|
||||
return content, err
|
||||
}
|
||||
|
||||
LogInfo(fmt.Sprintf("从文件解析完成: %d 个IP地址", len(content)))
|
||||
LogInfo(GetText("file_parse_complete", len(content)))
|
||||
return content, nil
|
||||
}
|
||||
|
||||
@ -300,7 +293,7 @@ func parseIP8(ip string) []string {
|
||||
testIP := net.ParseIP(realIP)
|
||||
|
||||
if testIP == nil {
|
||||
LogError(fmt.Sprintf("无效的IP格式: %s", realIP))
|
||||
LogError(GetText("invalid_ip_format", realIP))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -308,7 +301,7 @@ func parseIP8(ip string) []string {
|
||||
ipRange := strings.Split(ip, ".")[0]
|
||||
var allIP []string
|
||||
|
||||
LogInfo(fmt.Sprintf("解析网段: %s.0.0.0/8", ipRange))
|
||||
LogInfo(GetText("parse_subnet", ipRange))
|
||||
|
||||
// 遍历所有可能的第二、三段
|
||||
for a := 0; a <= 255; a++ {
|
||||
@ -329,7 +322,7 @@ func parseIP8(ip string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo(fmt.Sprintf("生成采样IP: %d 个", len(allIP)))
|
||||
LogInfo(GetText("sample_ip_generated", len(allIP)))
|
||||
return allIP
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
package Common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// ParsePort 解析端口配置字符串为端口号列表
|
||||
@ -42,7 +41,7 @@ func ParsePort(ports string) []int {
|
||||
if strings.Contains(port, "-") {
|
||||
ranges := strings.Split(port, "-")
|
||||
if len(ranges) < 2 {
|
||||
LogError(fmt.Sprintf("端口范围格式错误: %s", port))
|
||||
LogError(GetText("port_range_format_error", port))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -63,7 +62,7 @@ func ParsePort(ports string) []int {
|
||||
end, _ := strconv.Atoi(upper)
|
||||
for i := start; i <= end; i++ {
|
||||
if i > 65535 || i < 1 {
|
||||
LogError(fmt.Sprintf("忽略无效端口: %d", i))
|
||||
LogError(GetText("ignore_invalid_port", i))
|
||||
continue
|
||||
}
|
||||
scanPorts = append(scanPorts, i)
|
||||
@ -74,7 +73,7 @@ func ParsePort(ports string) []int {
|
||||
scanPorts = removeDuplicate(scanPorts)
|
||||
sort.Ints(scanPorts)
|
||||
|
||||
LogInfo(fmt.Sprintf("有效端口数量: %d", len(scanPorts)))
|
||||
LogInfo(GetText("valid_port_count", len(scanPorts)))
|
||||
return scanPorts
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package Common
|
||||
|
||||
import "fmt"
|
||||
|
||||
// 扫描模式常量 - 使用大写开头表示这是一个预设的扫描模式
|
||||
const (
|
||||
ModeAll = "All" // 全量扫描
|
||||
@ -48,7 +46,7 @@ var PluginGroups = map[string][]string{
|
||||
|
||||
// ParseScanMode 解析扫描模式
|
||||
func ParseScanMode(mode string) {
|
||||
LogInfo(fmt.Sprintf("解析扫描模式: %s", mode))
|
||||
LogInfo(GetText("parse_scan_mode", mode))
|
||||
|
||||
// 检查是否是预设模式
|
||||
presetModes := []string{
|
||||
@ -60,9 +58,9 @@ func ParseScanMode(mode string) {
|
||||
if mode == presetMode {
|
||||
ScanMode = mode
|
||||
if plugins := GetPluginsForMode(mode); plugins != nil {
|
||||
LogInfo(fmt.Sprintf("使用预设模式: %s, 包含插件: %v", mode, plugins))
|
||||
LogInfo(GetText("using_preset_mode_plugins", mode, plugins))
|
||||
} else {
|
||||
LogInfo(fmt.Sprintf("使用预设模式: %s", mode))
|
||||
LogInfo(GetText("using_preset_mode", mode))
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -71,14 +69,14 @@ func ParseScanMode(mode string) {
|
||||
// 检查是否是有效的插件名
|
||||
if _, exists := PluginManager[mode]; exists {
|
||||
ScanMode = mode
|
||||
LogInfo(fmt.Sprintf("使用单个插件: %s", mode))
|
||||
LogInfo(GetText("using_single_plugin", mode))
|
||||
return
|
||||
}
|
||||
|
||||
// 默认使用All模式
|
||||
ScanMode = ModeAll
|
||||
LogInfo(fmt.Sprintf("未识别的模式,使用默认模式: %s", ModeAll))
|
||||
LogInfo(fmt.Sprintf("包含插件: %v", PluginGroups[ModeAll]))
|
||||
LogInfo(GetText("using_default_mode", ModeAll))
|
||||
LogInfo(GetText("included_plugins", PluginGroups[ModeAll]))
|
||||
}
|
||||
|
||||
// GetPluginsForMode 获取指定模式下的插件列表
|
||||
|
@ -22,7 +22,7 @@ func WrapperTCP(network, address string, forward *net.Dialer) (net.Conn, error)
|
||||
if Socks5Proxy == "" {
|
||||
conn, err := forward.Dial(network, address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("建立TCP连接失败: %v", err)
|
||||
return nil, fmt.Errorf(GetText("tcp_conn_failed"), err)
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
@ -30,12 +30,12 @@ func WrapperTCP(network, address string, forward *net.Dialer) (net.Conn, error)
|
||||
// Socks5代理模式
|
||||
dialer, err := Socks5Dialer(forward)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建Socks5代理失败: %v", err)
|
||||
return nil, fmt.Errorf(GetText("socks5_create_failed"), err)
|
||||
}
|
||||
|
||||
conn, err := dialer.Dial(network, address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("通过Socks5建立连接失败: %v", err)
|
||||
return nil, fmt.Errorf(GetText("socks5_conn_failed"), err)
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
@ -46,12 +46,12 @@ func Socks5Dialer(forward *net.Dialer) (proxy.Dialer, error) {
|
||||
// 解析代理URL
|
||||
u, err := url.Parse(Socks5Proxy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("解析Socks5代理地址失败: %v", err)
|
||||
return nil, fmt.Errorf(GetText("socks5_parse_failed"), err)
|
||||
}
|
||||
|
||||
// 验证代理类型
|
||||
if strings.ToLower(u.Scheme) != "socks5" {
|
||||
return nil, errors.New("仅支持socks5代理")
|
||||
return nil, errors.New(GetText("socks5_only"))
|
||||
}
|
||||
|
||||
address := u.Host
|
||||
@ -71,7 +71,7 @@ func Socks5Dialer(forward *net.Dialer) (proxy.Dialer, error) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建Socks5代理失败: %v", err)
|
||||
return nil, fmt.Errorf(GetText("socks5_create_failed"), err)
|
||||
}
|
||||
|
||||
return dialer, nil
|
||||
|
1126
Common/i18n.go
Normal file
1126
Common/i18n.go
Normal file
File diff suppressed because it is too large
Load Diff
16
Core/ICMP.go
16
Core/ICMP.go
@ -80,7 +80,7 @@ func handleAliveHosts(chanHosts chan string, hostslist []string, isPing bool) {
|
||||
|
||||
// 保留原有的控制台输出
|
||||
if !Common.Silent {
|
||||
Common.LogSuccess(fmt.Sprintf("目标 %-15s 存活 (%s)", ip, protocol))
|
||||
Common.LogSuccess(Common.GetText("target_alive", ip, protocol))
|
||||
}
|
||||
}
|
||||
livewg.Done()
|
||||
@ -96,8 +96,8 @@ func probeWithICMP(hostslist []string, chanHosts chan string) {
|
||||
return
|
||||
}
|
||||
|
||||
Common.LogError(fmt.Sprintf("ICMP监听失败: %v", err))
|
||||
Common.LogInfo("正在尝试无监听ICMP探测...")
|
||||
Common.LogError(Common.GetText("icmp_listen_failed", err))
|
||||
Common.LogInfo(Common.GetText("trying_no_listen_icmp"))
|
||||
|
||||
// 尝试无监听ICMP探测
|
||||
conn2, err := net.DialTimeout("ip4:icmp", "127.0.0.1", 3*time.Second)
|
||||
@ -107,9 +107,9 @@ func probeWithICMP(hostslist []string, chanHosts chan string) {
|
||||
return
|
||||
}
|
||||
|
||||
Common.LogError(fmt.Sprintf("ICMP连接失败: %v", err))
|
||||
Common.LogInfo("当前用户权限不足,无法发送ICMP包")
|
||||
Common.LogInfo("切换为PING方式探测...")
|
||||
Common.LogError(Common.GetText("icmp_connect_failed", err))
|
||||
Common.LogInfo(Common.GetText("insufficient_privileges"))
|
||||
Common.LogInfo(Common.GetText("switching_to_ping"))
|
||||
|
||||
// 降级使用ping探测
|
||||
RunPing(hostslist, chanHosts)
|
||||
@ -121,7 +121,7 @@ func printAliveStats(hostslist []string) {
|
||||
if len(hostslist) > 1000 {
|
||||
arrTop, arrLen := ArrayCountValueTop(AliveHosts, Common.LiveTop, true)
|
||||
for i := 0; i < len(arrTop); i++ {
|
||||
Common.LogSuccess(fmt.Sprintf("%s.0.0/16 存活主机数: %d", arrTop[i], arrLen[i]))
|
||||
Common.LogSuccess(Common.GetText("subnet_16_alive", arrTop[i], arrLen[i]))
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ func printAliveStats(hostslist []string) {
|
||||
if len(hostslist) > 256 {
|
||||
arrTop, arrLen := ArrayCountValueTop(AliveHosts, Common.LiveTop, false)
|
||||
for i := 0; i < len(arrTop); i++ {
|
||||
Common.LogSuccess(fmt.Sprintf("%s.0/24 存活主机数: %d", arrTop[i], arrLen[i]))
|
||||
Common.LogSuccess(Common.GetText("subnet_24_alive", arrTop[i], arrLen[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user