mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-07-13 21:02:44 +08:00
简化输出格式
This commit is contained in:
parent
875d128e53
commit
805af82a1e
@ -5,7 +5,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version = "2.0.0"
|
var version = "2.0.1"
|
||||||
var Userdict = map[string][]string{
|
var Userdict = map[string][]string{
|
||||||
"ftp": {"ftp", "admin", "www", "web", "root", "db", "wwwroot", "data"},
|
"ftp": {"ftp", "admin", "www", "web", "root", "db", "wwwroot", "data"},
|
||||||
"mysql": {"root", "mysql"},
|
"mysql": {"root", "mysql"},
|
||||||
|
@ -94,7 +94,6 @@ func Flag(Info *HostInfo) {
|
|||||||
flag.Int64Var(&WebTimeout, "wt", 5, GetText("flag_web_timeout"))
|
flag.Int64Var(&WebTimeout, "wt", 5, GetText("flag_web_timeout"))
|
||||||
flag.StringVar(&HttpProxy, "proxy", "", GetText("flag_http_proxy"))
|
flag.StringVar(&HttpProxy, "proxy", "", GetText("flag_http_proxy"))
|
||||||
flag.StringVar(&Socks5Proxy, "socks5", "", GetText("flag_socks5_proxy"))
|
flag.StringVar(&Socks5Proxy, "socks5", "", GetText("flag_socks5_proxy"))
|
||||||
|
|
||||||
// 本地扫描配置
|
// 本地扫描配置
|
||||||
flag.BoolVar(&LocalMode, "local", false, GetText("flag_local_mode"))
|
flag.BoolVar(&LocalMode, "local", false, GetText("flag_local_mode"))
|
||||||
|
|
||||||
@ -128,7 +127,7 @@ func Flag(Info *HostInfo) {
|
|||||||
flag.BoolVar(&Silent, "silent", false, GetText("flag_silent_mode"))
|
flag.BoolVar(&Silent, "silent", false, GetText("flag_silent_mode"))
|
||||||
flag.BoolVar(&NoColor, "nocolor", false, GetText("flag_no_color"))
|
flag.BoolVar(&NoColor, "nocolor", false, GetText("flag_no_color"))
|
||||||
flag.BoolVar(&JsonFormat, "json", false, GetText("flag_json_format"))
|
flag.BoolVar(&JsonFormat, "json", false, GetText("flag_json_format"))
|
||||||
flag.StringVar(&LogLevel, "log", LogLevelSuccess, GetText("flag_log_level"))
|
flag.StringVar(&LogLevel, "log", LogLevelBase, GetText("flag_log_level"))
|
||||||
flag.BoolVar(&ShowProgress, "pg", false, GetText("flag_show_progress"))
|
flag.BoolVar(&ShowProgress, "pg", false, GetText("flag_show_progress"))
|
||||||
|
|
||||||
flag.StringVar(&Language, "lang", "zh", GetText("flag_language"))
|
flag.StringVar(&Language, "lang", "zh", GetText("flag_language"))
|
||||||
|
139
Common/Log.go
139
Common/Log.go
@ -44,6 +44,7 @@ type LogEntry struct {
|
|||||||
const (
|
const (
|
||||||
LogLevelAll = "ALL" // 显示所有级别日志
|
LogLevelAll = "ALL" // 显示所有级别日志
|
||||||
LogLevelError = "ERROR" // 仅显示错误日志
|
LogLevelError = "ERROR" // 仅显示错误日志
|
||||||
|
LogLevelBase = "BASE" // 仅显示信息日志
|
||||||
LogLevelInfo = "INFO" // 仅显示信息日志
|
LogLevelInfo = "INFO" // 仅显示信息日志
|
||||||
LogLevelSuccess = "SUCCESS" // 仅显示成功日志
|
LogLevelSuccess = "SUCCESS" // 仅显示成功日志
|
||||||
LogLevelDebug = "DEBUG" // 仅显示调试日志
|
LogLevelDebug = "DEBUG" // 仅显示调试日志
|
||||||
@ -51,10 +52,11 @@ const (
|
|||||||
|
|
||||||
// 日志级别对应的显示颜色映射
|
// 日志级别对应的显示颜色映射
|
||||||
var logColors = map[string]color.Attribute{
|
var logColors = map[string]color.Attribute{
|
||||||
LogLevelError: color.FgRed, // 错误日志显示红色
|
LogLevelError: color.FgBlue, // 错误日志显示蓝色
|
||||||
LogLevelInfo: color.FgYellow, // 信息日志显示黄色
|
LogLevelBase: color.FgYellow, // 信息日志显示黄色
|
||||||
LogLevelSuccess: color.FgGreen, // 成功日志显示绿色
|
LogLevelInfo: color.FgGreen, // 信息日志显示绿色
|
||||||
LogLevelDebug: color.FgBlue, // 调试日志显示蓝色
|
LogLevelSuccess: color.FgRed, // 成功日志显示红色
|
||||||
|
LogLevelDebug: color.FgWhite, // 调试日志显示白色
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitLogger 初始化日志系统
|
// InitLogger 初始化日志系统
|
||||||
@ -63,42 +65,50 @@ func InitLogger() {
|
|||||||
log.SetOutput(io.Discard)
|
log.SetOutput(io.Discard)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var StartTime = time.Now()
|
||||||
|
|
||||||
// formatLogMessage 格式化日志消息为标准格式
|
// formatLogMessage 格式化日志消息为标准格式
|
||||||
// 返回格式:[时间] [级别] 内容
|
// 返回格式:[时间] [级别] 内容
|
||||||
func formatLogMessage(entry *LogEntry) string {
|
func formatLogMessage(entry *LogEntry) string {
|
||||||
timeStr := entry.Time.Format("2006-01-02 15:04:05")
|
elapsed := time.Since(StartTime)
|
||||||
return fmt.Sprintf("[%s] [%s] %s", timeStr, entry.Level, entry.Content)
|
var timeStr string
|
||||||
|
|
||||||
|
// 根据时间长短选择合适的单位
|
||||||
|
switch {
|
||||||
|
case elapsed < time.Second:
|
||||||
|
// 毫秒显示,不需要小数
|
||||||
|
timeStr = fmt.Sprintf("%dms", elapsed.Milliseconds())
|
||||||
|
case elapsed < time.Minute:
|
||||||
|
// 秒显示,保留一位小数
|
||||||
|
timeStr = fmt.Sprintf("%.1fs", elapsed.Seconds())
|
||||||
|
case elapsed < time.Hour:
|
||||||
|
// 分钟和秒显示
|
||||||
|
minutes := int(elapsed.Minutes())
|
||||||
|
seconds := int(elapsed.Seconds()) % 60
|
||||||
|
timeStr = fmt.Sprintf("%dm%ds", minutes, seconds)
|
||||||
|
default:
|
||||||
|
// 小时、分钟和秒显示
|
||||||
|
hours := int(elapsed.Hours())
|
||||||
|
minutes := int(elapsed.Minutes()) % 60
|
||||||
|
seconds := int(elapsed.Seconds()) % 60
|
||||||
|
timeStr = fmt.Sprintf("%dh%dm%ds", hours, minutes, seconds)
|
||||||
|
}
|
||||||
|
str := " "
|
||||||
|
switch entry.Level {
|
||||||
|
case LogLevelSuccess:
|
||||||
|
str = "[+]"
|
||||||
|
case LogLevelInfo:
|
||||||
|
str = "[*]"
|
||||||
|
case LogLevelError:
|
||||||
|
str = "[-]"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("[%s] %s %s", timeStr, str, entry.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// printLog 根据日志级别打印日志
|
// printLog 根据日志级别打印日志
|
||||||
func printLog(entry *LogEntry) {
|
func printLog(entry *LogEntry) {
|
||||||
// 根据当前设置的日志级别过滤日志
|
if LogLevel != "debug" && entry.Level == LogLevelDebug {
|
||||||
shouldPrint := false
|
|
||||||
switch LogLevel {
|
|
||||||
case LogLevelDebug:
|
|
||||||
// DEBUG级别显示所有日志
|
|
||||||
shouldPrint = true
|
|
||||||
case LogLevelError:
|
|
||||||
// ERROR级别显示 ERROR、SUCCESS、INFO
|
|
||||||
shouldPrint = entry.Level == LogLevelError ||
|
|
||||||
entry.Level == LogLevelSuccess ||
|
|
||||||
entry.Level == LogLevelInfo
|
|
||||||
case LogLevelSuccess:
|
|
||||||
// SUCCESS级别显示 SUCCESS、INFO
|
|
||||||
shouldPrint = entry.Level == LogLevelSuccess ||
|
|
||||||
entry.Level == LogLevelInfo
|
|
||||||
case LogLevelInfo:
|
|
||||||
// INFO级别只显示 INFO
|
|
||||||
shouldPrint = entry.Level == LogLevelInfo
|
|
||||||
case LogLevelAll:
|
|
||||||
// ALL显示所有日志
|
|
||||||
shouldPrint = true
|
|
||||||
default:
|
|
||||||
// 默认只显示 INFO
|
|
||||||
shouldPrint = entry.Level == LogLevelInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
if !shouldPrint {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,27 +149,6 @@ func clearAndWaitProgress() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogError 记录错误日志,自动包含文件名和行号信息
|
|
||||||
func LogError(errMsg string) {
|
|
||||||
// 获取调用者的文件名和行号
|
|
||||||
_, file, line, ok := runtime.Caller(1)
|
|
||||||
if !ok {
|
|
||||||
file = "unknown"
|
|
||||||
line = 0
|
|
||||||
}
|
|
||||||
file = filepath.Base(file)
|
|
||||||
|
|
||||||
errorMsg := fmt.Sprintf("%s:%d - %s", file, line, errMsg)
|
|
||||||
|
|
||||||
entry := &LogEntry{
|
|
||||||
Level: LogLevelError,
|
|
||||||
Time: time.Now(),
|
|
||||||
Content: errorMsg,
|
|
||||||
}
|
|
||||||
|
|
||||||
handleLog(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleLog 统一处理日志的输出
|
// handleLog 统一处理日志的输出
|
||||||
func handleLog(entry *LogEntry) {
|
func handleLog(entry *LogEntry) {
|
||||||
if ProgressBar != nil {
|
if ProgressBar != nil {
|
||||||
@ -173,6 +162,24 @@ func handleLog(entry *LogEntry) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogDebug 记录调试日志
|
||||||
|
func LogDebug(msg string) {
|
||||||
|
handleLog(&LogEntry{
|
||||||
|
Level: LogLevelDebug,
|
||||||
|
Time: time.Now(),
|
||||||
|
Content: msg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogInfo 记录进度信息
|
||||||
|
func LogBase(msg string) {
|
||||||
|
handleLog(&LogEntry{
|
||||||
|
Level: LogLevelBase,
|
||||||
|
Time: time.Now(),
|
||||||
|
Content: msg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// LogInfo 记录信息日志
|
// LogInfo 记录信息日志
|
||||||
func LogInfo(msg string) {
|
func LogInfo(msg string) {
|
||||||
handleLog(&LogEntry{
|
handleLog(&LogEntry{
|
||||||
@ -198,13 +205,25 @@ func LogSuccess(result string) {
|
|||||||
status.mu.Unlock()
|
status.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogDebug 记录调试日志
|
// LogError 记录错误日志,自动包含文件名和行号信息
|
||||||
func LogDebug(msg string) {
|
func LogError(errMsg string) {
|
||||||
handleLog(&LogEntry{
|
// 获取调用者的文件名和行号
|
||||||
Level: LogLevelDebug,
|
_, file, line, ok := runtime.Caller(1)
|
||||||
|
if !ok {
|
||||||
|
file = "unknown"
|
||||||
|
line = 0
|
||||||
|
}
|
||||||
|
file = filepath.Base(file)
|
||||||
|
|
||||||
|
errorMsg := fmt.Sprintf("%s:%d - %s", file, line, errMsg)
|
||||||
|
|
||||||
|
entry := &LogEntry{
|
||||||
|
Level: LogLevelError,
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
Content: msg,
|
Content: errorMsg,
|
||||||
})
|
}
|
||||||
|
|
||||||
|
handleLog(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckErrs 检查是否为需要重试的错误
|
// CheckErrs 检查是否为需要重试的错误
|
||||||
|
@ -31,7 +31,7 @@ func ParseUser() error {
|
|||||||
// 处理直接指定的用户名列表
|
// 处理直接指定的用户名列表
|
||||||
if Username != "" {
|
if Username != "" {
|
||||||
usernames = strings.Split(Username, ",")
|
usernames = strings.Split(Username, ",")
|
||||||
LogInfo(GetText("no_username_specified", len(usernames)))
|
LogBase(GetText("no_username_specified", len(usernames)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从文件加载用户名列表
|
// 从文件加载用户名列表
|
||||||
@ -47,12 +47,12 @@ func ParseUser() error {
|
|||||||
usernames = append(usernames, user)
|
usernames = append(usernames, user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogInfo(GetText("load_usernames_from_file", len(users)))
|
LogBase(GetText("load_usernames_from_file", len(users)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去重处理
|
// 去重处理
|
||||||
usernames = RemoveDuplicate(usernames)
|
usernames = RemoveDuplicate(usernames)
|
||||||
LogInfo(GetText("total_usernames", len(usernames)))
|
LogBase(GetText("total_usernames", len(usernames)))
|
||||||
|
|
||||||
// 更新用户字典
|
// 更新用户字典
|
||||||
for name := range Userdict {
|
for name := range Userdict {
|
||||||
@ -74,7 +74,7 @@ func ParsePass(Info *HostInfo) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Passwords = pwdList
|
Passwords = pwdList
|
||||||
LogInfo(GetText("load_passwords", len(pwdList)))
|
LogBase(GetText("load_passwords", len(pwdList)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从文件加载密码列表
|
// 从文件加载密码列表
|
||||||
@ -89,7 +89,7 @@ func ParsePass(Info *HostInfo) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Passwords = pwdList
|
Passwords = pwdList
|
||||||
LogInfo(GetText("load_passwords_from_file", len(passes)))
|
LogBase(GetText("load_passwords_from_file", len(passes)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理哈希文件
|
// 处理哈希文件
|
||||||
@ -111,7 +111,7 @@ func ParsePass(Info *HostInfo) error {
|
|||||||
LogError(GetText("invalid_hash", line))
|
LogError(GetText("invalid_hash", line))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogInfo(GetText("load_valid_hashes", validCount))
|
LogBase(GetText("load_valid_hashes", validCount))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理直接指定的URL列表
|
// 处理直接指定的URL列表
|
||||||
@ -126,7 +126,7 @@ func ParsePass(Info *HostInfo) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogInfo(GetText("load_urls", len(URLs)))
|
LogBase(GetText("load_urls", len(URLs)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从文件加载URL列表
|
// 从文件加载URL列表
|
||||||
@ -145,7 +145,7 @@ func ParsePass(Info *HostInfo) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogInfo(GetText("load_urls_from_file", len(urls)))
|
LogBase(GetText("load_urls_from_file", len(urls)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从文件加载主机列表
|
// 从文件加载主机列表
|
||||||
@ -168,7 +168,7 @@ func ParsePass(Info *HostInfo) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogInfo(GetText("load_hosts_from_file", len(hosts)))
|
LogBase(GetText("load_hosts_from_file", len(hosts)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从文件加载端口列表
|
// 从文件加载端口列表
|
||||||
@ -186,7 +186,7 @@ func ParsePass(Info *HostInfo) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ports = newport.String()
|
Ports = newport.String()
|
||||||
LogInfo(GetText("load_ports_from_file"))
|
LogBase(GetText("load_ports_from_file"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -222,7 +222,7 @@ func Readfile(filename string) ([]string, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(GetText("read_file_success", filename, lineCount))
|
LogBase(GetText("read_file_success", filename, lineCount))
|
||||||
return content, nil
|
return content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ func ParseInput(Info *HostInfo) error {
|
|||||||
// 处理爆破线程配置
|
// 处理爆破线程配置
|
||||||
if BruteThreads <= 0 {
|
if BruteThreads <= 0 {
|
||||||
BruteThreads = 1
|
BruteThreads = 1
|
||||||
LogInfo(GetText("brute_threads", BruteThreads))
|
LogBase(GetText("brute_threads", BruteThreads))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理端口配置
|
// 处理端口配置
|
||||||
@ -265,7 +265,7 @@ func ParseInput(Info *HostInfo) error {
|
|||||||
} else {
|
} else {
|
||||||
Ports += "," + AddPorts
|
Ports += "," + AddPorts
|
||||||
}
|
}
|
||||||
LogInfo(GetText("extra_ports", AddPorts))
|
LogBase(GetText("extra_ports", AddPorts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理用户名配置
|
// 处理用户名配置
|
||||||
@ -275,7 +275,7 @@ func ParseInput(Info *HostInfo) error {
|
|||||||
Userdict[dict] = append(Userdict[dict], users...)
|
Userdict[dict] = append(Userdict[dict], users...)
|
||||||
Userdict[dict] = RemoveDuplicate(Userdict[dict])
|
Userdict[dict] = RemoveDuplicate(Userdict[dict])
|
||||||
}
|
}
|
||||||
LogInfo(GetText("extra_usernames", AddUsers))
|
LogBase(GetText("extra_usernames", AddUsers))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理密码配置
|
// 处理密码配置
|
||||||
@ -283,7 +283,7 @@ func ParseInput(Info *HostInfo) error {
|
|||||||
passes := strings.Split(AddPasswords, ",")
|
passes := strings.Split(AddPasswords, ",")
|
||||||
Passwords = append(Passwords, passes...)
|
Passwords = append(Passwords, passes...)
|
||||||
Passwords = RemoveDuplicate(Passwords)
|
Passwords = RemoveDuplicate(Passwords)
|
||||||
LogInfo(GetText("extra_passwords", AddPasswords))
|
LogBase(GetText("extra_passwords", AddPasswords))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理Socks5代理配置
|
// 处理Socks5代理配置
|
||||||
@ -301,7 +301,7 @@ func ParseInput(Info *HostInfo) error {
|
|||||||
return fmt.Errorf(GetText("socks5_proxy_error", err))
|
return fmt.Errorf(GetText("socks5_proxy_error", err))
|
||||||
}
|
}
|
||||||
DisablePing = true
|
DisablePing = true
|
||||||
LogInfo(GetText("socks5_proxy", Socks5Proxy))
|
LogBase(GetText("socks5_proxy", Socks5Proxy))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理HTTP代理配置
|
// 处理HTTP代理配置
|
||||||
@ -325,7 +325,7 @@ func ParseInput(Info *HostInfo) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(GetText("proxy_format_error", err))
|
return fmt.Errorf(GetText("proxy_format_error", err))
|
||||||
}
|
}
|
||||||
LogInfo(GetText("http_proxy", HttpProxy))
|
LogBase(GetText("http_proxy", HttpProxy))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理Hash配置
|
// 处理Hash配置
|
||||||
|
@ -24,7 +24,7 @@ func ParseIP(host string, filename string, nohosts ...string) (hosts []string, e
|
|||||||
host = hostport[0]
|
host = hostport[0]
|
||||||
hosts = ParseIPs(host)
|
hosts = ParseIPs(host)
|
||||||
Ports = hostport[1]
|
Ports = hostport[1]
|
||||||
LogInfo(GetText("host_port_parsed", Ports))
|
LogBase(GetText("host_port_parsed", Ports))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 解析主机地址
|
// 解析主机地址
|
||||||
@ -37,7 +37,7 @@ func ParseIP(host string, filename string, nohosts ...string) (hosts []string, e
|
|||||||
LogError(GetText("read_host_file_failed", err))
|
LogError(GetText("read_host_file_failed", err))
|
||||||
} else {
|
} else {
|
||||||
hosts = append(hosts, fileHosts...)
|
hosts = append(hosts, fileHosts...)
|
||||||
LogInfo(GetText("extra_hosts_loaded", len(fileHosts)))
|
LogBase(GetText("extra_hosts_loaded", len(fileHosts)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,13 +64,13 @@ func ParseIP(host string, filename string, nohosts ...string) (hosts []string, e
|
|||||||
}
|
}
|
||||||
hosts = newHosts
|
hosts = newHosts
|
||||||
sort.Strings(hosts)
|
sort.Strings(hosts)
|
||||||
LogInfo(GetText("hosts_excluded", len(excludeHosts)))
|
LogBase(GetText("hosts_excluded", len(excludeHosts)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去重处理
|
// 去重处理
|
||||||
hosts = RemoveDuplicate(hosts)
|
hosts = RemoveDuplicate(hosts)
|
||||||
LogInfo(GetText("final_valid_hosts", len(hosts)))
|
LogBase(GetText("final_valid_hosts", len(hosts)))
|
||||||
|
|
||||||
// 检查解析结果
|
// 检查解析结果
|
||||||
if len(hosts) == 0 && len(HostPort) == 0 && (host != "" || filename != "") {
|
if len(hosts) == 0 && len(HostPort) == 0 && (host != "" || filename != "") {
|
||||||
@ -132,7 +132,7 @@ func parseIP2(host string) []string {
|
|||||||
|
|
||||||
ipRange := IPRange(ipNet)
|
ipRange := IPRange(ipNet)
|
||||||
hosts := parseIP1(ipRange)
|
hosts := parseIP1(ipRange)
|
||||||
LogInfo(GetText("parse_cidr_to_range", host, ipRange))
|
LogBase(GetText("parse_cidr_to_range", host, ipRange))
|
||||||
return hosts
|
return hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ func parseIP1(ip string) []string {
|
|||||||
allIP = append(allIP, prefixIP+"."+strconv.Itoa(i))
|
allIP = append(allIP, prefixIP+"."+strconv.Itoa(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(GetText("generate_ip_range", prefixIP, startNum, prefixIP, endNum))
|
LogBase(GetText("generate_ip_range", prefixIP, startNum, prefixIP, endNum))
|
||||||
} else {
|
} else {
|
||||||
// 处理完整IP范围格式
|
// 处理完整IP范围格式
|
||||||
splitIP1 := strings.Split(ipRange[0], ".")
|
splitIP1 := strings.Split(ipRange[0], ".")
|
||||||
@ -197,7 +197,7 @@ func parseIP1(ip string) []string {
|
|||||||
allIP = append(allIP, ip)
|
allIP = append(allIP, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(GetText("generate_ip_range", ipRange[0], ipRange[1]))
|
LogBase(GetText("generate_ip_range", ipRange[0], ipRange[1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return allIP
|
return allIP
|
||||||
@ -217,7 +217,7 @@ func IPRange(c *net.IPNet) string {
|
|||||||
end := bcst.String()
|
end := bcst.String()
|
||||||
|
|
||||||
result := fmt.Sprintf("%s-%s", start, end)
|
result := fmt.Sprintf("%s-%s", start, end)
|
||||||
LogInfo(GetText("cidr_range", result))
|
LogBase(GetText("cidr_range", result))
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,11 +253,11 @@ func Readipfile(filename string) ([]string, error) {
|
|||||||
for _, host := range hosts {
|
for _, host := range hosts {
|
||||||
HostPort = append(HostPort, fmt.Sprintf("%s:%s", host, port))
|
HostPort = append(HostPort, fmt.Sprintf("%s:%s", host, port))
|
||||||
}
|
}
|
||||||
LogInfo(GetText("parse_ip_port", line))
|
LogBase(GetText("parse_ip_port", line))
|
||||||
} else {
|
} else {
|
||||||
hosts := ParseIPs(line)
|
hosts := ParseIPs(line)
|
||||||
content = append(content, hosts...)
|
content = append(content, hosts...)
|
||||||
LogInfo(GetText("parse_ip_address", line))
|
LogBase(GetText("parse_ip_address", line))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ func Readipfile(filename string) ([]string, error) {
|
|||||||
return content, err
|
return content, err
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(GetText("file_parse_complete", len(content)))
|
LogBase(GetText("file_parse_complete", len(content)))
|
||||||
return content, nil
|
return content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +300,7 @@ func parseIP8(ip string) []string {
|
|||||||
ipRange := strings.Split(ip, ".")[0]
|
ipRange := strings.Split(ip, ".")[0]
|
||||||
var allIP []string
|
var allIP []string
|
||||||
|
|
||||||
LogInfo(GetText("parse_subnet", ipRange))
|
LogBase(GetText("parse_subnet", ipRange))
|
||||||
|
|
||||||
// 遍历所有可能的第二、三段
|
// 遍历所有可能的第二、三段
|
||||||
for a := 0; a <= 255; a++ {
|
for a := 0; a <= 255; a++ {
|
||||||
@ -321,7 +321,7 @@ func parseIP8(ip string) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(GetText("sample_ip_generated", len(allIP)))
|
LogBase(GetText("sample_ip_generated", len(allIP)))
|
||||||
return allIP
|
return allIP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package Common
|
package Common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParsePort 解析端口配置字符串为端口号列表
|
// ParsePort 解析端口配置字符串为端口号列表
|
||||||
@ -73,7 +73,7 @@ func ParsePort(ports string) []int {
|
|||||||
scanPorts = removeDuplicate(scanPorts)
|
scanPorts = removeDuplicate(scanPorts)
|
||||||
sort.Ints(scanPorts)
|
sort.Ints(scanPorts)
|
||||||
|
|
||||||
LogInfo(GetText("valid_port_count", len(scanPorts)))
|
LogBase(GetText("valid_port_count", len(scanPorts)))
|
||||||
return scanPorts
|
return scanPorts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ var PluginGroups = map[string][]string{
|
|||||||
|
|
||||||
// ParseScanMode 解析扫描模式
|
// ParseScanMode 解析扫描模式
|
||||||
func ParseScanMode(mode string) {
|
func ParseScanMode(mode string) {
|
||||||
LogInfo(GetText("parse_scan_mode", mode))
|
LogBase(GetText("parse_scan_mode", mode))
|
||||||
|
|
||||||
// 检查是否是预设模式
|
// 检查是否是预设模式
|
||||||
presetModes := []string{
|
presetModes := []string{
|
||||||
@ -58,9 +58,9 @@ func ParseScanMode(mode string) {
|
|||||||
if mode == presetMode {
|
if mode == presetMode {
|
||||||
ScanMode = mode
|
ScanMode = mode
|
||||||
if plugins := GetPluginsForMode(mode); plugins != nil {
|
if plugins := GetPluginsForMode(mode); plugins != nil {
|
||||||
LogInfo(GetText("using_preset_mode_plugins", mode, plugins))
|
LogBase(GetText("using_preset_mode_plugins", mode, plugins))
|
||||||
} else {
|
} else {
|
||||||
LogInfo(GetText("using_preset_mode", mode))
|
LogBase(GetText("using_preset_mode", mode))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -69,14 +69,14 @@ func ParseScanMode(mode string) {
|
|||||||
// 检查是否是有效的插件名
|
// 检查是否是有效的插件名
|
||||||
if _, exists := PluginManager[mode]; exists {
|
if _, exists := PluginManager[mode]; exists {
|
||||||
ScanMode = mode
|
ScanMode = mode
|
||||||
LogInfo(GetText("using_single_plugin", mode))
|
LogBase(GetText("using_single_plugin", mode))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认使用All模式
|
// 默认使用All模式
|
||||||
ScanMode = ModeAll
|
ScanMode = ModeAll
|
||||||
LogInfo(GetText("using_default_mode", ModeAll))
|
LogBase(GetText("using_default_mode", ModeAll))
|
||||||
LogInfo(GetText("included_plugins", PluginGroups[ModeAll]))
|
LogBase(GetText("included_plugins", PluginGroups[ModeAll]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPluginsForMode 获取指定模式下的插件列表
|
// GetPluginsForMode 获取指定模式下的插件列表
|
||||||
|
@ -97,7 +97,7 @@ func probeWithICMP(hostslist []string, chanHosts chan string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Common.LogError(Common.GetText("icmp_listen_failed", err))
|
Common.LogError(Common.GetText("icmp_listen_failed", err))
|
||||||
Common.LogInfo(Common.GetText("trying_no_listen_icmp"))
|
Common.LogBase(Common.GetText("trying_no_listen_icmp"))
|
||||||
|
|
||||||
// 尝试无监听ICMP探测
|
// 尝试无监听ICMP探测
|
||||||
conn2, err := net.DialTimeout("ip4:icmp", "127.0.0.1", 3*time.Second)
|
conn2, err := net.DialTimeout("ip4:icmp", "127.0.0.1", 3*time.Second)
|
||||||
@ -108,8 +108,8 @@ func probeWithICMP(hostslist []string, chanHosts chan string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Common.LogError(Common.GetText("icmp_connect_failed", err))
|
Common.LogError(Common.GetText("icmp_connect_failed", err))
|
||||||
Common.LogInfo(Common.GetText("insufficient_privileges"))
|
Common.LogBase(Common.GetText("insufficient_privileges"))
|
||||||
Common.LogInfo(Common.GetText("switching_to_ping"))
|
Common.LogBase(Common.GetText("switching_to_ping"))
|
||||||
|
|
||||||
// 降级使用ping探测
|
// 降级使用ping探测
|
||||||
RunPing(hostslist, chanHosts)
|
RunPing(hostslist, chanHosts)
|
||||||
|
@ -120,7 +120,7 @@ func PortConnect(addr Addr, results chan<- ScanResult, timeout int64, wg *sync.W
|
|||||||
|
|
||||||
// 记录开放端口
|
// 记录开放端口
|
||||||
address := fmt.Sprintf("%s:%d", addr.ip, addr.port)
|
address := fmt.Sprintf("%s:%d", addr.ip, addr.port)
|
||||||
Common.LogSuccess(fmt.Sprintf("端口开放 %s", address))
|
Common.LogInfo(fmt.Sprintf("端口开放 %s", address))
|
||||||
|
|
||||||
// 保存端口扫描结果
|
// 保存端口扫描结果
|
||||||
portResult := &Common.ScanResult{
|
portResult := &Common.ScanResult{
|
||||||
@ -145,7 +145,6 @@ func PortConnect(addr Addr, results chan<- ScanResult, timeout int64, wg *sync.W
|
|||||||
scanner := NewPortInfoScanner(addr.ip, addr.port, conn, time.Duration(timeout)*time.Second)
|
scanner := NewPortInfoScanner(addr.ip, addr.port, conn, time.Duration(timeout)*time.Second)
|
||||||
if serviceInfo, err := scanner.Identify(); err == nil {
|
if serviceInfo, err := scanner.Identify(); err == nil {
|
||||||
result.Service = serviceInfo
|
result.Service = serviceInfo
|
||||||
|
|
||||||
// 构造服务识别日志
|
// 构造服务识别日志
|
||||||
var logMsg strings.Builder
|
var logMsg strings.Builder
|
||||||
logMsg.WriteString(fmt.Sprintf("服务识别 %s => ", address))
|
logMsg.WriteString(fmt.Sprintf("服务识别 %s => ", address))
|
||||||
@ -202,8 +201,11 @@ func PortConnect(addr Addr, results chan<- ScanResult, timeout int64, wg *sync.W
|
|||||||
Details: details,
|
Details: details,
|
||||||
}
|
}
|
||||||
Common.SaveResult(serviceResult)
|
Common.SaveResult(serviceResult)
|
||||||
|
if serviceInfo.Name != "unknown" {
|
||||||
Common.LogSuccess(logMsg.String())
|
Common.LogSuccess(logMsg.String())
|
||||||
|
} else {
|
||||||
|
Common.LogDebug(logMsg.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ var (
|
|||||||
// Scan 执行扫描主流程
|
// Scan 执行扫描主流程
|
||||||
// info: 主机信息结构体,包含扫描目标的基本信息
|
// info: 主机信息结构体,包含扫描目标的基本信息
|
||||||
func Scan(info Common.HostInfo) {
|
func Scan(info Common.HostInfo) {
|
||||||
Common.LogInfo("开始信息扫描")
|
Common.LogBase("开始信息扫描")
|
||||||
|
|
||||||
// 初始化HTTP客户端配置
|
// 初始化HTTP客户端配置
|
||||||
lib.Inithttp()
|
lib.Inithttp()
|
||||||
@ -55,7 +55,7 @@ func Scan(info Common.HostInfo) {
|
|||||||
// ch: 并发控制通道
|
// ch: 并发控制通道
|
||||||
// wg: 等待组
|
// wg: 等待组
|
||||||
func executeLocalScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) {
|
func executeLocalScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) {
|
||||||
Common.LogInfo("执行本地信息收集")
|
Common.LogBase("执行本地信息收集")
|
||||||
|
|
||||||
// 获取本地模式支持的插件列表
|
// 获取本地模式支持的插件列表
|
||||||
validLocalPlugins := getValidPlugins(Common.ModeLocal)
|
validLocalPlugins := getValidPlugins(Common.ModeLocal)
|
||||||
@ -68,10 +68,10 @@ func executeLocalScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGrou
|
|||||||
|
|
||||||
// 输出使用的插件信息
|
// 输出使用的插件信息
|
||||||
if Common.ScanMode == Common.ModeLocal {
|
if Common.ScanMode == Common.ModeLocal {
|
||||||
Common.LogInfo("使用全部本地插件")
|
Common.LogBase("使用全部本地插件")
|
||||||
Common.ParseScanMode(Common.ScanMode)
|
Common.ParseScanMode(Common.ScanMode)
|
||||||
} else {
|
} else {
|
||||||
Common.LogInfo(fmt.Sprintf("使用插件: %s", Common.ScanMode))
|
Common.LogBase(fmt.Sprintf("使用插件: %s", Common.ScanMode))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行扫描任务
|
// 执行扫描任务
|
||||||
@ -83,7 +83,7 @@ func executeLocalScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGrou
|
|||||||
// ch: 并发控制通道
|
// ch: 并发控制通道
|
||||||
// wg: 等待组
|
// wg: 等待组
|
||||||
func executeWebScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) {
|
func executeWebScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) {
|
||||||
Common.LogInfo("开始Web扫描")
|
Common.LogBase("开始Web扫描")
|
||||||
|
|
||||||
// 获取Web模式支持的插件列表
|
// 获取Web模式支持的插件列表
|
||||||
validWebPlugins := getValidPlugins(Common.ModeWeb)
|
validWebPlugins := getValidPlugins(Common.ModeWeb)
|
||||||
@ -108,10 +108,10 @@ func executeWebScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup)
|
|||||||
|
|
||||||
// 输出使用的插件信息
|
// 输出使用的插件信息
|
||||||
if Common.ScanMode == Common.ModeWeb {
|
if Common.ScanMode == Common.ModeWeb {
|
||||||
Common.LogInfo("使用全部Web插件")
|
Common.LogBase("使用全部Web插件")
|
||||||
Common.ParseScanMode(Common.ScanMode)
|
Common.ParseScanMode(Common.ScanMode)
|
||||||
} else {
|
} else {
|
||||||
Common.LogInfo(fmt.Sprintf("使用插件: %s", Common.ScanMode))
|
Common.LogBase(fmt.Sprintf("使用插件: %s", Common.ScanMode))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行扫描任务
|
// 执行扫描任务
|
||||||
@ -136,7 +136,7 @@ func executeHostScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Common.LogInfo("开始主机扫描")
|
Common.LogBase("开始主机扫描")
|
||||||
executeScan(hosts, info, ch, wg)
|
executeScan(hosts, info, ch, wg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ func executeScan(hosts []string, info Common.HostInfo, ch *chan struct{}, wg *sy
|
|||||||
// 检查主机存活性
|
// 检查主机存活性
|
||||||
if shouldPingScan(hosts) {
|
if shouldPingScan(hosts) {
|
||||||
hosts = CheckLive(hosts, Common.UsePing)
|
hosts = CheckLive(hosts, Common.UsePing)
|
||||||
Common.LogInfo(fmt.Sprintf("存活主机数量: %d", len(hosts)))
|
Common.LogBase(fmt.Sprintf("存活主机数量: %d", len(hosts)))
|
||||||
if Common.IsICMPScan() {
|
if Common.IsICMPScan() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ func executeScan(hosts []string, info Common.HostInfo, ch *chan struct{}, wg *sy
|
|||||||
|
|
||||||
// 执行漏洞扫描
|
// 执行漏洞扫描
|
||||||
if len(targetInfos) > 0 {
|
if len(targetInfos) > 0 {
|
||||||
Common.LogInfo("开始漏洞扫描")
|
Common.LogBase("开始漏洞扫描")
|
||||||
executeScans(targetInfos, ch, wg)
|
executeScans(targetInfos, ch, wg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@ func getAlivePorts(hosts []string) []string {
|
|||||||
alivePorts = NoPortScan(hosts, Common.Ports)
|
alivePorts = NoPortScan(hosts, Common.Ports)
|
||||||
} else if len(hosts) > 0 {
|
} else if len(hosts) > 0 {
|
||||||
alivePorts = PortScan(hosts, Common.Ports, Common.Timeout)
|
alivePorts = PortScan(hosts, Common.Ports, Common.Timeout)
|
||||||
Common.LogInfo(fmt.Sprintf("存活端口数量: %d", len(alivePorts)))
|
Common.LogBase(fmt.Sprintf("存活端口数量: %d", len(alivePorts)))
|
||||||
if Common.IsPortScan() {
|
if Common.IsPortScan() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ func getAlivePorts(hosts []string) []string {
|
|||||||
alivePorts = append(alivePorts, Common.HostPort...)
|
alivePorts = append(alivePorts, Common.HostPort...)
|
||||||
alivePorts = Common.RemoveDuplicate(alivePorts)
|
alivePorts = Common.RemoveDuplicate(alivePorts)
|
||||||
Common.HostPort = nil
|
Common.HostPort = nil
|
||||||
Common.LogInfo(fmt.Sprintf("存活端口数量: %d", len(alivePorts)))
|
Common.LogBase(fmt.Sprintf("存活端口数量: %d", len(alivePorts)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return alivePorts
|
return alivePorts
|
||||||
@ -307,7 +307,7 @@ func executeScans(targets []Common.HostInfo, ch *chan struct{}, wg *sync.WaitGro
|
|||||||
|
|
||||||
// 处理插件列表
|
// 处理插件列表
|
||||||
finalPlugins := getUniquePlugins(loadedPlugins)
|
finalPlugins := getUniquePlugins(loadedPlugins)
|
||||||
Common.LogInfo(fmt.Sprintf("加载的插件: %s", strings.Join(finalPlugins, ", ")))
|
Common.LogBase(fmt.Sprintf("加载的插件: %s", strings.Join(finalPlugins, ", ")))
|
||||||
|
|
||||||
// 初始化进度条
|
// 初始化进度条
|
||||||
initializeProgressBar(actualTasks)
|
initializeProgressBar(actualTasks)
|
||||||
@ -406,7 +406,7 @@ func finishScan(wg *sync.WaitGroup) {
|
|||||||
Common.ProgressBar.Finish()
|
Common.ProgressBar.Finish()
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
Common.LogSuccess(fmt.Sprintf("扫描已完成: %v/%v", Common.End, Common.Num))
|
Common.LogBase(fmt.Sprintf("扫描已完成: %v/%v", Common.End, Common.Num))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mutex 用于保护共享资源的并发访问
|
// Mutex 用于保护共享资源的并发访问
|
||||||
@ -445,7 +445,7 @@ func ScanFunc(name *string, info *Common.HostInfo) {
|
|||||||
|
|
||||||
plugin, exists := Common.PluginManager[*name]
|
plugin, exists := Common.PluginManager[*name]
|
||||||
if !exists {
|
if !exists {
|
||||||
Common.LogInfo(fmt.Sprintf("扫描类型 %v 无对应插件,已跳过", *name))
|
Common.LogBase(fmt.Sprintf("扫描类型 %v 无对应插件,已跳过", *name))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ var (
|
|||||||
|
|
||||||
// LocalInfoScan 本地信息收集主函数
|
// LocalInfoScan 本地信息收集主函数
|
||||||
func LocalInfoScan(info *Common.HostInfo) (err error) {
|
func LocalInfoScan(info *Common.HostInfo) (err error) {
|
||||||
Common.LogInfo("开始本地信息收集...")
|
Common.LogBase("开始本地信息收集...")
|
||||||
|
|
||||||
// 获取用户主目录
|
// 获取用户主目录
|
||||||
home, err := os.UserHomeDir()
|
home, err := os.UserHomeDir()
|
||||||
@ -107,7 +107,7 @@ func LocalInfoScan(info *Common.HostInfo) (err error) {
|
|||||||
// 根据规则搜索敏感文件
|
// 根据规则搜索敏感文件
|
||||||
searchSensitiveFiles()
|
searchSensitiveFiles()
|
||||||
|
|
||||||
Common.LogInfo("本地信息收集完成")
|
Common.LogBase("本地信息收集完成")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ func geturl(info *Common.HostInfo, flag int, CheckData []WebScan.CheckDatas) (er
|
|||||||
if reurl != "" {
|
if reurl != "" {
|
||||||
logMsg += fmt.Sprintf(" 重定向地址: %s", reurl)
|
logMsg += fmt.Sprintf(" 重定向地址: %s", reurl)
|
||||||
}
|
}
|
||||||
Common.LogSuccess(logMsg)
|
Common.LogInfo(logMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回结果
|
// 返回结果
|
||||||
|
Loading…
Reference in New Issue
Block a user