refactor: 输出格式重构,重构SMB、SMB2、FTP的一些验证逻辑

This commit is contained in:
ZacharyZcR
2025-01-01 05:24:49 +08:00
parent d13e1952e9
commit 277ea5d332
47 changed files with 879 additions and 867 deletions
+61 -46
View File
@@ -1,6 +1,7 @@
package Plugins
import (
"context"
"fmt"
"github.com/jlaffaye/ftp"
"github.com/shadow1ng/fscan/Common"
@@ -17,8 +18,10 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
maxRetries := Common.MaxRetries
threads := Common.BruteThreads
successChan := make(chan struct{}, 1)
defer close(successChan)
// 创建带取消功能的context
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 先尝试匿名登录
for retryCount := 0; retryCount < maxRetries; retryCount++ {
@@ -26,7 +29,7 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
if flag && err == nil {
return nil
}
errlog := fmt.Sprintf("[-] ftp %v:%v %v %v", info.Host, info.Ports, "anonymous", err)
errlog := fmt.Sprintf("ftp %v:%v %v %v", info.Host, info.Ports, "anonymous", err)
Common.LogError(errlog)
if err != nil && !strings.Contains(err.Error(), "Login incorrect") {
@@ -40,36 +43,41 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
break
}
// 创建任务通道
taskChan := make(chan struct {
user string
pass string
}, len(Common.Userdict["ftp"])*len(Common.Passwords))
// 任务分发goroutine
go func() {
defer close(taskChan)
for _, user := range Common.Userdict["ftp"] {
for _, pass := range Common.Passwords {
select {
case <-ctx.Done():
return
default:
pass = strings.Replace(pass, "{user}", user, -1)
taskChan <- struct {
user string
pass string
}{user, pass}
}
}
}
}()
var wg sync.WaitGroup
resultChan := make(chan error, threads)
// 生成所有用户名密码组合任务
for _, user := range Common.Userdict["ftp"] {
for _, pass := range Common.Passwords {
pass = strings.Replace(pass, "{user}", user, -1)
taskChan <- struct {
user string
pass string
}{user, pass}
}
}
close(taskChan)
// 启动工作线程
var wg sync.WaitGroup
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for task := range taskChan {
// 检查是否已经成功
select {
case <-successChan:
case <-ctx.Done():
resultChan <- nil
return
default:
@@ -77,88 +85,95 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
// 重试循环
for retryCount := 0; retryCount < maxRetries; retryCount++ {
// 执行FTP连接
done := make(chan struct {
success bool
err error
})
}, 1)
connCtx, connCancel := context.WithTimeout(ctx, time.Duration(Common.Timeout)*time.Second)
go func(user, pass string) {
success, err := FtpConn(info, user, pass)
done <- struct {
select {
case <-connCtx.Done():
case done <- struct {
success bool
err error
}{success, err}
}{success, err}:
}
}(task.user, task.pass)
// 等待结果或超时
var err error
select {
case <-ctx.Done():
connCancel()
resultChan <- nil
return
case result := <-done:
err = result.err
if result.success && err == nil {
select {
case successChan <- struct{}{}:
successLog := fmt.Sprintf("[+] FTP %v:%v %v %v",
info.Host, info.Ports, task.user, task.pass)
Common.LogSuccess(successLog)
default:
}
successLog := fmt.Sprintf("FTP %v:%v %v %v",
info.Host, info.Ports, task.user, task.pass)
Common.LogSuccess(successLog)
time.Sleep(100 * time.Millisecond)
cancel() // 取消所有操作
resultChan <- nil
return
}
case <-time.After(time.Duration(Common.Timeout) * time.Second):
case <-connCtx.Done():
err = fmt.Errorf("连接超时")
}
// 处理错误情况
connCancel()
if err != nil {
errlog := fmt.Sprintf("[-] ftp %v:%v %v %v %v",
select {
case <-ctx.Done():
resultChan <- nil
return
default:
}
errlog := fmt.Sprintf("ftp %v:%v %v %v %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
// 对于登录失败的错误,直接继续下一个
if strings.Contains(err.Error(), "Login incorrect") {
break
}
// 特别处理连接数过多的情况
if strings.Contains(err.Error(), "too many connections") {
time.Sleep(5 * time.Second)
if retryCount < maxRetries-1 {
continue // 继续重试
continue
}
}
// 检查是否需要重试
if retryErr := Common.CheckErrs(err); retryErr != nil {
if retryCount == maxRetries-1 {
continue // 继续下一个密码,而不是返回
continue
}
continue // 继续重试
continue
}
}
break // 如果不需要重试,跳出重试循环
break
}
}
resultChan <- nil
}()
}
// 等待所有线程完成
go func() {
wg.Wait()
close(resultChan)
}()
// 检查结果
for err := range resultChan {
if err != nil {
tmperr = err
// 对于超时错误也继续执行
if !strings.Contains(err.Error(), "扫描超时") {
if retryErr := Common.CheckErrs(err); retryErr != nil {
continue // 继续尝试,而不是返回
continue
}
}
}
@@ -189,7 +204,7 @@ func FtpConn(info *Common.HostInfo, user string, pass string) (flag bool, err er
}
// 登录成功,获取目录信息
result := fmt.Sprintf("[+] ftp %v:%v:%v %v", Host, Port, Username, Password)
result := fmt.Sprintf("ftp %v:%v:%v %v", Host, Port, Username, Password)
dirs, err := conn.List("")
if err == nil && len(dirs) > 0 {
// 最多显示前6个目录