mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-24 12:11:52 +08:00
refactor: 输出格式重构,去掉所有插件的多线程,因为多线程会导致结果不准确,加入进度条
This commit is contained in:
+41
-86
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,7 +15,6 @@ func ActiveMQScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 首先测试默认账户
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
@@ -35,103 +33,60 @@ func ActiveMQScan(info *Common.HostInfo) (tmperr error) {
|
||||
break
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["activemq"])*len(Common.Passwords))
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["activemq"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行连接测试
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行连接测试
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
flag, err := ActiveMQConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{flag, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
flag, err := ActiveMQConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{flag, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("ActiveMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("ActiveMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,7 +126,7 @@ func ActiveMQConn(info *Common.HostInfo, user string, pass string) (bool, error)
|
||||
response := string(respBuf[:n])
|
||||
|
||||
if strings.Contains(response, "CONNECTED") {
|
||||
result := fmt.Sprintf("[+] ActiveMQ服务 %v:%v 爆破成功 用户名: %v 密码: %v",
|
||||
result := fmt.Sprintf("ActiveMQ服务 %v:%v 爆破成功 用户名: %v 密码: %v",
|
||||
info.Host, info.Ports, user, pass)
|
||||
Common.LogSuccess(result)
|
||||
return true, nil
|
||||
|
||||
+42
-87
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,7 +15,6 @@ func CassandraScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 首先测试无认证访问
|
||||
@@ -34,103 +32,60 @@ func CassandraScan(info *Common.HostInfo) (tmperr error) {
|
||||
break
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["cassandra"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["cassandra"] {
|
||||
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 {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
// 执行连接
|
||||
done := make(chan struct {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := CassandraConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := CassandraConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Cassandra服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Cassandra服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -541,7 +541,7 @@ func (d *DomainInfo) GetSPNs() (map[string][]string, error) {
|
||||
_ = entry.GetAttributeValue("cn")
|
||||
spnList := entry.GetAttributeValues("servicePrincipalName")
|
||||
if len(spnList) > 0 {
|
||||
key := fmt.Sprintf("[*] SPN:%s", dn)
|
||||
key := fmt.Sprintf("SPN:%s", dn)
|
||||
spns[key] = spnList
|
||||
}
|
||||
}
|
||||
@@ -708,7 +708,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
|
||||
for _, category := range categories {
|
||||
if computers, ok := specialComputers[category]; ok {
|
||||
fmt.Printf("[*] %s:\n", category)
|
||||
fmt.Printf("%s:\n", category)
|
||||
for _, computer := range computers {
|
||||
fmt.Printf("\t%s\n", computer)
|
||||
}
|
||||
@@ -724,7 +724,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
}
|
||||
|
||||
// 打印用户信息
|
||||
fmt.Println("[*] 域用户:")
|
||||
fmt.Println("域用户:")
|
||||
for _, user := range users {
|
||||
fmt.Println("\t" + user)
|
||||
}
|
||||
@@ -737,7 +737,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
}
|
||||
|
||||
// 打印域管理员信息
|
||||
fmt.Println("[*] 域管理员:")
|
||||
fmt.Println("域管理员:")
|
||||
for _, admin := range admins {
|
||||
fmt.Println("\t" + admin)
|
||||
}
|
||||
@@ -750,7 +750,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
}
|
||||
|
||||
// 打印组织单位信息
|
||||
fmt.Println("[*] 组织单位:")
|
||||
fmt.Println("组织单位:")
|
||||
for _, ou := range ous {
|
||||
fmt.Println("\t" + ou)
|
||||
}
|
||||
@@ -763,7 +763,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
}
|
||||
|
||||
// 打印域计算机信息
|
||||
fmt.Println("[*] 域计算机:")
|
||||
fmt.Println("域计算机:")
|
||||
for _, computer := range computers {
|
||||
fmt.Printf("\t%s", computer.Name)
|
||||
if computer.OperatingSystem != "" {
|
||||
@@ -775,7 +775,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
// 获取并显示信任域关系
|
||||
trustDomains, err := di.GetTrustDomains()
|
||||
if err == nil {
|
||||
fmt.Println("[*] 信任域关系:")
|
||||
fmt.Println("信任域关系:")
|
||||
for _, domain := range trustDomains {
|
||||
fmt.Printf("\t%s\n", domain)
|
||||
}
|
||||
@@ -786,7 +786,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
adminGroups, err := di.GetAdminGroups()
|
||||
if err == nil {
|
||||
for groupName, members := range adminGroups {
|
||||
fmt.Printf("[*] %s成员:\n", groupName)
|
||||
fmt.Printf("%s成员:\n", groupName)
|
||||
for _, member := range members {
|
||||
fmt.Printf("\t%s\n", member)
|
||||
}
|
||||
@@ -798,7 +798,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
delegations, err := di.GetDelegation()
|
||||
if err == nil {
|
||||
for delegationType, entries := range delegations {
|
||||
fmt.Printf("[*] %s:\n", delegationType)
|
||||
fmt.Printf("%s:\n", delegationType)
|
||||
for _, entry := range entries {
|
||||
fmt.Printf("\t%s\n", entry)
|
||||
}
|
||||
@@ -809,7 +809,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
// 获取并显示AS-REP Roasting漏洞用户
|
||||
asrepUsers, err := di.GetAsrepRoastUsers()
|
||||
if err == nil {
|
||||
fmt.Println("[*] AS-REP弱口令账户:")
|
||||
fmt.Println("AS-REP弱口令账户:")
|
||||
for _, user := range asrepUsers {
|
||||
fmt.Printf("\t%s\n", user)
|
||||
}
|
||||
@@ -819,7 +819,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
// 获取并显示域密码策略
|
||||
passwordPolicy, err := di.GetPasswordPolicy()
|
||||
if err == nil {
|
||||
fmt.Println("[*] 域密码策略:")
|
||||
fmt.Println("域密码策略:")
|
||||
for key, value := range passwordPolicy {
|
||||
fmt.Printf("\t%s: %s\n", key, value)
|
||||
}
|
||||
@@ -843,7 +843,7 @@ func DCInfoScan(info *Common.HostInfo) (err error) {
|
||||
fmt.Println()
|
||||
}
|
||||
} else {
|
||||
fmt.Println("[*] 未发现SPN信息\n")
|
||||
fmt.Println("未发现SPN信息\n")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+42
-87
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -18,7 +17,6 @@ func ElasticScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 首先测试无认证访问
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
@@ -35,105 +33,62 @@ func ElasticScan(info *Common.HostInfo) (tmperr error) {
|
||||
break
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["elastic"])*len(Common.Passwords))
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["elastic"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行连接尝试
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行连接尝试
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
flag, err := ElasticConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{flag, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
flag, err := ElasticConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{flag, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Elasticsearch服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Elasticsearch服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+49
-139
@@ -1,12 +1,10 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/jlaffaye/ftp"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,11 +15,6 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 创建带取消功能的context
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// 先尝试匿名登录
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
@@ -29,152 +22,74 @@ 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") {
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["ftp"])*len(Common.Passwords))
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 任务分发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}
|
||||
}
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["ftp"] {
|
||||
for _, pass := range Common.Passwords {
|
||||
pass = strings.Replace(pass, "{user}", user, -1)
|
||||
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
resultChan := make(chan error, threads)
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行FTP连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 启动工作线程
|
||||
for i := 0; i < threads; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for task := range taskChan {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
resultChan <- nil
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := FtpConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}, 1)
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
connCtx, connCancel := context.WithTimeout(ctx, time.Duration(Common.Timeout)*time.Second)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := FtpConn(info, user, pass)
|
||||
select {
|
||||
case <-connCtx.Done():
|
||||
case done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{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 {
|
||||
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 <-connCtx.Done():
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
connCancel()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] ftp %v:%v %v %v %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
continue
|
||||
}
|
||||
continue
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
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
|
||||
}
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,12 +106,6 @@ func FtpConn(info *Common.HostInfo, user string, pass string) (flag bool, err er
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// 确保连接被关闭
|
||||
defer func() {
|
||||
if conn != nil {
|
||||
conn.Quit() // 发送QUIT命令关闭连接
|
||||
}
|
||||
}()
|
||||
|
||||
// 尝试登录
|
||||
if err = conn.Login(Username, Password); err != nil {
|
||||
@@ -204,7 +113,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个目录
|
||||
@@ -217,5 +126,6 @@ func FtpConn(info *Common.HostInfo, user string, pass string) (flag bool, err er
|
||||
}
|
||||
}
|
||||
|
||||
Common.LogSuccess(result)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
+6
-6
@@ -71,14 +71,14 @@ func FcgiScan(info *Common.HostInfo) error {
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
fmt.Printf("[-] FastCGI连接失败 %v:%v - %v\n", info.Host, info.Ports, err)
|
||||
fmt.Printf("FastCGI连接失败 %v:%v - %v\n", info.Host, info.Ports, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 发送FastCGI请求
|
||||
stdout, stderr, err := fcgi.Request(env, reqParams)
|
||||
if err != nil {
|
||||
fmt.Printf("[-] FastCGI请求失败 %v:%v - %v\n", info.Host, info.Ports, err)
|
||||
fmt.Printf("FastCGI请求失败 %v:%v - %v\n", info.Host, info.Ports, err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -90,10 +90,10 @@ func FcgiScan(info *Common.HostInfo) error {
|
||||
// 命令执行成功,提取输出结果
|
||||
output = strings.SplitN(output, cutLine, 2)[0]
|
||||
if len(stderr) > 0 {
|
||||
result = fmt.Sprintf("[+] FastCGI漏洞确认 %v:%v\n命令输出:\n%v\n错误信息:\n%v\n建议尝试其他路径,例如: -path /www/wwwroot/index.php",
|
||||
result = fmt.Sprintf("FastCGI漏洞确认 %v:%v\n命令输出:\n%v\n错误信息:\n%v\n建议尝试其他路径,例如: -path /www/wwwroot/index.php",
|
||||
info.Host, info.Ports, output, string(stderr))
|
||||
} else {
|
||||
result = fmt.Sprintf("[+] FastCGI漏洞确认 %v:%v\n命令输出:\n%v",
|
||||
result = fmt.Sprintf("FastCGI漏洞确认 %v:%v\n命令输出:\n%v",
|
||||
info.Host, info.Ports, output)
|
||||
}
|
||||
Common.LogSuccess(result)
|
||||
@@ -102,10 +102,10 @@ func FcgiScan(info *Common.HostInfo) error {
|
||||
strings.Contains(output, "Status") {
|
||||
// 目标存在FastCGI服务但可能路径错误
|
||||
if len(stderr) > 0 {
|
||||
result = fmt.Sprintf("[*] FastCGI服务确认 %v:%v\n响应:\n%v\n错误信息:\n%v\n建议尝试其他路径,例如: -path /www/wwwroot/index.php",
|
||||
result = fmt.Sprintf("FastCGI服务确认 %v:%v\n响应:\n%v\n错误信息:\n%v\n建议尝试其他路径,例如: -path /www/wwwroot/index.php",
|
||||
info.Host, info.Ports, output, string(stderr))
|
||||
} else {
|
||||
result = fmt.Sprintf("[*] FastCGI服务确认 %v:%v\n响应:\n%v",
|
||||
result = fmt.Sprintf("FastCGI服务确认 %v:%v\n响应:\n%v",
|
||||
info.Host, info.Ports, output)
|
||||
}
|
||||
Common.LogSuccess(result)
|
||||
|
||||
+4
-4
@@ -149,12 +149,12 @@ func read(text []byte, host string) error {
|
||||
}
|
||||
|
||||
// 构建基础结果
|
||||
result := fmt.Sprintf("[*] NetInfo 扫描结果")
|
||||
result += fmt.Sprintf("\n[*] 目标主机: %s", host)
|
||||
result := fmt.Sprintf("NetInfo 扫描结果")
|
||||
result += fmt.Sprintf("\n目标主机: %s", host)
|
||||
if name != "" {
|
||||
result += fmt.Sprintf("\n[*] 主机名: %s", name)
|
||||
result += fmt.Sprintf("\n主机名: %s", name)
|
||||
}
|
||||
result += "\n[*] 发现的网络接口:"
|
||||
result += "\n发现的网络接口:"
|
||||
|
||||
// 用于分类存储地址
|
||||
var ipv4Addrs []string
|
||||
|
||||
+41
-83
@@ -8,7 +8,6 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -18,102 +17,61 @@ func IMAPScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["imap"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["imap"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行IMAP连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行IMAP连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := IMAPConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := IMAPConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("IMAP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("IMAP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-88
@@ -5,18 +5,15 @@ import (
|
||||
"github.com/IBM/sarama"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// KafkaScan 执行 Kafka 服务扫描
|
||||
func KafkaScan(info *Common.HostInfo) (tmperr error) {
|
||||
if Common.DisableBrute {
|
||||
return
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 首先测试无认证访问
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
@@ -33,105 +30,62 @@ func KafkaScan(info *Common.HostInfo) (tmperr error) {
|
||||
break
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["kafka"])*len(Common.Passwords))
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["kafka"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行Kafka连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行Kafka连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := KafkaConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := KafkaConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Kafka服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Kafka服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-87
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,7 +15,6 @@ func LDAPScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 首先尝试匿名访问
|
||||
flag, err := LDAPConn(info, "", "")
|
||||
@@ -24,105 +22,62 @@ func LDAPScan(info *Common.HostInfo) (tmperr error) {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["ldap"])*len(Common.Passwords))
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["ldap"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行LDAP连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行LDAP连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := LDAPConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := LDAPConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("LDAP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("LDAP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,10 +89,10 @@ var (
|
||||
)
|
||||
|
||||
func LocalInfoScan(info *Common.HostInfo) (err error) {
|
||||
fmt.Println("[+] LocalInfo扫描模块开始...")
|
||||
fmt.Println("LocalInfo扫描模块开始...")
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] Get UserHomeDir error: %v", err)
|
||||
errlog := fmt.Sprintf("Get UserHomeDir error: %v", err)
|
||||
Common.LogError(errlog)
|
||||
return err
|
||||
}
|
||||
@@ -103,7 +103,7 @@ func LocalInfoScan(info *Common.HostInfo) (err error) {
|
||||
// 规则搜索
|
||||
searchSensitiveFiles()
|
||||
|
||||
fmt.Println("[+] LocalInfo扫描模块结束...")
|
||||
fmt.Println("LocalInfo扫描模块结束...")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ func scanFixedLocations(home string) {
|
||||
|
||||
func checkAndLogFile(path string) {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
result := fmt.Sprintf("[+] Found sensitive file: %s", path)
|
||||
result := fmt.Sprintf("Found sensitive file: %s", path)
|
||||
Common.LogSuccess(result)
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ func searchSensitiveFiles() {
|
||||
for _, white := range whitelist {
|
||||
fileName := strings.ToLower(info.Name())
|
||||
if strings.Contains(fileName, white) {
|
||||
result := fmt.Sprintf("[+] Found potential sensitive file: %s", path)
|
||||
result := fmt.Sprintf("Found potential sensitive file: %s", path)
|
||||
Common.LogSuccess(result)
|
||||
break
|
||||
}
|
||||
|
||||
+42
-85
@@ -6,7 +6,6 @@ import (
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,103 +16,61 @@ func MssqlScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["mssql"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["mssql"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行MSSQL连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行MSSQL连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := MssqlConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := MssqlConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("MSSQL %v:%v %v %v %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("MSSQL %v:%v %v %v %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +107,7 @@ func MssqlConn(info *Common.HostInfo, user string, pass string) (bool, error) {
|
||||
}
|
||||
|
||||
// 连接成功
|
||||
result := fmt.Sprintf("[+] MSSQL %v:%v:%v %v", host, port, username, password)
|
||||
result := fmt.Sprintf("MSSQL %v:%v:%v %v", host, port, username, password)
|
||||
Common.LogSuccess(result)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
+52
-113
@@ -6,7 +6,6 @@ import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,132 +16,72 @@ func MysqlScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 添加成功标志通道
|
||||
successChan := make(chan struct{}, 1)
|
||||
defer close(successChan)
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["mysql"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["mysql"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 检查是否已经成功
|
||||
select {
|
||||
case <-successChan:
|
||||
resultChan <- nil
|
||||
return
|
||||
default:
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行MySQL连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
|
||||
// 执行MySQL连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := MysqlConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := MysqlConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
// 连接成功
|
||||
select {
|
||||
case successChan <- struct{}{}: // 标记成功
|
||||
successLog := fmt.Sprintf("MySQL %v:%v %v %v",
|
||||
info.Host, info.Ports, task.user, task.pass)
|
||||
Common.LogSuccess(successLog)
|
||||
default:
|
||||
}
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("MySQL %v:%v %v %v %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 特殊处理认证失败的情况
|
||||
if strings.Contains(err.Error(), "Access denied") {
|
||||
break // 跳出重试循环,继续下一个密码
|
||||
}
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
// 连接成功
|
||||
successLog := fmt.Sprintf("MySQL %v:%v %v %v",
|
||||
info.Host, info.Ports, user, pass)
|
||||
Common.LogSuccess(successLog)
|
||||
return nil
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("MySQL %v:%v %v %v %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if !strings.Contains(err.Error(), "Access denied") {
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 特殊处理认证失败的情况
|
||||
if strings.Contains(err.Error(), "Access denied") {
|
||||
break // 跳出重试循环,继续下一个密码
|
||||
}
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
tmperr = err
|
||||
if !strings.Contains(err.Error(), "Access denied") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-87
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/neo4j/neo4j-go-driver/v4/neo4j"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,7 +15,6 @@ func Neo4jScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 首先测试无认证访问和默认凭证
|
||||
initialChecks := []struct {
|
||||
@@ -34,105 +32,62 @@ func Neo4jScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["neo4j"])*len(Common.Passwords))
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["neo4j"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行Neo4j连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行Neo4j连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
flag, err := Neo4jConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{flag, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
flag, err := Neo4jConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{flag, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Neo4j服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Neo4j服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -229,7 +229,7 @@ func (info *NetBiosInfo) String() (output string) {
|
||||
}
|
||||
if text == "" {
|
||||
} else if info.DomainControllers != "" {
|
||||
output = fmt.Sprintf("[+] DC:%-24s", text)
|
||||
output = fmt.Sprintf("DC:%-24s", text)
|
||||
} else {
|
||||
output = fmt.Sprintf("%-30s", text)
|
||||
}
|
||||
|
||||
+42
-88
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
_ "github.com/sijms/go-ora/v2"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,107 +16,62 @@ func OracleScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["oracle"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["oracle"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行Oracle连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行Oracle连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := OracleConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := OracleConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Oracle %v:%v %v %v %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Oracle %v:%v %v %v %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+46
-92
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,111 +16,66 @@ func POP3Scan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["pop3"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["pop3"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行POP3连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行POP3连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := POP3Conn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := POP3Conn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
// 连接成功
|
||||
successLog := fmt.Sprintf("POP3服务 %v:%v 用户名: %v 密码: %v",
|
||||
info.Host, info.Ports, task.user, task.pass)
|
||||
Common.LogSuccess(successLog)
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
// 连接成功
|
||||
successLog := fmt.Sprintf("POP3服务 %v:%v 用户名: %v 密码: %v",
|
||||
info.Host, info.Ports, user, pass)
|
||||
Common.LogSuccess(successLog)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("POP3服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("POP3服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-88
@@ -6,7 +6,6 @@ import (
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,107 +16,62 @@ func PostgresScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["postgresql"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["postgresql"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行PostgreSQL连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行PostgreSQL连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := PostgresConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := PostgresConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("PostgreSQL %v:%v %v %v %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("PostgreSQL %v:%v %v %v %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
-113
@@ -37,130 +37,40 @@ func RdpScan(info *Common.HostInfo) (tmperr error) {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
num = 0
|
||||
all = len(Common.Userdict["rdp"]) * len(Common.Passwords)
|
||||
mutex sync.Mutex
|
||||
)
|
||||
|
||||
// 创建任务通道和结果通道
|
||||
brlist := make(chan Brutelist)
|
||||
resultChan := make(chan bool)
|
||||
|
||||
port, _ := strconv.Atoi(info.Ports)
|
||||
total := len(Common.Userdict["rdp"]) * len(Common.Passwords)
|
||||
num := 0
|
||||
|
||||
// 启动工作协程
|
||||
for i := 0; i < Common.BruteThreads; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for one := range brlist {
|
||||
select {
|
||||
case <-resultChan: // 检查是否已经找到有效凭据
|
||||
return
|
||||
default:
|
||||
// 遍历用户名密码组合
|
||||
for _, user := range Common.Userdict["rdp"] {
|
||||
for _, pass := range Common.Passwords {
|
||||
num++
|
||||
pass = strings.Replace(pass, "{user}", user, -1)
|
||||
|
||||
// 尝试连接
|
||||
flag, err := RdpConn(info.Host, Common.Domain, user, pass, port, Common.Timeout)
|
||||
|
||||
if flag && err == nil {
|
||||
// 连接成功
|
||||
var result string
|
||||
if Common.Domain != "" {
|
||||
result = fmt.Sprintf("RDP %v:%v:%v\\%v %v", info.Host, port, Common.Domain, user, pass)
|
||||
} else {
|
||||
result = fmt.Sprintf("RDP %v:%v:%v %v", info.Host, port, user, pass)
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
num++
|
||||
mutex.Unlock()
|
||||
|
||||
user, pass := one.user, one.pass
|
||||
flag, err := RdpConn(info.Host, Common.Domain, user, pass, port, Common.Timeout)
|
||||
|
||||
if flag && err == nil {
|
||||
// 连接成功
|
||||
var result string
|
||||
if Common.Domain != "" {
|
||||
result = fmt.Sprintf("RDP %v:%v:%v\\%v %v", info.Host, port, Common.Domain, user, pass)
|
||||
} else {
|
||||
result = fmt.Sprintf("RDP %v:%v:%v %v", info.Host, port, user, pass)
|
||||
}
|
||||
Common.LogSuccess(result)
|
||||
select {
|
||||
case resultChan <- true: // 通知其他goroutine找到了有效凭据
|
||||
default:
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 连接失败
|
||||
errlog := fmt.Sprintf("(%v/%v) RDP %v:%v %v %v %v", num, all, info.Host, port, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
Common.LogSuccess(result)
|
||||
return nil
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 分发扫描任务
|
||||
go func() {
|
||||
for _, user := range Common.Userdict["rdp"] {
|
||||
for _, pass := range Common.Passwords {
|
||||
pass = strings.Replace(pass, "{user}", user, -1)
|
||||
select {
|
||||
case <-resultChan: // 如果已经找到有效凭据,停止分发任务
|
||||
return
|
||||
case brlist <- Brutelist{user, pass}:
|
||||
}
|
||||
}
|
||||
// 连接失败
|
||||
errlog := fmt.Sprintf("(%v/%v) RDP %v:%v %v %v %v", num, total, info.Host, port, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
}
|
||||
close(brlist)
|
||||
}()
|
||||
|
||||
// 等待任务完成或找到有效凭据
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
|
||||
// 等待结果
|
||||
if <-resultChan {
|
||||
return nil
|
||||
}
|
||||
|
||||
return tmperr
|
||||
}
|
||||
|
||||
// worker RDP扫描工作协程
|
||||
func worker(host, domain string, port int, wg *sync.WaitGroup, brlist chan Brutelist,
|
||||
signal *bool, num *int, all int, mutex *sync.Mutex, timeout int64) {
|
||||
defer wg.Done()
|
||||
|
||||
for one := range brlist {
|
||||
if *signal {
|
||||
return
|
||||
}
|
||||
go incrNum(num, mutex)
|
||||
|
||||
user, pass := one.user, one.pass
|
||||
flag, err := RdpConn(host, domain, user, pass, port, timeout)
|
||||
|
||||
if flag && err == nil {
|
||||
// 连接成功
|
||||
var result string
|
||||
if domain != "" {
|
||||
result = fmt.Sprintf("RDP %v:%v:%v\\%v %v", host, port, domain, user, pass)
|
||||
} else {
|
||||
result = fmt.Sprintf("RDP %v:%v:%v %v", host, port, user, pass)
|
||||
}
|
||||
Common.LogSuccess(result)
|
||||
*signal = true
|
||||
return
|
||||
}
|
||||
|
||||
// 连接失败
|
||||
errlog := fmt.Sprintf("(%v/%v) RDP %v:%v %v %v %v", *num, all, host, port, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
}
|
||||
}
|
||||
|
||||
// incrNum 线程安全地增加计数器
|
||||
func incrNum(num *int, mutex *sync.Mutex) {
|
||||
mutex.Lock()
|
||||
*num++
|
||||
mutex.Unlock()
|
||||
}
|
||||
|
||||
// RdpConn 尝试RDP连接
|
||||
func RdpConn(ip, domain, user, password string, port int, timeout int64) (bool, error) {
|
||||
defer func() {
|
||||
|
||||
+91
-94
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,116 +16,114 @@ func RabbitMQScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["rabbitmq"])*len(Common.Passwords)+1) // +1 是为了加入guest账号
|
||||
// 先测试默认账号 guest/guest
|
||||
user, pass := "guest", "guest"
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
// 执行RabbitMQ连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 先加入默认账号guest/guest
|
||||
taskChan <- struct {
|
||||
user string
|
||||
pass string
|
||||
}{"guest", "guest"}
|
||||
go func() {
|
||||
success, err := RabbitMQConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}()
|
||||
|
||||
// 生成其他用户名密码组合任务
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
result := fmt.Sprintf("RabbitMQ服务 %v:%v 连接成功 用户名: %v 密码: %v",
|
||||
info.Host, info.Ports, user, pass)
|
||||
Common.LogSuccess(result)
|
||||
return nil
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("RabbitMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// 遍历其他用户名密码组合
|
||||
for _, user := range Common.Userdict["rabbitmq"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行RabbitMQ连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行RabbitMQ连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
success, err := RabbitMQConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := RabbitMQConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
result := fmt.Sprintf("RabbitMQ服务 %v:%v 连接成功 用户名: %v 密码: %v",
|
||||
info.Host, info.Ports, task.user, task.pass)
|
||||
Common.LogSuccess(result)
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
result := fmt.Sprintf("RabbitMQ服务 %v:%v 连接成功 用户名: %v 密码: %v",
|
||||
info.Host, info.Ports, user, pass)
|
||||
Common.LogSuccess(result)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("RabbitMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("RabbitMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -489,10 +489,10 @@ func readreply(conn net.Conn) (string, error) {
|
||||
|
||||
// testwrite 测试Redis写入权限
|
||||
func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
||||
fmt.Println("[*] 开始测试Redis写入权限...")
|
||||
fmt.Println("开始测试Redis写入权限...")
|
||||
|
||||
// 测试SSH目录写入权限
|
||||
fmt.Println("[*] 正在测试 /root/.ssh/ 目录写入权限...")
|
||||
fmt.Println("正在测试 /root/.ssh/ 目录写入权限...")
|
||||
_, err = conn.Write([]byte("CONFIG SET dir /root/.ssh/\r\n"))
|
||||
if err != nil {
|
||||
fmt.Printf("发送SSH目录测试命令失败: %v\n", err)
|
||||
@@ -503,7 +503,7 @@ func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
||||
fmt.Printf("读取SSH目录测试响应失败: %v\n", err)
|
||||
return flag, flagCron, err
|
||||
}
|
||||
fmt.Printf("[*] SSH目录测试响应: %s\n", text)
|
||||
fmt.Printf("SSH目录测试响应: %s\n", text)
|
||||
if strings.Contains(text, "OK") {
|
||||
flag = true
|
||||
fmt.Println("SSH目录写入权限测试成功")
|
||||
@@ -512,7 +512,7 @@ func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
||||
}
|
||||
|
||||
// 测试定时任务目录写入权限
|
||||
fmt.Println("[*] 正在测试 /var/spool/cron/ 目录写入权限...")
|
||||
fmt.Println("正在测试 /var/spool/cron/ 目录写入权限...")
|
||||
_, err = conn.Write([]byte("CONFIG SET dir /var/spool/cron/\r\n"))
|
||||
if err != nil {
|
||||
fmt.Printf("发送定时任务目录测试命令失败: %v\n", err)
|
||||
@@ -523,7 +523,7 @@ func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
||||
fmt.Printf("读取定时任务目录测试响应失败: %v\n", err)
|
||||
return flag, flagCron, err
|
||||
}
|
||||
fmt.Printf("[*] 定时任务目录测试响应: %s\n", text)
|
||||
fmt.Printf("定时任务目录测试响应: %s\n", text)
|
||||
if strings.Contains(text, "OK") {
|
||||
flagCron = true
|
||||
fmt.Println("定时任务目录写入权限测试成功")
|
||||
@@ -531,7 +531,7 @@ func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
||||
fmt.Println("定时任务目录写入权限测试失败")
|
||||
}
|
||||
|
||||
fmt.Printf("[*] 写入权限测试完成 - SSH权限: %v, Cron权限: %v\n", flag, flagCron)
|
||||
fmt.Printf("写入权限测试完成 - SSH权限: %v, Cron权限: %v\n", flag, flagCron)
|
||||
return flag, flagCron, err
|
||||
}
|
||||
|
||||
|
||||
+42
-87
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,7 +15,6 @@ func RsyncScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 首先测试匿名访问
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
@@ -36,105 +34,62 @@ func RsyncScan(info *Common.HostInfo) (tmperr error) {
|
||||
break
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["rsync"])*len(Common.Passwords))
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["rsync"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行Rsync连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行Rsync连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
flag, err := RsyncConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{flag && err == nil, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
flag, err := RsyncConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{flag && err == nil, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Rsync服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Rsync服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
-68
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"github.com/stacktitan/smb/smb"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -14,83 +13,39 @@ func SmbScan(info *Common.HostInfo) (tmperr error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
threads := Common.BruteThreads
|
||||
var wg sync.WaitGroup
|
||||
successChan := make(chan struct{}, 1)
|
||||
|
||||
// 按用户分组处理
|
||||
// 遍历所有用户
|
||||
for _, user := range Common.Userdict["smb"] {
|
||||
taskChan := make(chan string, len(Common.Passwords))
|
||||
|
||||
// 遍历该用户的所有密码
|
||||
for _, pass := range Common.Passwords {
|
||||
pass = strings.Replace(pass, "{user}", user, -1)
|
||||
taskChan <- pass
|
||||
}
|
||||
close(taskChan)
|
||||
|
||||
for i := 0; i < threads; i++ {
|
||||
wg.Add(1)
|
||||
go func(username string) {
|
||||
defer wg.Done()
|
||||
for pass := range taskChan {
|
||||
select {
|
||||
case <-successChan:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
success, err := doWithTimeOut(info, username, pass)
|
||||
if success {
|
||||
if Common.Domain != "" {
|
||||
Common.LogSuccess(fmt.Sprintf("SMB认证成功 %s:%s %s\\%s:%s",
|
||||
info.Host, info.Ports, Common.Domain, username, pass))
|
||||
} else {
|
||||
Common.LogSuccess(fmt.Sprintf("SMB认证成功 %s:%s %s:%s",
|
||||
info.Host, info.Ports, username, pass))
|
||||
}
|
||||
successChan <- struct{}{}
|
||||
|
||||
// 成功后等待确保日志打印完成
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
Common.LogError(fmt.Sprintf("SMB认证失败 %s:%s %s:%s %v",
|
||||
info.Host, info.Ports, username, pass, err))
|
||||
|
||||
// 等待失败日志打印完成
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if strings.Contains(err.Error(), "账号锁定") {
|
||||
for range taskChan {
|
||||
// 清空通道
|
||||
}
|
||||
time.Sleep(200 * time.Millisecond) // 确保锁定日志打印完成
|
||||
return
|
||||
}
|
||||
}
|
||||
success, err := doWithTimeOut(info, user, pass)
|
||||
if success {
|
||||
if Common.Domain != "" {
|
||||
Common.LogSuccess(fmt.Sprintf("SMB认证成功 %s:%s %s\\%s:%s",
|
||||
info.Host, info.Ports, Common.Domain, user, pass))
|
||||
} else {
|
||||
Common.LogSuccess(fmt.Sprintf("SMB认证成功 %s:%s %s:%s",
|
||||
info.Host, info.Ports, user, pass))
|
||||
}
|
||||
}(user)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
if err != nil {
|
||||
Common.LogError(fmt.Sprintf("SMB认证失败 %s:%s %s:%s %v",
|
||||
info.Host, info.Ports, user, pass, err))
|
||||
|
||||
select {
|
||||
case <-successChan:
|
||||
// 等待日志打印完成
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
Common.LogWG.Wait()
|
||||
return nil
|
||||
default:
|
||||
// 等待失败日志打印完成
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if strings.Contains(err.Error(), "账号锁定") {
|
||||
// 账号锁定时跳过当前用户的剩余密码
|
||||
break // 跳出密码循环,继续下一个用户
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 主函数结束前多等待一会
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
Common.LogWG.Wait()
|
||||
// 最后再等待一下,确保所有日志都打印完成
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+64
-161
@@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hirochachacha/go-smb2"
|
||||
@@ -27,110 +26,59 @@ func SmbScan2(info *Common.HostInfo) (tmperr error) {
|
||||
return smbPasswordScan(info)
|
||||
}
|
||||
|
||||
// smbPasswordScan 使用密码进行认证扫描
|
||||
func smbPasswordScan(info *Common.HostInfo) error {
|
||||
if Common.DisableBrute {
|
||||
return nil
|
||||
}
|
||||
|
||||
threads := Common.BruteThreads
|
||||
|
||||
var wg sync.WaitGroup
|
||||
successChan := make(chan struct{}, 1)
|
||||
hasprint := false
|
||||
var hasPrintMutex sync.Mutex
|
||||
|
||||
// 改成按用户分组处理
|
||||
// 遍历每个用户
|
||||
for _, user := range Common.Userdict["smb"] {
|
||||
// 为每个用户创建密码任务通道
|
||||
taskChan := make(chan string, len(Common.Passwords))
|
||||
|
||||
// 生成该用户的所有密码任务
|
||||
// 遍历该用户的所有密码
|
||||
for _, pass := range Common.Passwords {
|
||||
pass = strings.ReplaceAll(pass, "{user}", user)
|
||||
taskChan <- pass
|
||||
}
|
||||
close(taskChan)
|
||||
|
||||
// 启动工作线程
|
||||
for i := 0; i < threads; i++ {
|
||||
wg.Add(1)
|
||||
go func(username string) {
|
||||
defer wg.Done()
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < Common.MaxRetries; retryCount++ {
|
||||
success, err, printed := Smb2Con(info, user, pass, []byte{}, hasprint)
|
||||
|
||||
for pass := range taskChan {
|
||||
select {
|
||||
case <-successChan:
|
||||
return
|
||||
default:
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
if printed {
|
||||
hasprint = true
|
||||
}
|
||||
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < Common.MaxRetries; retryCount++ {
|
||||
hasPrintMutex.Lock()
|
||||
currentHasPrint := hasprint
|
||||
hasPrintMutex.Unlock()
|
||||
if success {
|
||||
logSuccessfulAuth(info, user, pass, []byte{})
|
||||
return nil
|
||||
}
|
||||
|
||||
success, err, printed := Smb2Con(info, username, pass, []byte{}, currentHasPrint)
|
||||
if err != nil {
|
||||
logFailedAuth(info, user, pass, []byte{}, err)
|
||||
|
||||
if printed {
|
||||
hasPrintMutex.Lock()
|
||||
hasprint = true
|
||||
hasPrintMutex.Unlock()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
if success {
|
||||
logSuccessfulAuth(info, username, pass, []byte{})
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
successChan <- struct{}{}
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logFailedAuth(info, username, pass, []byte{}, err)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// 检查是否账户锁定
|
||||
if strings.Contains(err.Error(), "user account has been automatically locked") {
|
||||
// 发现账户锁定,清空任务通道并返回
|
||||
for range taskChan {
|
||||
// 清空通道
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 其他登录失败情况
|
||||
if strings.Contains(err.Error(), "LOGIN_FAILED") ||
|
||||
strings.Contains(err.Error(), "Authentication failed") ||
|
||||
strings.Contains(err.Error(), "attempted logon is invalid") ||
|
||||
strings.Contains(err.Error(), "bad username or authentication") {
|
||||
break
|
||||
}
|
||||
|
||||
if retryCount < Common.MaxRetries-1 {
|
||||
time.Sleep(time.Second * time.Duration(retryCount+2))
|
||||
continue
|
||||
}
|
||||
}
|
||||
// 检查是否账户锁定
|
||||
if strings.Contains(err.Error(), "user account has been automatically locked") {
|
||||
// 账户锁定,跳过该用户的剩余密码
|
||||
break
|
||||
}
|
||||
|
||||
// 其他登录失败情况
|
||||
if strings.Contains(err.Error(), "LOGIN_FAILED") ||
|
||||
strings.Contains(err.Error(), "Authentication failed") ||
|
||||
strings.Contains(err.Error(), "attempted logon is invalid") ||
|
||||
strings.Contains(err.Error(), "bad username or authentication") {
|
||||
break
|
||||
}
|
||||
|
||||
if retryCount < Common.MaxRetries-1 {
|
||||
time.Sleep(time.Second * time.Duration(retryCount+2))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}(user)
|
||||
}
|
||||
|
||||
wg.Wait() // 等待当前用户的所有密码尝试完成
|
||||
|
||||
// 检查是否已经找到正确密码
|
||||
select {
|
||||
case <-successChan:
|
||||
return nil
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -139,94 +87,49 @@ func smbHashScan(info *Common.HostInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
threads := Common.BruteThreads
|
||||
var wg sync.WaitGroup
|
||||
successChan := make(chan struct{}, 1)
|
||||
hasprint := false
|
||||
var hasPrintMutex sync.Mutex
|
||||
|
||||
// 按用户分组处理
|
||||
// 遍历每个用户
|
||||
for _, user := range Common.Userdict["smb"] {
|
||||
// 为每个用户创建hash任务通道
|
||||
taskChan := make(chan []byte, len(Common.HashBytes))
|
||||
|
||||
// 生成该用户的所有hash任务
|
||||
// 遍历该用户的所有hash
|
||||
for _, hash := range Common.HashBytes {
|
||||
taskChan <- hash
|
||||
}
|
||||
close(taskChan)
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < Common.MaxRetries; retryCount++ {
|
||||
success, err, printed := Smb2Con(info, user, "", hash, hasprint)
|
||||
|
||||
// 启动工作线程
|
||||
for i := 0; i < threads; i++ {
|
||||
wg.Add(1)
|
||||
go func(username string) {
|
||||
defer wg.Done()
|
||||
if printed {
|
||||
hasprint = true
|
||||
}
|
||||
|
||||
for hash := range taskChan {
|
||||
select {
|
||||
case <-successChan:
|
||||
return
|
||||
default:
|
||||
}
|
||||
if success {
|
||||
logSuccessfulAuth(info, user, "", hash)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < Common.MaxRetries; retryCount++ {
|
||||
hasPrintMutex.Lock()
|
||||
currentHasPrint := hasprint
|
||||
hasPrintMutex.Unlock()
|
||||
if err != nil {
|
||||
logFailedAuth(info, user, "", hash, err)
|
||||
|
||||
success, err, printed := Smb2Con(info, username, "", hash, currentHasPrint)
|
||||
|
||||
if printed {
|
||||
hasPrintMutex.Lock()
|
||||
hasprint = true
|
||||
hasPrintMutex.Unlock()
|
||||
}
|
||||
|
||||
if success {
|
||||
logSuccessfulAuth(info, username, "", hash)
|
||||
successChan <- struct{}{}
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logFailedAuth(info, username, "", hash, err)
|
||||
|
||||
// 检查是否账户锁定
|
||||
if strings.Contains(err.Error(), "user account has been automatically locked") {
|
||||
// 发现账户锁定,清空任务通道并返回
|
||||
for range taskChan {
|
||||
// 清空通道
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 其他登录失败情况
|
||||
if strings.Contains(err.Error(), "LOGIN_FAILED") ||
|
||||
strings.Contains(err.Error(), "Authentication failed") ||
|
||||
strings.Contains(err.Error(), "attempted logon is invalid") ||
|
||||
strings.Contains(err.Error(), "bad username or authentication") {
|
||||
break
|
||||
}
|
||||
|
||||
if retryCount < Common.MaxRetries-1 {
|
||||
time.Sleep(time.Second * time.Duration(retryCount+1))
|
||||
continue
|
||||
}
|
||||
}
|
||||
// 检查是否账户锁定
|
||||
if strings.Contains(err.Error(), "user account has been automatically locked") {
|
||||
// 账户锁定,跳过该用户的剩余hash
|
||||
break
|
||||
}
|
||||
|
||||
// 其他登录失败情况
|
||||
if strings.Contains(err.Error(), "LOGIN_FAILED") ||
|
||||
strings.Contains(err.Error(), "Authentication failed") ||
|
||||
strings.Contains(err.Error(), "attempted logon is invalid") ||
|
||||
strings.Contains(err.Error(), "bad username or authentication") {
|
||||
break
|
||||
}
|
||||
|
||||
if retryCount < Common.MaxRetries-1 {
|
||||
time.Sleep(time.Second * time.Duration(retryCount+1))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}(user)
|
||||
}
|
||||
|
||||
wg.Wait() // 等待当前用户的所有hash尝试完成
|
||||
|
||||
// 检查是否已经找到正确凭据
|
||||
select {
|
||||
case <-successChan:
|
||||
return nil
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+42
-87
@@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,7 +16,6 @@ func SmtpScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 先测试匿名访问
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
@@ -36,105 +34,62 @@ func SmtpScan(info *Common.HostInfo) (tmperr error) {
|
||||
break
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["smtp"])*len(Common.Passwords))
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["smtp"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行SMTP连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行SMTP连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
flag, err := SmtpConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
}{flag, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
flag, err := SmtpConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{flag, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("SMTP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("SMTP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+50
-91
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,106 +16,66 @@ func SNMPScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
portNum, _ := strconv.Atoi(info.Ports)
|
||||
defaultCommunities := []string{"public", "private", "cisco", "community"}
|
||||
starttime := time.Now().Unix()
|
||||
timeout := time.Duration(Common.Timeout) * time.Second
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan string, len(defaultCommunities))
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有community任务
|
||||
// 遍历所有 community
|
||||
for _, community := range defaultCommunities {
|
||||
taskChan <- community
|
||||
}
|
||||
close(taskChan)
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(timeout.Seconds()) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
// 启动工作线程
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < threads; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
starttime := time.Now().Unix()
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行SNMP连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
for community := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
timeout := time.Duration(Common.Timeout) * time.Second
|
||||
if time.Now().Unix()-starttime > int64(timeout.Seconds()) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
go func(community string) {
|
||||
success, err := SNMPConnect(info, community, portNum)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(community)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
// 连接成功
|
||||
successLog := fmt.Sprintf("SNMP服务 %v:%v community: %v 连接成功",
|
||||
info.Host, info.Ports, community)
|
||||
Common.LogSuccess(successLog)
|
||||
return nil
|
||||
}
|
||||
case <-time.After(timeout):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("SNMP服务 %v:%v 尝试失败 community: %v 错误: %v",
|
||||
info.Host, info.Ports, community, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
|
||||
// 执行SNMP连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func(community string) {
|
||||
success, err := SNMPConnect(info, community, portNum)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(community)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
// 连接成功
|
||||
successLog := fmt.Sprintf("SNMP服务 %v:%v community: %v 连接成功",
|
||||
info.Host, info.Ports, community)
|
||||
Common.LogSuccess(successLog)
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(timeout):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("SNMP服务 %v:%v 尝试失败 community: %v 错误: %v",
|
||||
info.Host, info.Ports, community, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
}
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
-98
@@ -1,13 +1,13 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,97 +17,67 @@ func SshScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["ssh"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["ssh"] {
|
||||
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 {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
done := make(chan struct {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(Common.Timeout)*time.Second)
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
}, 1)
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := SshConn(info, user, pass)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case done <- struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := SshConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}{success, err}:
|
||||
}
|
||||
}(user, pass)
|
||||
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("SSH认证失败 %v:%v User:%v Pass:%v Err:%v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否是已知错误,如果是则等待3秒后重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success {
|
||||
successLog := fmt.Sprintf("SSH认证成功 %v:%v User:%v Pass:%v",
|
||||
info.Host, info.Ports, user, pass)
|
||||
Common.LogSuccess(successLog)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
cancel()
|
||||
return nil
|
||||
}
|
||||
|
||||
if Common.SshKeyPath != "" {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-ctx.Done():
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
cancel()
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("SSH认证失败 %v:%v User:%v Pass:%v Err:%v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if Common.SshKeyPath != "" {
|
||||
return err
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,29 +123,13 @@ func SshConn(info *Common.HostInfo, user string, pass string) (flag bool, err er
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
flag = true
|
||||
|
||||
// 如果需要执行命令
|
||||
if Common.Command != "" {
|
||||
output, err := session.CombinedOutput(Common.Command)
|
||||
_, err := session.CombinedOutput(Common.Command)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
if Common.SshKeyPath != "" {
|
||||
Common.LogSuccess(fmt.Sprintf("SSH密钥认证成功 %v:%v\n命令输出:\n%v",
|
||||
info.Host, info.Ports, string(output)))
|
||||
} else {
|
||||
Common.LogSuccess(fmt.Sprintf("SSH认证成功 %v:%v User:%v Pass:%v\n命令输出:\n%v",
|
||||
info.Host, info.Ports, user, pass, string(output)))
|
||||
}
|
||||
} else {
|
||||
if Common.SshKeyPath != "" {
|
||||
Common.LogSuccess(fmt.Sprintf("SSH密钥认证成功 %v:%v",
|
||||
info.Host, info.Ports))
|
||||
} else {
|
||||
Common.LogSuccess(fmt.Sprintf("SSH认证成功 %v:%v User:%v Pass:%v",
|
||||
info.Host, info.Ports, user, pass))
|
||||
}
|
||||
}
|
||||
|
||||
return flag, nil
|
||||
return true, nil
|
||||
}
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ func SmbGhostScan(info *Common.HostInfo) error {
|
||||
bytes.Equal(buff[74:76], []byte{0x02, 0x00}) {
|
||||
|
||||
// 发现漏洞,记录结果
|
||||
result := fmt.Sprintf("[+] %v CVE-2020-0796 SmbGhost Vulnerable", ip)
|
||||
result := fmt.Sprintf("%v CVE-2020-0796 SmbGhost Vulnerable", ip)
|
||||
Common.LogSuccess(result)
|
||||
}
|
||||
|
||||
|
||||
+53
-100
@@ -8,7 +8,6 @@ import (
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -19,120 +18,74 @@ func TelnetScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["telnet"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["telnet"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行Telnet连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
noAuth bool
|
||||
err error
|
||||
})
|
||||
|
||||
// 执行Telnet连接
|
||||
done := make(chan struct {
|
||||
go func(user, pass string) {
|
||||
flag, err := telnetConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
noAuth bool
|
||||
err error
|
||||
})
|
||||
}{err == nil, flag, err}
|
||||
}(user, pass)
|
||||
|
||||
go func(user, pass string) {
|
||||
flag, err := telnetConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
noAuth bool
|
||||
err error
|
||||
}{err == nil, flag, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.noAuth {
|
||||
// 无需认证
|
||||
result := fmt.Sprintf("Telnet服务 %v:%v 无需认证",
|
||||
info.Host, info.Ports)
|
||||
Common.LogSuccess(result)
|
||||
resultChan <- nil
|
||||
return
|
||||
} else if result.success {
|
||||
// 成功爆破
|
||||
result := fmt.Sprintf("Telnet服务 %v:%v 用户名:%v 密码:%v",
|
||||
info.Host, info.Ports, task.user, task.pass)
|
||||
Common.LogSuccess(result)
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.noAuth {
|
||||
// 无需认证
|
||||
result := fmt.Sprintf("Telnet服务 %v:%v 无需认证",
|
||||
info.Host, info.Ports)
|
||||
Common.LogSuccess(result)
|
||||
return nil
|
||||
} else if result.success {
|
||||
// 成功爆破
|
||||
result := fmt.Sprintf("Telnet服务 %v:%v 用户名:%v 密码:%v",
|
||||
info.Host, info.Ports, user, pass)
|
||||
Common.LogSuccess(result)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Telnet连接失败 %v:%v 用户名:%v 密码:%v 错误:%v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("Telnet连接失败 %v:%v 用户名:%v 密码:%v 错误:%v",
|
||||
info.Host, info.Ports, user, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TomcatScan 执行 Tomcat Manager 服务扫描
|
||||
func TomcatScan(info *Common.HostInfo) (tmperr error) {
|
||||
if Common.DisableBrute {
|
||||
return
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["tomcat"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
for _, user := range Common.Userdict["tomcat"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
|
||||
// 执行Tomcat连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := TomcatConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] Tomcat Manager %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmperr
|
||||
}
|
||||
|
||||
// TomcatConn 尝试 Tomcat Manager 连接
|
||||
func TomcatConn(info *Common.HostInfo, user string, pass string) (bool, error) {
|
||||
host, port := info.Host, info.Ports
|
||||
timeout := time.Duration(Common.Timeout) * time.Second
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: timeout,
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
}
|
||||
|
||||
// 尝试不同的管理路径
|
||||
paths := []string{
|
||||
"/manager/html",
|
||||
"/manager/status",
|
||||
"/manager/text",
|
||||
"/host-manager/html",
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
baseURL := fmt.Sprintf("http://%s:%s%s", host, port, path)
|
||||
|
||||
req, err := http.NewRequest("GET", baseURL, nil)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// 添加Basic认证
|
||||
auth := base64.StdEncoding.EncodeToString([]byte(user + ":" + pass))
|
||||
req.Header.Add("Authorization", "Basic "+auth)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 检查响应状态
|
||||
if resp.StatusCode == 200 {
|
||||
result := fmt.Sprintf("[+] Tomcat Manager %v:%v %s 爆破成功 用户名: %v 密码: %v",
|
||||
host, port, path, user, pass)
|
||||
Common.LogSuccess(result)
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("认证失败")
|
||||
}
|
||||
+49
-89
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/mitchellh/go-vnc"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,103 +15,64 @@ func VncScan(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
modename := "vnc"
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan string, len(Common.Passwords))
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有密码任务
|
||||
// 遍历所有密码
|
||||
for _, pass := range Common.Passwords {
|
||||
taskChan <- pass
|
||||
}
|
||||
close(taskChan)
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
// 启动工作线程
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < threads; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
starttime := time.Now().Unix()
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行VNC连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
for pass := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
go func(pass string) {
|
||||
success, err := VncConn(info, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
// 连接成功
|
||||
successLog := fmt.Sprintf("%s://%v:%v 密码: %v",
|
||||
modename, info.Host, info.Ports, pass)
|
||||
Common.LogSuccess(successLog)
|
||||
return nil
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("%s://%v:%v 尝试密码: %v 错误: %v",
|
||||
modename, info.Host, info.Ports, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否是需要重试的错误
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
|
||||
// 执行VNC连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func(pass string) {
|
||||
success, err := VncConn(info, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
// 连接成功
|
||||
successLog := fmt.Sprintf("%s://%v:%v 密码: %v",
|
||||
modename, info.Host, info.Ports, pass)
|
||||
Common.LogSuccess(successLog)
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("%s://%v:%v 尝试密码: %v 错误: %v",
|
||||
modename, info.Host, info.Ports, pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否是需要重试的错误
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
}
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+71
-115
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -34,130 +33,87 @@ func WmiExec(info *Common.HostInfo) (tmperr error) {
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["smb"])*len(Common.Passwords))
|
||||
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
// 遍历所有用户名密码组合
|
||||
for _, user := range Common.Userdict["smb"] {
|
||||
for _, pass := range Common.Passwords {
|
||||
pass = strings.Replace(pass, "{user}", user, -1)
|
||||
taskChan <- struct {
|
||||
user string
|
||||
pass string
|
||||
}{user, pass}
|
||||
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
return fmt.Errorf("扫描超时")
|
||||
}
|
||||
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 执行WMI连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := Wmiexec(info, user, pass, Common.HashValue)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(user, pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success {
|
||||
// 成功连接
|
||||
var successLog string
|
||||
if Common.Domain != "" {
|
||||
successLog = fmt.Sprintf("WmiExec %v:%v:%v\\%v ",
|
||||
info.Host, info.Ports, Common.Domain, user)
|
||||
} else {
|
||||
successLog = fmt.Sprintf("WmiExec %v:%v:%v ",
|
||||
info.Host, info.Ports, user)
|
||||
}
|
||||
|
||||
if Common.HashValue != "" {
|
||||
successLog += "hash: " + Common.HashValue
|
||||
} else {
|
||||
successLog += pass
|
||||
}
|
||||
Common.LogSuccess(successLog)
|
||||
return nil
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("WmiExec %v:%v %v %v %v",
|
||||
info.Host, 445, user, pass, err)
|
||||
errlog = strings.Replace(errlog, "\n", "", -1)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
return err
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
|
||||
// 如果是32位hash值,只尝试一次密码
|
||||
if len(Common.HashValue) == 32 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
close(taskChan)
|
||||
|
||||
// 启动工作线程
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < threads; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
|
||||
// 执行WMI连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := Wmiexec(info, user, pass, Common.HashValue)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success {
|
||||
// 成功连接
|
||||
var successLog string
|
||||
if Common.Domain != "" {
|
||||
successLog = fmt.Sprintf("[+] WmiExec %v:%v:%v\\%v ",
|
||||
info.Host, info.Ports, Common.Domain, task.user)
|
||||
} else {
|
||||
successLog = fmt.Sprintf("[+] WmiExec %v:%v:%v ",
|
||||
info.Host, info.Ports, task.user)
|
||||
}
|
||||
|
||||
if Common.HashValue != "" {
|
||||
successLog += "hash: " + Common.HashValue
|
||||
} else {
|
||||
successLog += task.pass
|
||||
}
|
||||
Common.LogSuccess(successLog)
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] WmiExec %v:%v %v %v %v",
|
||||
info.Host, 445, task.user, task.pass, err)
|
||||
errlog = strings.Replace(errlog, "\n", "", -1)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmperr
|
||||
}
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/shadow1ng/fscan/Common"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ZabbixScan 执行 Zabbix 服务扫描
|
||||
func ZabbixScan(info *Common.HostInfo) (tmperr error) {
|
||||
if Common.DisableBrute {
|
||||
return
|
||||
}
|
||||
|
||||
maxRetries := Common.MaxRetries
|
||||
threads := Common.BruteThreads
|
||||
|
||||
// 先测试默认账号
|
||||
defaultDone := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func() {
|
||||
success, err := ZabbixConn(info, "Admin", "zabbix")
|
||||
defaultDone <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}()
|
||||
|
||||
select {
|
||||
case result := <-defaultDone:
|
||||
if result.success && result.err == nil {
|
||||
return result.err
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
Common.LogError(fmt.Sprintf("[-] Zabbix默认账号连接超时 %v:%v", info.Host, info.Ports))
|
||||
}
|
||||
|
||||
// 创建任务通道
|
||||
taskChan := make(chan struct {
|
||||
user string
|
||||
pass string
|
||||
}, len(Common.Userdict["zabbix"])*len(Common.Passwords))
|
||||
resultChan := make(chan error, threads)
|
||||
|
||||
// 生成所有用户名密码组合任务
|
||||
for _, user := range Common.Userdict["zabbix"] {
|
||||
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()
|
||||
starttime := time.Now().Unix()
|
||||
|
||||
for task := range taskChan {
|
||||
// 重试循环
|
||||
for retryCount := 0; retryCount < maxRetries; retryCount++ {
|
||||
// 检查是否超时
|
||||
if time.Now().Unix()-starttime > int64(Common.Timeout) {
|
||||
resultChan <- fmt.Errorf("扫描超时")
|
||||
return
|
||||
}
|
||||
|
||||
// 执行Zabbix连接
|
||||
done := make(chan struct {
|
||||
success bool
|
||||
err error
|
||||
})
|
||||
|
||||
go func(user, pass string) {
|
||||
success, err := ZabbixConn(info, user, pass)
|
||||
done <- struct {
|
||||
success bool
|
||||
err error
|
||||
}{success, err}
|
||||
}(task.user, task.pass)
|
||||
|
||||
// 等待结果或超时
|
||||
var err error
|
||||
select {
|
||||
case result := <-done:
|
||||
err = result.err
|
||||
if result.success && err == nil {
|
||||
resultChan <- nil
|
||||
return
|
||||
}
|
||||
case <-time.After(time.Duration(Common.Timeout) * time.Second):
|
||||
err = fmt.Errorf("连接超时")
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] Zabbix服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
|
||||
info.Host, info.Ports, task.user, task.pass, err)
|
||||
Common.LogError(errlog)
|
||||
|
||||
// 检查是否需要重试
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
if retryCount == maxRetries-1 {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
continue // 继续重试
|
||||
}
|
||||
}
|
||||
|
||||
break // 如果不需要重试,跳出重试循环
|
||||
}
|
||||
}
|
||||
resultChan <- nil
|
||||
}()
|
||||
}
|
||||
|
||||
// 等待所有线程完成
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
|
||||
// 检查结果
|
||||
for err := range resultChan {
|
||||
if err != nil {
|
||||
tmperr = err
|
||||
if retryErr := Common.CheckErrs(err); retryErr != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmperr
|
||||
}
|
||||
|
||||
// ZabbixConn 尝试 Zabbix API 连接
|
||||
func ZabbixConn(info *Common.HostInfo, user string, pass string) (bool, error) {
|
||||
host, port := info.Host, info.Ports
|
||||
timeout := time.Duration(Common.Timeout) * time.Second
|
||||
|
||||
// 构造 API URL
|
||||
apiURL := fmt.Sprintf("http://%s:%s/api_jsonrpc.php", host, port)
|
||||
|
||||
// 构造认证请求
|
||||
authRequest := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "user.login",
|
||||
"params": map[string]string{
|
||||
"user": user,
|
||||
"password": pass,
|
||||
},
|
||||
"id": 1,
|
||||
}
|
||||
|
||||
// 创建HTTP客户端
|
||||
client := resty.New()
|
||||
client.SetTimeout(timeout)
|
||||
|
||||
// 发送认证请求
|
||||
resp, err := client.R().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody(authRequest).
|
||||
Post(apiURL)
|
||||
|
||||
if err != nil {
|
||||
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||
return false, fmt.Errorf("连接超时")
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var result struct {
|
||||
Result string `json:"result"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data string `json:"data"`
|
||||
} `json:"error"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(resp.Body(), &result); err != nil {
|
||||
return false, fmt.Errorf("响应解析失败")
|
||||
}
|
||||
|
||||
// 检查是否认证成功
|
||||
if result.Result != "" {
|
||||
success := fmt.Sprintf("[+] Zabbix服务 %v:%v 爆破成功 用户名: %v 密码: %v", host, port, user, pass)
|
||||
Common.LogSuccess(success)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("认证失败: %v", result.Error.Message)
|
||||
}
|
||||
Reference in New Issue
Block a user