fscan/common/globals.go
ZacharyZcR d19abcac36 feat: 新增发包频率控制功能
- 添加-rate参数:控制每分钟最大发包次数
- 添加-maxpkts参数:控制整个程序最大发包总数
- 在所有网络操作点集成发包限制检查
- 支持端口扫描、Web检测、服务插件、POC扫描等场景
- 默认不限制,保持向后兼容性
2025-09-02 11:24:09 +00:00

333 lines
10 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package common
import (
"fmt"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/shadow1ng/fscan/common/config"
)
/*
globals.go - 全局配置变量
直接定义全局变量消除base包的双重声明。
*/
var (
// =============================================================================
// 核心扫描配置
// =============================================================================
ScanMode string = DefaultScanMode // 扫描模式
ThreadNum int = DefaultThreadNum // 线程数
Timeout int64 = DefaultTimeout // 超时时间
DisablePing bool = false // 禁用ping
LocalMode bool = false // 本地模式
LocalPlugin string // 本地插件选择
AliveOnly bool // 仅存活检测
DisableBrute bool // 禁用暴力破解
MaxRetries int = 3 // 最大重试次数
// =============================================================================
// 认证相关配置
// =============================================================================
Username string // 用户名
Password string // 密码
Domain string // 域
Userdict map[string][]string // 用户字典
Passwords []string // 密码列表
// =============================================================================
// 网络配置
// =============================================================================
HttpProxy string // HTTP代理
Socks5Proxy string // SOCKS5代理
WebTimeout int64 = 5 // Web超时时间
// =============================================================================
// 文件路径
// =============================================================================
SshKeyPath string // SSH密钥路径
PersistenceTargetFile string // Linux持久化目标文件
WinPEFile string // Windows PE文件
// =============================================================================
// 功能开关
// =============================================================================
NoColor bool // 禁用颜色
Silent bool // 静默模式
DisableSave bool // 禁用保存
DisableProgress bool // 禁用进度条
Language string = DefaultLanguage // 语言
LogLevel string = DefaultLogLevel // 日志级别
// =============================================================================
// 高级功能
// =============================================================================
Shellcode string // Shellcode
LocalPluginsList []string // 本地插件列表
DnsLog bool // DNS日志
ForwardShellActive bool // 正向Shell状态
ReverseShellActive bool // 反向Shell状态
Socks5ProxyActive bool // SOCKS5代理状态
// =============================================================================
// 端口和服务映射
// =============================================================================
PortMap map[int][]string // 端口到服务映射
DefaultMap []string // 默认探测器映射
// =============================================================================
// 输出控制
// =============================================================================
Outputfile string = "result.txt" // 输出文件
OutputFormat string = "txt" // 输出格式
ShowProgress bool = true // 显示进度条
StartTime time.Time // 开始时间
ProgressBar interface{} // 进度条实例
OutputMutex sync.Mutex // 输出互斥锁
// =============================================================================
// 计数器
// =============================================================================
End int64 // 结束计数器
Num int64 // 数量计数器
// 网络包计数器 - 使用原子操作确保线程安全
PacketCount int64 // 总发包数量
TCPPacketCount int64 // TCP包数量总计
TCPSuccessPacketCount int64 // TCP成功连接包数量
TCPFailedPacketCount int64 // TCP失败连接包数量
UDPPacketCount int64 // UDP包数量
HTTPPacketCount int64 // HTTP请求数量
// 发包频率控制变量
PacketRateStartTime int64 // 当前分钟的开始时间戳
PacketRateCurrentCount int64 // 当前分钟内的发包数量
PacketRateMutex sync.Mutex // 发包频率控制互斥锁
// =============================================================================
// 初始化控制
// =============================================================================
initOnce sync.Once // 确保初始化只执行一次
)
// InitGlobalConfig 初始化全局配置
func InitGlobalConfig() {
initOnce.Do(func() {
// 初始化时间
if StartTime.IsZero() {
StartTime = time.Now()
}
// 初始化映射和切片
if Userdict == nil {
Userdict = make(map[string][]string)
}
if PortMap == nil {
PortMap = make(map[int][]string)
}
if DefaultMap == nil {
DefaultMap = make([]string, 0)
}
if Passwords == nil {
Passwords = make([]string, 0)
}
// 从config模块获取字典和映射
if serviceDict := config.GetGlobalServiceDict(); serviceDict != nil {
Userdict = serviceDict.GetAllUserDicts()
Passwords = serviceDict.GetPasswords()
}
if probeMapping := config.GetGlobalProbeMapping(); probeMapping != nil {
PortMap = probeMapping.GetAllPortMappings()
DefaultMap = probeMapping.GetDefaultProbes()
}
})
}
// init 自动初始化
func init() {
InitGlobalConfig()
}
// POCInfo POC相关信息
type PocInfo struct {
Target string
PocName string
}
var Pocinfo PocInfo
// 版本信息
const version = "2.2.1"
// 日志级别常量
const (
LogLevelAll = "all"
LogLevelError = "error"
LogLevelBase = "base"
LogLevelInfo = "info"
LogLevelSuccess = "success"
LogLevelDebug = "debug"
LogLevelInfoSuccess = "info,success"
LogLevelBaseInfoSuccess = "base,info,success"
)
// LogWithProgress 已在progressmanager.go中定义此处不重复
// =============================================================================
// 网络包计数器功能
// =============================================================================
// IncrementPacketCount 增加总包计数(原子操作)
func IncrementPacketCount() int64 {
return atomic.AddInt64(&PacketCount, 1)
}
// IncrementTCPSuccessPacketCount 增加TCP成功连接包计数原子操作
func IncrementTCPSuccessPacketCount() int64 {
atomic.AddInt64(&TCPSuccessPacketCount, 1)
atomic.AddInt64(&TCPPacketCount, 1)
return atomic.AddInt64(&PacketCount, 1)
}
// IncrementTCPFailedPacketCount 增加TCP失败连接包计数原子操作
func IncrementTCPFailedPacketCount() int64 {
atomic.AddInt64(&TCPFailedPacketCount, 1)
atomic.AddInt64(&TCPPacketCount, 1)
return atomic.AddInt64(&PacketCount, 1)
}
// IncrementUDPPacketCount 增加UDP包计数原子操作
func IncrementUDPPacketCount() int64 {
atomic.AddInt64(&UDPPacketCount, 1)
return atomic.AddInt64(&PacketCount, 1)
}
// IncrementHTTPPacketCount 增加HTTP包计数原子操作
func IncrementHTTPPacketCount() int64 {
atomic.AddInt64(&HTTPPacketCount, 1)
return atomic.AddInt64(&PacketCount, 1)
}
// GetPacketCount 获取总包计数(原子操作)
func GetPacketCount() int64 {
return atomic.LoadInt64(&PacketCount)
}
// GetTCPPacketCount 获取TCP包计数原子操作
func GetTCPPacketCount() int64 {
return atomic.LoadInt64(&TCPPacketCount)
}
// GetTCPSuccessPacketCount 获取TCP成功连接包计数原子操作
func GetTCPSuccessPacketCount() int64 {
return atomic.LoadInt64(&TCPSuccessPacketCount)
}
// GetTCPFailedPacketCount 获取TCP失败连接包计数原子操作
func GetTCPFailedPacketCount() int64 {
return atomic.LoadInt64(&TCPFailedPacketCount)
}
// GetUDPPacketCount 获取UDP包计数原子操作
func GetUDPPacketCount() int64 {
return atomic.LoadInt64(&UDPPacketCount)
}
// GetHTTPPacketCount 获取HTTP包计数原子操作
func GetHTTPPacketCount() int64 {
return atomic.LoadInt64(&HTTPPacketCount)
}
// ResetPacketCounters 重置所有包计数器(原子操作)
func ResetPacketCounters() {
atomic.StoreInt64(&PacketCount, 0)
atomic.StoreInt64(&TCPPacketCount, 0)
atomic.StoreInt64(&TCPSuccessPacketCount, 0)
atomic.StoreInt64(&TCPFailedPacketCount, 0)
atomic.StoreInt64(&UDPPacketCount, 0)
atomic.StoreInt64(&HTTPPacketCount, 0)
}
// =============================================================================
// 发包频率控制功能
// =============================================================================
// CanSendPacket 检查是否可以发包 - 同时检查频率限制和总数限制
// 返回值: (可以发包, 错误信息)
func CanSendPacket() (bool, string) {
// 检查总数限制
if MaxPacketCount > 0 {
currentTotal := atomic.LoadInt64(&PacketCount)
if currentTotal >= MaxPacketCount {
return false, fmt.Sprintf("已达到最大发包数量限制: %d", MaxPacketCount)
}
}
// 检查频率限制
if PacketRateLimit > 0 {
PacketRateMutex.Lock()
defer PacketRateMutex.Unlock()
currentTime := time.Now().Unix() / 60 // 当前分钟
// 如果是新的分钟,重置计数器
if PacketRateStartTime != currentTime {
PacketRateStartTime = currentTime
atomic.StoreInt64(&PacketRateCurrentCount, 0)
}
// 检查当前分钟的发包数是否超限
currentCount := atomic.LoadInt64(&PacketRateCurrentCount)
if currentCount >= PacketRateLimit {
return false, fmt.Sprintf("已达到每分钟发包频率限制: %d", PacketRateLimit)
}
// 增加当前分钟的发包计数
atomic.AddInt64(&PacketRateCurrentCount, 1)
}
return true, ""
}
// WaitForPacketLimit 等待直到可以发包 - 智能等待策略
func WaitForPacketLimit() error {
maxWaitTime := 60 * time.Second // 最大等待1分钟
startWait := time.Now()
for {
canSend, reason := CanSendPacket()
if canSend {
return nil
}
// 如果是总数限制,直接返回错误
if MaxPacketCount > 0 && strings.Contains(reason, "最大发包数量") {
return fmt.Errorf(reason)
}
// 如果等待超时,返回错误
if time.Since(startWait) > maxWaitTime {
return fmt.Errorf("等待发包权限超时: %s", reason)
}
// 短暂休眠后重试
time.Sleep(100 * time.Millisecond)
}
}