mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-05-06 19:03:21 +00:00
feat: 增加SNMP扫描 增加UDP端口扫描
This commit is contained in:
parent
9e8726e1f8
commit
3529efcb24
@ -51,6 +51,7 @@ var (
|
|||||||
ScanMode string // 原Scantype
|
ScanMode string // 原Scantype
|
||||||
ThreadNum int // 原Threads
|
ThreadNum int // 原Threads
|
||||||
UseSynScan bool
|
UseSynScan bool
|
||||||
|
UseUdpScan bool
|
||||||
Timeout int64 = 3
|
Timeout int64 = 3
|
||||||
LiveTop int
|
LiveTop int
|
||||||
DisablePing bool // 原NoPing
|
DisablePing bool // 原NoPing
|
||||||
|
@ -72,6 +72,7 @@ func Flag(Info *HostInfo) {
|
|||||||
" 漏洞类: ms17010, smbghost, smb2\n"+
|
" 漏洞类: ms17010, smbghost, smb2\n"+
|
||||||
" 其他: findnet, wmiexec, localinfo")
|
" 其他: findnet, wmiexec, localinfo")
|
||||||
flag.BoolVar(&UseSynScan, "sS", false, "使用SYN扫描替代TCP全连接扫描(需要root/管理员权限)")
|
flag.BoolVar(&UseSynScan, "sS", false, "使用SYN扫描替代TCP全连接扫描(需要root/管理员权限)")
|
||||||
|
flag.BoolVar(&UseUdpScan, "sU", false, "使用UDP扫描(部分端口自动使用UDP协议)")
|
||||||
flag.IntVar(&ThreadNum, "t", 600, "设置扫描线程数")
|
flag.IntVar(&ThreadNum, "t", 600, "设置扫描线程数")
|
||||||
flag.Int64Var(&Timeout, "time", 3, "设置连接超时时间(单位:秒)")
|
flag.Int64Var(&Timeout, "time", 3, "设置连接超时时间(单位:秒)")
|
||||||
flag.IntVar(&LiveTop, "top", 10, "仅显示指定数量的存活主机")
|
flag.IntVar(&LiveTop, "top", 10, "仅显示指定数量的存活主机")
|
||||||
|
@ -21,7 +21,7 @@ var pluginGroups = map[string][]string{
|
|||||||
"web", "fcgi", // web类
|
"web", "fcgi", // web类
|
||||||
"mysql", "mssql", "redis", "mongodb", "postgres", // 数据库类
|
"mysql", "mssql", "redis", "mongodb", "postgres", // 数据库类
|
||||||
"oracle", "memcached", "elasticsearch", "rabbitmq", "kafka", "activemq", // 数据库类
|
"oracle", "memcached", "elasticsearch", "rabbitmq", "kafka", "activemq", // 数据库类
|
||||||
"ftp", "ssh", "telnet", "smb", "rdp", "vnc", "netbios", "ldap", "smtp", "imap", "pop3", // 服务类
|
"ftp", "ssh", "telnet", "smb", "rdp", "vnc", "netbios", "ldap", "smtp", "imap", "pop3", "snmp", // 服务类
|
||||||
"ms17010", "smbghost", "smb2", // 漏洞类
|
"ms17010", "smbghost", "smb2", // 漏洞类
|
||||||
"findnet", // 其他
|
"findnet", // 其他
|
||||||
},
|
},
|
||||||
@ -36,7 +36,7 @@ var pluginGroups = map[string][]string{
|
|||||||
"web", "fcgi",
|
"web", "fcgi",
|
||||||
},
|
},
|
||||||
ModeService: {
|
ModeService: {
|
||||||
"ftp", "ssh", "telnet", "smb", "rdp", "vnc", "netbios", "ldap", "smtp", "imap", "pop3",
|
"ftp", "ssh", "telnet", "smb", "rdp", "vnc", "netbios", "ldap", "smtp", "imap", "pop3", "snmp",
|
||||||
},
|
},
|
||||||
ModeVul: {
|
ModeVul: {
|
||||||
"ms17010", "smbghost", "smb2",
|
"ms17010", "smbghost", "smb2",
|
||||||
|
@ -5,11 +5,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ServicePorts = "21,22,23,25,110,135,139,143,389,445,465,587,636,993,995,1433,1521,2222,3306,3389,5432,5672,5671,6379,8161,9000,9092,9093,9200,11211,15672,15671,27017,61616,61613"
|
var ServicePorts = "21,22,23,25,110,135,139,143,161,162,389,445,465,587,636,993,995,1433,1521,2222,3306,3389,5432,5672,5671,6379,8161,9000,9092,9093,9200,11211,15672,15671,27017,61616,61613"
|
||||||
var DbPorts = "1433,1521,3306,5432,5672,6379,9093,9200,11211,27017,61616"
|
var DbPorts = "1433,1521,3306,5432,5672,6379,9093,9200,11211,27017,61616"
|
||||||
var WebPorts = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10250,12018,12443,14000,15672,15671,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,21000,21501,21502,28018,20880"
|
var WebPorts = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10250,12018,12443,14000,15672,15671,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,21000,21501,21502,28018,20880"
|
||||||
var AllPorts = "1-65535"
|
var AllPorts = "1-65535"
|
||||||
var MainPorts = "21,22,23,80,81,110,135,143,139,389,443,445,993,995,1433,1521,3306,5432,5672,6379,7001,8000,8080,8089,9000,9200,9092,11211,15672,27017,61616"
|
var MainPorts = "21,22,23,80,81,110,135,139,143,161,389,443,445,993,995,1433,1521,3306,5432,5672,6379,7001,8000,8080,8089,9000,9200,9092,11211,15672,27017,61616"
|
||||||
|
|
||||||
func ParsePortsFromString(portsStr string) []int {
|
func ParsePortsFromString(portsStr string) []int {
|
||||||
var ports []int
|
var ports []int
|
||||||
|
@ -84,14 +84,19 @@ func PortScan(hostslist []string, ports string, timeout int64) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func PortConnect(addr Addr, respondingHosts chan<- string, timeout int64, wg *sync.WaitGroup) {
|
func PortConnect(addr Addr, respondingHosts chan<- string, timeout int64, wg *sync.WaitGroup) {
|
||||||
defer wg.Done() // 保留 defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
var isOpen bool
|
var isOpen bool
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if Common.UseSynScan {
|
if Common.UseUdpScan {
|
||||||
|
// UDP扫描
|
||||||
|
isOpen, err = UDPScan(addr.ip, addr.port, timeout)
|
||||||
|
} else if Common.UseSynScan {
|
||||||
|
// SYN扫描
|
||||||
isOpen, err = SynScan(addr.ip, addr.port, timeout)
|
isOpen, err = SynScan(addr.ip, addr.port, timeout)
|
||||||
} else {
|
} else {
|
||||||
|
// 标准TCP扫描
|
||||||
conn, err := Common.WrapperTcpWithTimeout("tcp4",
|
conn, err := Common.WrapperTcpWithTimeout("tcp4",
|
||||||
fmt.Sprintf("%s:%v", addr.ip, addr.port),
|
fmt.Sprintf("%s:%v", addr.ip, addr.port),
|
||||||
time.Duration(timeout)*time.Second)
|
time.Duration(timeout)*time.Second)
|
||||||
@ -107,7 +112,11 @@ func PortConnect(addr Addr, respondingHosts chan<- string, timeout int64, wg *sy
|
|||||||
|
|
||||||
// 记录开放端口
|
// 记录开放端口
|
||||||
address := fmt.Sprintf("%s:%d", addr.ip, addr.port)
|
address := fmt.Sprintf("%s:%d", addr.ip, addr.port)
|
||||||
result := fmt.Sprintf("[+] 端口开放 %s", address)
|
protocol := "TCP"
|
||||||
|
if Common.UseUdpScan {
|
||||||
|
protocol = "UDP"
|
||||||
|
}
|
||||||
|
result := fmt.Sprintf("[+] %s端口开放 %s", protocol, address)
|
||||||
Common.LogSuccess(result)
|
Common.LogSuccess(result)
|
||||||
|
|
||||||
respondingHosts <- address
|
respondingHosts <- address
|
||||||
@ -306,6 +315,47 @@ func calculateTCPChecksum(tcpHeader []byte, srcIP, dstIP net.IP) uint16 {
|
|||||||
return ^uint16(sum)
|
return ^uint16(sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UDPScan(ip string, port int, timeout int64) (bool, error) {
|
||||||
|
// 创建UDP套接字
|
||||||
|
sendConn, err := net.ListenPacket("udp4", "0.0.0.0:0")
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("创建UDP套接字失败: %v", err)
|
||||||
|
}
|
||||||
|
defer sendConn.Close()
|
||||||
|
|
||||||
|
// 设置目标地址
|
||||||
|
dstAddr := &net.UDPAddr{
|
||||||
|
IP: net.ParseIP(ip),
|
||||||
|
Port: port,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送空包
|
||||||
|
_, err = sendConn.WriteTo([]byte{0x00}, dstAddr)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("发送UDP包失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置读取超时
|
||||||
|
sendConn.SetReadDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
|
||||||
|
|
||||||
|
// 尝试读取响应
|
||||||
|
buffer := make([]byte, 65507) // UDP最大包大小
|
||||||
|
n, _, err := sendConn.ReadFrom(buffer)
|
||||||
|
|
||||||
|
// 如果收到ICMP不可达,说明端口关闭
|
||||||
|
if err != nil {
|
||||||
|
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||||
|
// 超时可能意味着端口开放但没有响应
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
// 其他错误说明端口可能关闭
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收到响应说明端口开放
|
||||||
|
return n > 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 获取系统对应的接口名
|
// 获取系统对应的接口名
|
||||||
func getInterfaceName() string {
|
func getInterfaceName() string {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
|
@ -109,6 +109,12 @@ func init() {
|
|||||||
ScanFunc: Plugins.POP3Scan,
|
ScanFunc: Plugins.POP3Scan,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Common.RegisterPlugin("snmp", Common.ScanPlugin{
|
||||||
|
Name: "SNMP",
|
||||||
|
Ports: []int{161, 162}, // SNMP默认端口
|
||||||
|
ScanFunc: Plugins.SNMPScan,
|
||||||
|
})
|
||||||
|
|
||||||
Common.RegisterPlugin("rdp", Common.ScanPlugin{
|
Common.RegisterPlugin("rdp", Common.ScanPlugin{
|
||||||
Name: "RDP",
|
Name: "RDP",
|
||||||
Ports: []int{3389},
|
Ports: []int{3389},
|
||||||
|
90
Plugins/SNMP.go
Normal file
90
Plugins/SNMP.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package Plugins
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gosnmp/gosnmp"
|
||||||
|
"github.com/shadow1ng/fscan/Common"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SNMPScan 执行SNMP服务扫描
|
||||||
|
// SNMPScan 执行SNMP服务扫描
|
||||||
|
func SNMPScan(info *Common.HostInfo) (tmperr error) {
|
||||||
|
if Common.DisableBrute {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
starttime := time.Now().Unix()
|
||||||
|
portNum, _ := strconv.Atoi(info.Ports) // 添加端口转换
|
||||||
|
|
||||||
|
// 首先尝试默认community strings
|
||||||
|
defaultCommunities := []string{"public", "private", "cisco", "community"}
|
||||||
|
|
||||||
|
for _, community := range defaultCommunities {
|
||||||
|
flag, err := SNMPConnect(info, community, portNum) // 传入转换后的端口
|
||||||
|
if flag && err == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if Common.CheckErrs(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
errlog := fmt.Sprintf("[-] SNMP服务 %v:%v 尝试失败 community: %v 错误: %v",
|
||||||
|
info.Host, info.Ports, community, err)
|
||||||
|
Common.LogError(errlog)
|
||||||
|
tmperr = err
|
||||||
|
|
||||||
|
// 修正超时计算
|
||||||
|
timeout := time.Duration(Common.Timeout) * time.Second
|
||||||
|
if time.Now().Unix()-starttime > int64(timeout.Seconds())*int64(len(defaultCommunities)) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmperr
|
||||||
|
}
|
||||||
|
|
||||||
|
// SNMPConnect 尝试SNMP连接
|
||||||
|
func SNMPConnect(info *Common.HostInfo, community string, portNum int) (bool, error) {
|
||||||
|
host := info.Host
|
||||||
|
timeout := time.Duration(Common.Timeout) * time.Second
|
||||||
|
|
||||||
|
snmp := &gosnmp.GoSNMP{
|
||||||
|
Target: host,
|
||||||
|
Port: uint16(portNum),
|
||||||
|
Community: community,
|
||||||
|
Version: gosnmp.Version2c,
|
||||||
|
Timeout: timeout,
|
||||||
|
Retries: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := snmp.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer snmp.Conn.Close()
|
||||||
|
|
||||||
|
oids := []string{"1.3.6.1.2.1.1.1.0"}
|
||||||
|
result, err := snmp.Get(oids)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result.Variables) > 0 {
|
||||||
|
success := fmt.Sprintf("[+] SNMP服务 %v:%v community: %v",
|
||||||
|
host, portNum, community) // 使用portNum替换port
|
||||||
|
|
||||||
|
if result.Variables[0].Type != gosnmp.NoSuchObject {
|
||||||
|
sysDesc := strings.TrimSpace(string(result.Variables[0].Value.([]byte)))
|
||||||
|
success += fmt.Sprintf(" System: %v", sysDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
Common.LogSuccess(success)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, fmt.Errorf("认证失败")
|
||||||
|
}
|
1
go.mod
1
go.mod
@ -46,6 +46,7 @@ require (
|
|||||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/gosnmp/gosnmp v1.38.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -129,6 +129,8 @@ github.com/gopherjs/gopherjs v0.0.0-20210621113107-84c6004145de/go.mod h1:MtKwTf
|
|||||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/gosnmp/gosnmp v1.38.0 h1:I5ZOMR8kb0DXAFg/88ACurnuwGwYkXWq3eLpJPHMEYc=
|
||||||
|
github.com/gosnmp/gosnmp v1.38.0/go.mod h1:FE+PEZvKrFz9afP9ii1W3cprXuVZ17ypCcyyfYuu5LY=
|
||||||
github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY=
|
github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY=
|
||||||
github.com/goxjs/glfw v0.0.0-20191126052801-d2efb5f20838/go.mod h1:oS8P8gVOT4ywTcjV6wZlOU4GuVFQ8F5328KY3MJ79CY=
|
github.com/goxjs/glfw v0.0.0-20191126052801-d2efb5f20838/go.mod h1:oS8P8gVOT4ywTcjV6wZlOU4GuVFQ8F5328KY3MJ79CY=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user