fix: set conn deadline in smtp testAnonymousAccess/testOpenRelay to avoid hang on silent servers - #608
Merged
Conversation
…void hang on silent servers testAnonymousAccess and testOpenRelay dial the target and immediately hand the connection to smtp.NewClient without setting any deadline. smtp.NewClient reads the 220 greeting as its first operation, so a server that accepts TCP but never sends data (honeypot/tarpit) blocks the goroutine forever. The outer select waits on resultChan or ctx.Done(); with the default -gt 0 the context has no deadline, so Scan never returns and RunScan's wg.Wait() freezes the whole process. Set the same ModuleTimeout deadline used by the other functions in this file (doSMTPAuth, testVRFYCommand, testEXPNCommand, getServerInfo). Verified against a live accept-but-silent SMTP endpoint: - unpatched: process hangs (31 goroutines, stack at smtp.go:276) - patched: full plugin chain completes in ~92s, no regression on normally-responding servers (detection output identical)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
现象
扫描包含 SMTP 服务(25/465/587/2525)的网段时,若目标服务器接受 TCP 连接但永不发送 220 banner
(蜜罐/tarpit/防反制设备常见行为),fscan 进程会永久假死:CPU 归零、日志停止输出、
连接停留在 ESTABLISHED,持续 1 小时以上不会自行退出,只能强杀。
根因
plugins/services/smtp.go中,testAnonymousAccess与testOpenRelay两个函数的goroutine 在
DialTCP之后未调用conn.SetDeadline就直接smtp.NewClient:smtp.NewClient第一步是读取服务器的220 greeting,该读没有超时 → goroutine 永久阻塞;select { case <-resultChan; case <-ctx.Done() }:默认-gt 0时 ctx 无 deadline,永远不会触发 →
Scan()永不返回;core.RunScan的wg.Wait()(core/scanner.go:129)永久等待,整个进程假死。同文件其余函数(
doSMTPAuth、testVRFYCommand、testEXPNCommand、getServerInfo)均已正确设置 deadline,仅这两处遗漏。默认参数(-gt 0)下必现。
修复(共 6 行,两个函数各 3 行)
在两处
DialTCP之后、smtp.NewClient之前,补上与其他函数一致的 deadline:
go _ = conn.SetDeadline(time.Now().Add(session.Config.ModuleTimeout())) 完整 diff:
```diff
--- a/plugins/services/smtp.go
+++ b/plugins/services/smtp.go
@@ -243,6 +243,9 @@ func (p *SMTPPlugin) testAnonymousAccess(...) {
}
defer func() { _ = conn.Close() }()
@@ -295,6 +298,9 @@ func (p *SMTPPlugin) testOpenRelay(...) {
}
defer func() { _ = conn.Close() }()
```
修复验证(同一 commit 源码树 A/B 构建,仅差这 6 行)
即:修复消除挂死,且对正常服务器的检测能力零回归。
复现步骤