mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-07-13 21:02:44 +08:00
refactor: 调整逻辑,修复SMB2的一个跳出问题
This commit is contained in:
parent
af06345aa5
commit
235e2aee60
@ -901,6 +901,8 @@ var (
|
|||||||
HttpProxy string // 原Proxy
|
HttpProxy string // 原Proxy
|
||||||
Socks5Proxy string
|
Socks5Proxy string
|
||||||
|
|
||||||
|
LocalMode bool // -local 本地模式
|
||||||
|
|
||||||
// POC配置
|
// POC配置
|
||||||
PocPath string
|
PocPath string
|
||||||
Pocinfo PocInfo
|
Pocinfo PocInfo
|
||||||
|
@ -215,6 +215,9 @@ func Flag(Info *HostInfo) {
|
|||||||
flag.StringVar(&HttpProxy, "proxy", "", "设置HTTP代理服务器")
|
flag.StringVar(&HttpProxy, "proxy", "", "设置HTTP代理服务器")
|
||||||
flag.StringVar(&Socks5Proxy, "socks5", "", "设置Socks5代理(用于TCP连接,将影响超时设置)")
|
flag.StringVar(&Socks5Proxy, "socks5", "", "设置Socks5代理(用于TCP连接,将影响超时设置)")
|
||||||
|
|
||||||
|
// 本地扫描配置
|
||||||
|
flag.BoolVar(&LocalMode, "local", false, "启用本地信息收集模式")
|
||||||
|
|
||||||
// POC配置
|
// POC配置
|
||||||
flag.StringVar(&PocPath, "pocpath", "", "指定自定义POC文件路径")
|
flag.StringVar(&PocPath, "pocpath", "", "指定自定义POC文件路径")
|
||||||
flag.StringVar(&Pocinfo.PocName, "pocname", "", "指定要使用的POC名称,如: -pocname weblogic")
|
flag.StringVar(&Pocinfo.PocName, "pocname", "", "指定要使用的POC名称,如: -pocname weblogic")
|
||||||
|
@ -3,6 +3,7 @@ package Common
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@ -204,12 +205,27 @@ func Readfile(filename string) ([]string, error) {
|
|||||||
|
|
||||||
// ParseInput 解析和验证输入参数配置
|
// ParseInput 解析和验证输入参数配置
|
||||||
func ParseInput(Info *HostInfo) error {
|
func ParseInput(Info *HostInfo) error {
|
||||||
// 所有目标参数为空时表示本地扫描模式
|
// 检查互斥的扫描模式
|
||||||
if Info.Host == "" && HostsFile == "" && TargetURL == "" && URLsFile == "" {
|
modes := 0
|
||||||
LogInfo("未指定扫描目标,将以本地模式运行")
|
if Info.Host != "" || HostsFile != "" {
|
||||||
|
modes++
|
||||||
|
}
|
||||||
|
if TargetURL != "" || URLsFile != "" {
|
||||||
|
modes++
|
||||||
|
}
|
||||||
|
if LocalMode {
|
||||||
|
modes++
|
||||||
}
|
}
|
||||||
|
|
||||||
// 配置基本参数
|
if modes == 0 {
|
||||||
|
// 无参数时显示帮助
|
||||||
|
flag.Usage()
|
||||||
|
return fmt.Errorf("请指定扫描参数")
|
||||||
|
} else if modes > 1 {
|
||||||
|
return fmt.Errorf("参数 -h、-u、-local 不能同时使用")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理爆破线程配置
|
||||||
if BruteThreads <= 0 {
|
if BruteThreads <= 0 {
|
||||||
BruteThreads = 1
|
BruteThreads = 1
|
||||||
LogInfo(fmt.Sprintf("暴力破解线程数: %d", BruteThreads))
|
LogInfo(fmt.Sprintf("暴力破解线程数: %d", BruteThreads))
|
||||||
|
@ -26,64 +26,46 @@ func Scan(info Common.HostInfo) {
|
|||||||
// 初始化HTTP客户端
|
// 初始化HTTP客户端
|
||||||
lib.Inithttp()
|
lib.Inithttp()
|
||||||
|
|
||||||
// 处理特殊情况
|
|
||||||
if info.Host == "" && len(Common.URLs) == 0 {
|
|
||||||
// Host为空且没有URLs,设置Local模式
|
|
||||||
LocalScan = true
|
|
||||||
Common.ScanMode = Common.ModeLocal
|
|
||||||
Common.LogInfo("未检测到目标,自动切换为本地扫描模式")
|
|
||||||
} else if len(Common.URLs) > 0 {
|
|
||||||
// 存在URLs时设置为Web模式
|
|
||||||
WebScan = true
|
|
||||||
Common.ScanMode = Common.ModeWeb
|
|
||||||
Common.LogInfo("检测到URL列表,自动切换为Web扫描模式")
|
|
||||||
}
|
|
||||||
|
|
||||||
Common.ParseScanMode(Common.ScanMode)
|
|
||||||
|
|
||||||
ch := make(chan struct{}, Common.ThreadNum)
|
ch := make(chan struct{}, Common.ThreadNum)
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
|
|
||||||
// 本地信息收集模式
|
// 根据不同模式执行扫描
|
||||||
if LocalScan {
|
switch {
|
||||||
|
case Common.LocalMode:
|
||||||
|
// 本地信息收集模式
|
||||||
|
Common.LogInfo("执行本地信息收集")
|
||||||
executeScans([]Common.HostInfo{info}, &ch, &wg)
|
executeScans([]Common.HostInfo{info}, &ch, &wg)
|
||||||
finishScan(&wg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Web模式直接处理URLs
|
case len(Common.URLs) > 0:
|
||||||
if WebScan {
|
// Web模式
|
||||||
var targetInfos []Common.HostInfo
|
var targetInfos []Common.HostInfo
|
||||||
for _, url := range Common.URLs {
|
for _, url := range Common.URLs {
|
||||||
urlInfo := info
|
urlInfo := info
|
||||||
// 确保URL包含协议前缀
|
|
||||||
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
|
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
|
||||||
url = "http://" + url
|
url = "http://" + url
|
||||||
}
|
}
|
||||||
urlInfo.Url = url
|
urlInfo.Url = url
|
||||||
targetInfos = append(targetInfos, urlInfo)
|
targetInfos = append(targetInfos, urlInfo)
|
||||||
}
|
}
|
||||||
if len(targetInfos) > 0 {
|
Common.LogInfo("开始Web扫描")
|
||||||
Common.LogInfo("开始Web扫描")
|
executeScans(targetInfos, &ch, &wg)
|
||||||
executeScans(targetInfos, &ch, &wg)
|
|
||||||
finishScan(&wg)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 常规模式:初始化并解析目标
|
default:
|
||||||
var hosts []string
|
// 主机扫描模式
|
||||||
var err error
|
if info.Host == "" {
|
||||||
if info.Host != "" {
|
Common.LogError("未指定扫描目标")
|
||||||
hosts, err = Common.ParseIP(info.Host, Common.HostsFile, Common.ExcludeHosts)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hosts, err := Common.ParseIP(info.Host, Common.HostsFile, Common.ExcludeHosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Common.LogError(fmt.Sprintf("解析主机错误: %v", err))
|
Common.LogError(fmt.Sprintf("解析主机错误: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Common.LogInfo("开始主机扫描")
|
||||||
|
executeScan(hosts, info, &ch, &wg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行目标扫描
|
|
||||||
executeScan(hosts, info, &ch, &wg)
|
|
||||||
finishScan(&wg)
|
finishScan(&wg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,9 @@ func SmblConn(info *Common.HostInfo, user string, pass string, signal chan struc
|
|||||||
return false, fmt.Errorf("认证失败")
|
return false, fmt.Errorf("认证失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加 debug 输出原始错误信息
|
||||||
|
Common.LogDebug(fmt.Sprintf("SMB original error: %v", err))
|
||||||
|
|
||||||
// 清理错误信息中的换行符和多余空格
|
// 清理错误信息中的换行符和多余空格
|
||||||
errMsg := strings.TrimSpace(strings.ReplaceAll(err.Error(), "\n", " "))
|
errMsg := strings.TrimSpace(strings.ReplaceAll(err.Error(), "\n", " "))
|
||||||
if strings.Contains(errMsg, "NT Status Error") {
|
if strings.Contains(errMsg, "NT Status Error") {
|
||||||
|
@ -35,8 +35,14 @@ func smbPasswordScan(info *Common.HostInfo) error {
|
|||||||
|
|
||||||
// 遍历每个用户
|
// 遍历每个用户
|
||||||
for _, user := range Common.Userdict["smb"] {
|
for _, user := range Common.Userdict["smb"] {
|
||||||
|
accountLocked := false // 添加账户锁定标志
|
||||||
|
|
||||||
// 遍历该用户的所有密码
|
// 遍历该用户的所有密码
|
||||||
for _, pass := range Common.Passwords {
|
for _, pass := range Common.Passwords {
|
||||||
|
if accountLocked { // 如果账户被锁定,跳过剩余密码
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
pass = strings.ReplaceAll(pass, "{user}", user)
|
pass = strings.ReplaceAll(pass, "{user}", user)
|
||||||
|
|
||||||
// 重试循环
|
// 重试循环
|
||||||
@ -56,8 +62,9 @@ func smbPasswordScan(info *Common.HostInfo) error {
|
|||||||
logFailedAuth(info, user, pass, []byte{}, err)
|
logFailedAuth(info, user, pass, []byte{}, err)
|
||||||
|
|
||||||
// 检查是否账户锁定
|
// 检查是否账户锁定
|
||||||
if strings.Contains(err.Error(), "user account has been automatically locked") {
|
if strings.Contains(err.Error(), "account has been automatically locked") ||
|
||||||
// 账户锁定,跳过该用户的剩余密码
|
strings.Contains(err.Error(), "account has been locked") {
|
||||||
|
accountLocked = true // 设置锁定标志
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user