fscan/plugins/legacy/Base.go
ZacharyZcR e3c14e9f8e feat: 新增SMBInfo插件,增强SMB协议信息收集能力
- 新增smbinfo插件,专门用于SMB协议信息收集和操作系统检测
- 实现完整的NTLM Type 2消息解析,提取详细的系统信息
- 支持Windows版本识别、计算机名、域名等信息提取
- 采用标准插件输出格式,与其他插件保持一致
- 保留原始NetBIOS插件,两个插件功能互补
- 优化SMB协议数据包处理,提升兼容性和稳定性
2025-08-12 23:06:01 +08:00

108 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package Plugins
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"errors"
"fmt"
"net"
)
// ReadBytes 从连接读取数据直到EOF或错误 - 改进的SMB协议处理
func ReadBytes(conn net.Conn) ([]byte, error) {
// 首先读取NetBIOS头部(4字节)来确定消息长度
headerBuf := make([]byte, 4)
n, err := conn.Read(headerBuf)
if err != nil {
return nil, fmt.Errorf("读取NetBIOS头部失败: %v", err)
}
if n != 4 {
return nil, fmt.Errorf("NetBIOS头部长度不足: %d", n)
}
// 解析NetBIOS消息长度(大端序)
messageLength := int(headerBuf[0])<<24 | int(headerBuf[1])<<16 | int(headerBuf[2])<<8 | int(headerBuf[3])
// 防止过大的消息长度(安全检查)
if messageLength > 1024*1024 { // 1MB限制
return nil, fmt.Errorf("消息长度过大: %d", messageLength)
}
// 如果消息长度为0只返回头部
if messageLength == 0 {
return headerBuf, nil
}
// 读取完整消息体
messageBuf := make([]byte, messageLength)
totalRead := 0
for totalRead < messageLength {
n, err := conn.Read(messageBuf[totalRead:])
if err != nil {
return nil, fmt.Errorf("读取消息体失败(已读取%d/%d字节): %v", totalRead, messageLength, err)
}
totalRead += n
}
// 返回完整消息(头部+消息体)
result := make([]byte, 0, 4+messageLength)
result = append(result, headerBuf...)
result = append(result, messageBuf...)
return result, nil
}
// 默认AES加密密钥
var key = "0123456789abcdef"
// AesDecrypt 使用AES-CBC模式解密字符串
func AesDecrypt(crypted string, key string) (string, error) {
// base64解码
cryptedBytes, err := base64.StdEncoding.DecodeString(crypted)
if err != nil {
return "", fmt.Errorf("base64解码失败: %v", err)
}
keyBytes := []byte(key)
// 创建解密块
block, err := aes.NewCipher(keyBytes)
if err != nil {
return "", fmt.Errorf("创建解密块失败: %v", err)
}
// 创建CBC解密模式
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, keyBytes[:blockSize])
// 解密数据
origData := make([]byte, len(cryptedBytes))
blockMode.CryptBlocks(origData, cryptedBytes)
// 去除填充
origData, err = PKCS7UnPadding(origData)
if err != nil {
return "", fmt.Errorf("去除PKCS7填充失败: %v", err)
}
return string(origData), nil
}
// PKCS7UnPadding 去除PKCS7填充
func PKCS7UnPadding(data []byte) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, errors.New("数据长度为0")
}
padding := int(data[length-1])
if padding > length {
return nil, errors.New("填充长度无效")
}
return data[:length-padding], nil
}