mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-05-06 02:41:29 +00:00
feat: 增加SNMP扫描 增加UDP端口扫描
This commit is contained in:
parent
9e8726e1f8
commit
3529efcb24
@ -51,6 +51,7 @@ var (
|
||||
ScanMode string // 原Scantype
|
||||
ThreadNum int // 原Threads
|
||||
UseSynScan bool
|
||||
UseUdpScan bool
|
||||
Timeout int64 = 3
|
||||
LiveTop int
|
||||
DisablePing bool // 原NoPing
|
||||
|
@ -72,6 +72,7 @@ func Flag(Info *HostInfo) {
|
||||
" 漏洞类: ms17010, smbghost, smb2\n"+
|
||||
" 其他: findnet, wmiexec, localinfo")
|
||||
flag.BoolVar(&UseSynScan, "sS", false, "使用SYN扫描替代TCP全连接扫描(需要root/管理员权限)")
|
||||
flag.BoolVar(&UseUdpScan, "sU", false, "使用UDP扫描(部分端口自动使用UDP协议)")
|
||||
flag.IntVar(&ThreadNum, "t", 600, "设置扫描线程数")
|
||||
flag.Int64Var(&Timeout, "time", 3, "设置连接超时时间(单位:秒)")
|
||||
flag.IntVar(&LiveTop, "top", 10, "仅显示指定数量的存活主机")
|
||||
|
@ -21,7 +21,7 @@ var pluginGroups = map[string][]string{
|
||||
"web", "fcgi", // web类
|
||||
"mysql", "mssql", "redis", "mongodb", "postgres", // 数据库类
|
||||
"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", // 漏洞类
|
||||
"findnet", // 其他
|
||||
},
|
||||
@ -36,7 +36,7 @@ var pluginGroups = map[string][]string{
|
||||
"web", "fcgi",
|
||||
},
|
||||
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: {
|
||||
"ms17010", "smbghost", "smb2",
|
||||
|
@ -5,11 +5,11 @@ import (
|
||||
"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 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 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 {
|
||||
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) {
|
||||
defer wg.Done() // 保留 defer wg.Done()
|
||||
defer wg.Done()
|
||||
|
||||
var isOpen bool
|
||||
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)
|
||||
} else {
|
||||
// 标准TCP扫描
|
||||
conn, err := Common.WrapperTcpWithTimeout("tcp4",
|
||||
fmt.Sprintf("%s:%v", addr.ip, addr.port),
|
||||
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)
|
||||
result := fmt.Sprintf("[+] 端口开放 %s", address)
|
||||
protocol := "TCP"
|
||||
if Common.UseUdpScan {
|
||||
protocol = "UDP"
|
||||
}
|
||||
result := fmt.Sprintf("[+] %s端口开放 %s", protocol, address)
|
||||
Common.LogSuccess(result)
|
||||
|
||||
respondingHosts <- address
|
||||
@ -306,6 +315,47 @@ func calculateTCPChecksum(tcpHeader []byte, srcIP, dstIP net.IP) uint16 {
|
||||
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 {
|
||||
switch runtime.GOOS {
|
||||
|
@ -109,6 +109,12 @@ func init() {
|
||||
ScanFunc: Plugins.POP3Scan,
|
||||
})
|
||||
|
||||
Common.RegisterPlugin("snmp", Common.ScanPlugin{
|
||||
Name: "SNMP",
|
||||
Ports: []int{161, 162}, // SNMP默认端口
|
||||
ScanFunc: Plugins.SNMPScan,
|
||||
})
|
||||
|
||||
Common.RegisterPlugin("rdp", Common.ScanPlugin{
|
||||
Name: "RDP",
|
||||
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/snappy v0.0.4 // 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/go-multierror v1.1.1 // 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/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/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/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=
|
||||
|
Loading…
x
Reference in New Issue
Block a user