mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-23 19:51:52 +08:00
## 架构重构
- 全局变量消除,迁移至 Config/State 对象
- SMB 插件融合(smb/smb2/smbghost/smbinfo)
- 服务探测重构,实现 Nmap 风格 fallback 机制
- 输出系统重构,TXT 实时刷盘 + 双写机制
- i18n 框架升级至 go-i18n
## 性能优化
- 正则表达式预编译
- 内存优化 map[string]struct{}
- 并发指纹匹配
- SOCKS5 连接复用
- 滑动窗口调度 + 自适应线程池
## 新功能
- Web 管理界面
- 多格式 POC 适配(xray/afrog)
- 增强指纹库(3139条)
- Favicon hash 指纹识别
- 插件选择性编译(Build Tags)
- fscan-lab 靶场环境
- 默认端口扩展(62→133)
## 构建系统
- 添加 no_local tag 支持排除本地插件
- 多版本构建:fscan/fscan-nolocal/fscan-web
- CI 添加 snapshot 模式支持仅测试构建
## Bug 修复
- 修复 120+ 个问题,包括 RDP panic、批量扫描漏报、
JSON 输出格式、Redis 检测、Context 超时等
## 测试增强
- 单元测试覆盖率 74-100%
- 并发安全测试
- 集成测试(Web/端口/服务/SSH/ICMP)
100 lines
2.3 KiB
Go
100 lines
2.3 KiB
Go
package nla
|
|
|
|
import (
|
|
"encoding/asn1"
|
|
|
|
"github.com/shadow1ng/fscan/mylib/grdp/glog"
|
|
)
|
|
|
|
type NegoToken struct {
|
|
Data []byte `asn1:"explicit,tag:0"`
|
|
}
|
|
|
|
type TSRequest struct {
|
|
Version int `asn1:"explicit,tag:0"`
|
|
NegoTokens []NegoToken `asn1:"optional,explicit,tag:1"`
|
|
AuthInfo []byte `asn1:"optional,explicit,tag:2"`
|
|
PubKeyAuth []byte `asn1:"optional,explicit,tag:3"`
|
|
//ErrorCode int `asn1:"optional,explicit,tag:4"`
|
|
}
|
|
|
|
type TSCredentials struct {
|
|
CredType int `asn1:"explicit,tag:0"`
|
|
Credentials []byte `asn1:"explicit,tag:1"`
|
|
}
|
|
|
|
type TSPasswordCreds struct {
|
|
DomainName []byte `asn1:"explicit,tag:0"`
|
|
UserName []byte `asn1:"explicit,tag:1"`
|
|
Password []byte `asn1:"explicit,tag:2"`
|
|
}
|
|
|
|
type TSCspDataDetail struct {
|
|
KeySpec int `asn1:"explicit,tag:0"`
|
|
CardName string `asn1:"explicit,tag:1"`
|
|
ReaderName string `asn1:"explicit,tag:2"`
|
|
ContainerName string `asn1:"explicit,tag:3"`
|
|
CspName string `asn1:"explicit,tag:4"`
|
|
}
|
|
|
|
type TSSmartCardCreds struct {
|
|
Pin string `asn1:"explicit,tag:0"`
|
|
CspData []TSCspDataDetail `asn1:"explicit,tag:1"`
|
|
UserHint string `asn1:"explicit,tag:2"`
|
|
DomainHint string `asn1:"explicit,tag:3"`
|
|
}
|
|
|
|
func EncodeDERTRequest(msgs []Message, authInfo []byte, pubKeyAuth []byte) []byte {
|
|
req := TSRequest{
|
|
Version: 2,
|
|
}
|
|
|
|
if len(msgs) > 0 {
|
|
req.NegoTokens = make([]NegoToken, 0, len(msgs))
|
|
}
|
|
|
|
for _, msg := range msgs {
|
|
token := NegoToken{msg.Serialize()}
|
|
req.NegoTokens = append(req.NegoTokens, token)
|
|
}
|
|
|
|
if len(authInfo) > 0 {
|
|
req.AuthInfo = authInfo
|
|
}
|
|
|
|
if len(pubKeyAuth) > 0 {
|
|
req.PubKeyAuth = pubKeyAuth
|
|
}
|
|
|
|
result, err := asn1.Marshal(req)
|
|
if err != nil {
|
|
glog.Error(err)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func DecodeDERTRequest(s []byte) (*TSRequest, error) {
|
|
treq := &TSRequest{}
|
|
_, err := asn1.Unmarshal(s, treq)
|
|
return treq, err
|
|
}
|
|
func EncodeDERTCredentials(domain, username, password []byte) []byte {
|
|
tpas := TSPasswordCreds{domain, username, password}
|
|
result, err := asn1.Marshal(tpas)
|
|
if err != nil {
|
|
glog.Error(err)
|
|
}
|
|
tcre := TSCredentials{1, result}
|
|
result, err = asn1.Marshal(tcre)
|
|
if err != nil {
|
|
glog.Error(err)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func DecodeDERTCredentials(s []byte) (*TSCredentials, error) {
|
|
tcre := &TSCredentials{}
|
|
_, err := asn1.Unmarshal(s, tcre)
|
|
return tcre, err
|
|
}
|