mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 03:10:42 +08:00
Disable default global scan timeout
This commit is contained in:
@@ -52,7 +52,7 @@ fscan -h 192.168.1.0/24 -silent | jq 'select(.type=="VULN")'
|
|||||||
| `-t` | 端口扫描线程数 | `600` |
|
| `-t` | 端口扫描线程数 | `600` |
|
||||||
| `-mt` | 模块线程数 | `20` |
|
| `-mt` | 模块线程数 | `20` |
|
||||||
| `-time` | 连接超时(秒) | `3` |
|
| `-time` | 连接超时(秒) | `3` |
|
||||||
| `-gt` | 全局超时(秒) | `180` |
|
| `-gt` | 全局超时(秒,0 表示不限制) | `0` |
|
||||||
| `-np` | 跳过存活检测 | `false` |
|
| `-np` | 跳过存活检测 | `false` |
|
||||||
| `-ntp` | 禁用 TCP 补充探测 | `false` |
|
| `-ntp` | 禁用 TCP 补充探测 | `false` |
|
||||||
| `-ao` | 仅存活检测 | `false` |
|
| `-ao` | 仅存活检测 | `false` |
|
||||||
|
|||||||
+1
-1
@@ -110,7 +110,7 @@ func Flag(Info *HostInfo) error {
|
|||||||
flag.IntVar(&fv.ThreadNum, "t", 600, i18n.GetText("flag_thread_num"))
|
flag.IntVar(&fv.ThreadNum, "t", 600, i18n.GetText("flag_thread_num"))
|
||||||
flag.Int64Var(&fv.TimeoutSec, "time", 3, i18n.GetText("flag_timeout"))
|
flag.Int64Var(&fv.TimeoutSec, "time", 3, i18n.GetText("flag_timeout"))
|
||||||
flag.IntVar(&fv.ModuleThreadNum, "mt", 20, i18n.GetText("flag_module_thread_num"))
|
flag.IntVar(&fv.ModuleThreadNum, "mt", 20, i18n.GetText("flag_module_thread_num"))
|
||||||
flag.Int64Var(&fv.GlobalTimeout, "gt", 180, i18n.GetText("flag_global_timeout"))
|
flag.Int64Var(&fv.GlobalTimeout, "gt", 0, i18n.GetText("flag_global_timeout"))
|
||||||
flag.BoolVar(&fv.DisablePing, "np", false, i18n.GetText("flag_disable_ping"))
|
flag.BoolVar(&fv.DisablePing, "np", false, i18n.GetText("flag_disable_ping"))
|
||||||
flag.BoolVar(&fv.DisableTcpProbe, "ntp", false, i18n.GetText("flag_disable_tcp_probe"))
|
flag.BoolVar(&fv.DisableTcpProbe, "ntp", false, i18n.GetText("flag_disable_tcp_probe"))
|
||||||
flag.BoolVar(&fv.DisableSubnetProbe, "nsp", false, i18n.GetText("flag_disable_subnet_probe"))
|
flag.BoolVar(&fv.DisableSubnetProbe, "nsp", false, i18n.GetText("flag_disable_subnet_probe"))
|
||||||
|
|||||||
+4
-1
@@ -34,7 +34,7 @@ func TestBuildConfigFromFlags_ScanControl(t *testing.T) {
|
|||||||
ThreadNum: 600,
|
ThreadNum: 600,
|
||||||
ModuleThreadNum: 20,
|
ModuleThreadNum: 20,
|
||||||
TimeoutSec: 3,
|
TimeoutSec: 3,
|
||||||
GlobalTimeout: 180,
|
GlobalTimeout: 0,
|
||||||
},
|
},
|
||||||
validate: func(t *testing.T, cfg *Config) {
|
validate: func(t *testing.T, cfg *Config) {
|
||||||
if cfg.Mode != "all" {
|
if cfg.Mode != "all" {
|
||||||
@@ -49,6 +49,9 @@ func TestBuildConfigFromFlags_ScanControl(t *testing.T) {
|
|||||||
if cfg.Timeout != 3*time.Second {
|
if cfg.Timeout != 3*time.Second {
|
||||||
t.Errorf("Timeout = %v, want %v", cfg.Timeout, 3*time.Second)
|
t.Errorf("Timeout = %v, want %v", cfg.Timeout, 3*time.Second)
|
||||||
}
|
}
|
||||||
|
if cfg.GlobalTimeout != 0 {
|
||||||
|
t.Errorf("GlobalTimeout = %v, want disabled", cfg.GlobalTimeout)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ flag_timeout:
|
|||||||
flag_module_thread_num:
|
flag_module_thread_num:
|
||||||
other: "Module thread count"
|
other: "Module thread count"
|
||||||
flag_global_timeout:
|
flag_global_timeout:
|
||||||
other: "Global timeout"
|
other: "Global timeout in seconds (0 means unlimited)"
|
||||||
global_timeout_adjusted:
|
|
||||||
other: "Large scan detected, global timeout adjusted from {{.V0}}s to {{.V1}}s (use -gt to override)"
|
|
||||||
global_timeout_exceeded:
|
global_timeout_exceeded:
|
||||||
other: "Global timeout reached (-gt {{.V0}}s), scan aborted. Use -gt to increase or set to 0 to disable"
|
other: "Global timeout reached (-gt {{.V0}}s), scan aborted. Use -gt to increase or set to 0 to disable"
|
||||||
flag_disable_ping:
|
flag_disable_ping:
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ flag_timeout:
|
|||||||
flag_module_thread_num:
|
flag_module_thread_num:
|
||||||
other: "模块线程数"
|
other: "模块线程数"
|
||||||
flag_global_timeout:
|
flag_global_timeout:
|
||||||
other: "全局超时时间"
|
other: "全局超时时间(秒,0 表示不限制)"
|
||||||
global_timeout_adjusted:
|
|
||||||
other: "扫描规模较大,全局超时从 {{.V0}}s 自动调整为 {{.V1}}s(可用 -gt 手动指定)"
|
|
||||||
global_timeout_exceeded:
|
global_timeout_exceeded:
|
||||||
other: "全局超时已到(-gt {{.V0}}s),扫描被终止。大规模扫描请用 -gt 调大超时或设为 0 禁用"
|
other: "全局超时已到(-gt {{.V0}}s),扫描被终止。大规模扫描请用 -gt 调大超时或设为 0 禁用"
|
||||||
flag_disable_ping:
|
flag_disable_ping:
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/shadow1ng/fscan/common"
|
"github.com/shadow1ng/fscan/common"
|
||||||
"github.com/shadow1ng/fscan/common/i18n"
|
"github.com/shadow1ng/fscan/common/i18n"
|
||||||
"github.com/shadow1ng/fscan/common/output"
|
"github.com/shadow1ng/fscan/common/output"
|
||||||
"github.com/shadow1ng/fscan/common/parsers"
|
|
||||||
"github.com/shadow1ng/fscan/plugins"
|
"github.com/shadow1ng/fscan/plugins"
|
||||||
"github.com/shadow1ng/fscan/webscan/lib"
|
"github.com/shadow1ng/fscan/webscan/lib"
|
||||||
)
|
)
|
||||||
@@ -97,15 +96,6 @@ func RunScan(ctx context.Context, info common.HostInfo, session *common.ScanSess
|
|||||||
start := time.Now()
|
start := time.Now()
|
||||||
config := session.Config
|
config := session.Config
|
||||||
|
|
||||||
// 全局超时自适应:用户未显式指定 -gt 时,根据扫描规模自动调大
|
|
||||||
if !config.GlobalTimeoutExplicit && config.GlobalTimeout > 0 {
|
|
||||||
if adjusted := estimateGlobalTimeout(config, session); adjusted > config.GlobalTimeout {
|
|
||||||
session.LogInfo(i18n.Tr("global_timeout_adjusted",
|
|
||||||
int(config.GlobalTimeout.Seconds()), int(adjusted.Seconds())))
|
|
||||||
config.GlobalTimeout = adjusted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 全局超时:-gt 参数设置整个扫描的硬性截止时间
|
// 全局超时:-gt 参数设置整个扫描的硬性截止时间
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
if config.GlobalTimeout > 0 {
|
if config.GlobalTimeout > 0 {
|
||||||
@@ -499,52 +489,3 @@ func addCommonDetails(result *plugins.Result, details map[string]interface{}) {
|
|||||||
details["server"] = result.Server
|
details["server"] = result.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func estimateGlobalTimeout(config *common.Config, session *common.ScanSession) time.Duration {
|
|
||||||
portCount := int64(len(parsers.ParsePort(config.Target.Ports)))
|
|
||||||
if portCount == 0 {
|
|
||||||
portCount = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
var hostFile string
|
|
||||||
var hostStr string
|
|
||||||
if session.Params != nil {
|
|
||||||
hostFile = session.Params.HostsFile
|
|
||||||
hostStr = session.Params.Host
|
|
||||||
}
|
|
||||||
hostCount := parsers.EstimateHostCount(hostStr, hostFile)
|
|
||||||
if hostCount <= 0 {
|
|
||||||
hostCount = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
totalTasks := hostCount * portCount
|
|
||||||
threads := int64(config.ThreadNum)
|
|
||||||
if threads <= 0 {
|
|
||||||
threads = 600
|
|
||||||
}
|
|
||||||
|
|
||||||
// 端口扫描:平均每个任务约 50ms(大部分连接快速失败)
|
|
||||||
portScanSec := float64(totalTasks) * 0.05 / float64(threads)
|
|
||||||
|
|
||||||
// 插件扫描:开放率随端口数下降(全端口约 0.1%,少量端口约 5%)
|
|
||||||
openRate := 0.05
|
|
||||||
if portCount > 1000 {
|
|
||||||
openRate = 0.002
|
|
||||||
} else if portCount > 100 {
|
|
||||||
openRate = 0.01
|
|
||||||
}
|
|
||||||
moduleThreads := float64(config.ModuleThreadNum)
|
|
||||||
if moduleThreads <= 0 {
|
|
||||||
moduleThreads = 20
|
|
||||||
}
|
|
||||||
pluginSec := float64(totalTasks) * openRate * 2.0 / moduleThreads
|
|
||||||
// 总估算 + 20% 余量
|
|
||||||
estimatedSec := (portScanSec + pluginSec) * 1.2
|
|
||||||
|
|
||||||
const maxTimeout = 2 * time.Hour
|
|
||||||
estimated := time.Duration(estimatedSec) * time.Second
|
|
||||||
if estimated > maxTimeout {
|
|
||||||
estimated = maxTimeout
|
|
||||||
}
|
|
||||||
return estimated
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ func buildFlagVars(config Config, target Target) *common.FlagVars {
|
|||||||
ThreadNum: threadNum,
|
ThreadNum: threadNum,
|
||||||
ModuleThreadNum: moduleThreads,
|
ModuleThreadNum: moduleThreads,
|
||||||
TimeoutSec: timeout,
|
TimeoutSec: timeout,
|
||||||
GlobalTimeout: 180,
|
GlobalTimeout: 0,
|
||||||
DisablePing: config.DisablePing,
|
DisablePing: config.DisablePing,
|
||||||
DisableTcpProbe: config.DisableTCPProbe,
|
DisableTcpProbe: config.DisableTCPProbe,
|
||||||
DisableSubnetProbe: config.DisableSubnetProbe,
|
DisableSubnetProbe: config.DisableSubnetProbe,
|
||||||
|
|||||||
@@ -667,6 +667,9 @@ func TestBuildFlagVarsCustomValues(t *testing.T) {
|
|||||||
if fv.TimeoutSec != 10 {
|
if fv.TimeoutSec != 10 {
|
||||||
t.Fatalf("TimeoutSec = %d, want 10", fv.TimeoutSec)
|
t.Fatalf("TimeoutSec = %d, want 10", fv.TimeoutSec)
|
||||||
}
|
}
|
||||||
|
if fv.GlobalTimeout != 0 {
|
||||||
|
t.Fatalf("GlobalTimeout = %d, want disabled", fv.GlobalTimeout)
|
||||||
|
}
|
||||||
if fv.WebTimeout != 15 {
|
if fv.WebTimeout != 15 {
|
||||||
t.Fatalf("WebTimeout = %d, want 15", fv.WebTimeout)
|
t.Fatalf("WebTimeout = %d, want 15", fv.WebTimeout)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user