From 7f5a1419365c0d734487ea771104611ada9c2997 Mon Sep 17 00:00:00 2001 From: Mzack9999 Date: Thu, 21 Aug 2025 03:04:55 +0200 Subject: [PATCH 1/5] adding min auth support --- go.mod | 7 ++ go.sum | 14 ++++ pkg/js/libs/rsync/rsync.go | 148 +++++++++++++++++++++++++++++++++++-- 3 files changed, 163 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 2fd4ee3b53..0d622a321a 100644 --- a/go.mod +++ b/go.mod @@ -74,6 +74,7 @@ require ( github.com/go-pg/pg v8.0.7+incompatible github.com/go-sql-driver/mysql v1.9.3 github.com/goccy/go-json v0.10.5 + github.com/gokrazy/rsync v0.2.10 github.com/google/uuid v1.6.0 github.com/h2non/filetype v1.1.3 github.com/invopop/yaml v0.3.1 @@ -132,6 +133,7 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Mzack9999/go-http-digest-auth-client v0.6.1-0.20220414142836-eb8883508809 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect @@ -185,6 +187,7 @@ require ( github.com/cloudwego/base64x v0.1.5 // indirect github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect github.com/containerd/continuity v0.4.5 // indirect + github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidmz/go-pageant v1.0.2 // indirect @@ -223,6 +226,7 @@ require ( github.com/google/certificate-transparency-go v1.1.4 // indirect github.com/google/go-github/v30 v30.1.0 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/google/renameio/v2 v2.0.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -250,6 +254,7 @@ require ( github.com/klauspost/pgzip v1.2.6 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/labstack/gommon v0.4.2 // indirect + github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/libdns/libdns v0.2.1 // indirect github.com/logrusorgru/aurora/v4 v4.0.0 // indirect @@ -267,6 +272,7 @@ require ( github.com/minio/minlz v1.0.0 // indirect github.com/minio/selfupdate v0.6.1-0.20230907112617-f11e74f84ca7 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mmcloughlin/md4 v0.1.2 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/user v0.3.0 // indirect github.com/moby/term v0.5.0 // indirect @@ -341,6 +347,7 @@ require ( golang.org/x/arch v0.3.0 // indirect golang.org/x/sync v0.15.0 // indirect gopkg.in/djherbis/times.v1 v1.3.0 // indirect + kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 // indirect mellium.im/sasl v0.3.2 // indirect ) diff --git a/go.sum b/go.sum index 5fa540e33c..507b19ae48 100644 --- a/go.sum +++ b/go.sum @@ -69,6 +69,8 @@ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mo github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= @@ -276,6 +278,8 @@ github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdk github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08/go.mod h1:pCxVEbcm3AMg7ejXyorUXi6HQCzOIBf7zEDVPtw0/U4= github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4= github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= @@ -414,6 +418,8 @@ github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gokrazy/rsync v0.2.10 h1:9wXJmvKACwmfIq/ent6C/AiG5n+WonOfQPAKzxv5dUU= +github.com/gokrazy/rsync v0.2.10/go.mod h1:nrvfy+3qYcxt92pGtVa38uKlQ0dl2SrXEmtIaY/vCHA= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -499,6 +505,8 @@ github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0Z github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= +github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -625,6 +633,8 @@ github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcX github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3 h1:zcMi8R8vP0WrrXlFMNUBpDy/ydo3sTnCcUPowq1XmSc= +github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3/go.mod h1:RSub3ourNF8Hf+swvw49Catm3s7HVf4hzdFxDUnEzdA= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= @@ -680,6 +690,8 @@ github.com/minio/selfupdate v0.6.1-0.20230907112617-f11e74f84ca7/go.mod h1:bO02G github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mmcloughlin/md4 v0.1.2 h1:kGYl+iNbxhyz4u76ka9a+0TXP9KWt/LmnM0QhZwhcBo= +github.com/mmcloughlin/md4 v0.1.2/go.mod h1:AAxFX59fddW0IguqNzWlf1lazh1+rXeIt/Bj49cqDTQ= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= @@ -1505,6 +1517,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 h1:HsB2G/rEQiYyo1bGoQqHZ/Bvd6x1rERQTNdPr1FyWjI= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.70/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0= mellium.im/sasl v0.3.2/go.mod h1:NKXDi1zkr+BlMHLQjY3ofYuU4KSPFxknb8mfEu6SveY= moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= diff --git a/pkg/js/libs/rsync/rsync.go b/pkg/js/libs/rsync/rsync.go index a1b4073959..b00a588912 100644 --- a/pkg/js/libs/rsync/rsync.go +++ b/pkg/js/libs/rsync/rsync.go @@ -4,15 +4,37 @@ import ( "context" "fmt" "net" + "os" "strconv" "time" + rsyncclient "github.com/gokrazy/rsync/rsyncclient" "github.com/praetorian-inc/fingerprintx/pkg/plugins" "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/rsync" "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" + "github.com/projectdiscovery/utils/errkit" + fileutil "github.com/projectdiscovery/utils/file" ) type ( + // RsyncClient is a client for RSYNC servers. + // Internally client uses https://github.com/gokrazy/rsync driver. + // @example + // ```javascript + // const rsync = require('nuclei/rsync'); + // const client = new rsync.RsyncClient(); + // ``` + RsyncClient struct { + connection net.Conn + host string + port int + timeout time.Duration + username string + password string + client *rsyncclient.Client + passwordFile string + } + // IsRsyncResponse is the response from the IsRsync function. // this is returned by IsRsync function. // @example @@ -27,6 +49,14 @@ type ( } ) +func connect(executionId string, host string, port int) (net.Conn, error) { + dialer := protocolstate.GetDialersWithId(executionId) + if dialer == nil { + return nil, fmt.Errorf("dialers not initialized for %s", executionId) + } + return dialer.Fastdialer.Dial(context.Background(), "tcp", net.JoinHostPort(host, strconv.Itoa(port))) +} + // IsRsync checks if a host is running a Rsync server. // @example // ```javascript @@ -44,11 +74,7 @@ func isRsync(executionId string, host string, port int) (IsRsyncResponse, error) resp := IsRsyncResponse{} timeout := 5 * time.Second - dialer := protocolstate.GetDialersWithId(executionId) - if dialer == nil { - return IsRsyncResponse{}, fmt.Errorf("dialers not initialized for %s", executionId) - } - conn, err := dialer.Fastdialer.Dial(context.TODO(), "tcp", net.JoinHostPort(host, strconv.Itoa(port))) + conn, err := connect(executionId, host, port) if err != nil { return resp, err } @@ -59,7 +85,7 @@ func isRsync(executionId string, host string, port int) (IsRsyncResponse, error) rsyncPlugin := rsync.RSYNCPlugin{} service, err := rsyncPlugin.Run(conn, timeout, plugins.Target{Host: host}) if err != nil { - return resp, err + return resp, nil } if service == nil { return resp, nil @@ -68,3 +94,113 @@ func isRsync(executionId string, host string, port int) (IsRsyncResponse, error) resp.IsRsync = true return resp, nil } + +// Connect establishes a connection to the rsync server. +// @example +// ```javascript +// const rsync = require('nuclei/rsync'); +// const client = new rsync.RsyncClient(); +// const connected = client.Connect('acme.com', 873, 'username', 'password'); +// ``` +func (c *RsyncClient) Connect(ctx context.Context, host string, port int, username, password string) (bool, error) { + executionId := ctx.Value("executionId").(string) + conn, err := connect(executionId, host, port) + if err != nil { + return false, err + } + + // Create minimal rsync client with auth + args := []string{"--list-only"} + if username != "" { + args = append(args, "--user", username) + } + if password != "" { + // Create a temporary password file + tempFileName, err := fileutil.GetTempFileName() + if err != nil { + _ = conn.Close() + return false, fmt.Errorf("failed to get temporary filename: %v", err) + } + + // Write password to the file + err = os.WriteFile(tempFileName, []byte(password), 0600) + if err != nil { + _ = os.Remove(tempFileName) + _ = conn.Close() + return false, fmt.Errorf("failed to write password to file: %v", err) + } + + // Use the actual filename instead of stdin + args = append(args, "--password-file", tempFileName) + c.passwordFile = tempFileName + } + + client, err := rsyncclient.New(args) + if err != nil { + _ = conn.Close() + return false, fmt.Errorf("failed to create rsync client: %v", err) + } + + // Test authentication with minimal command + _, err = client.Run(ctx, conn, []string{"/"}) + if err != nil { + _ = conn.Close() + if c.passwordFile != "" { + _ = os.Remove(c.passwordFile) + } + return false, fmt.Errorf("authentication failed: %v", err) + } + + c.connection = conn + c.host = host + c.port = port + c.timeout = 30 * time.Second + c.username = username + c.password = password + c.client = client + + return true, nil +} + +// Close closes the rsync connection and cleans up temporary files. +// @example +// ```javascript +// const rsync = require('nuclei/rsync'); +// const client = new rsync.RsyncClient(); +// client.Connect('acme.com', 873, 'username', 'password'); +// // ... use client ... +// client.Close(); +// ``` +func (c *RsyncClient) Close() error { + var errs []error + + // Close the connection + if c.connection != nil { + if err := c.connection.Close(); err != nil { + errs = append(errs, err) + } + c.connection = nil + } + + // Clean up temporary password file + if c.passwordFile != "" { + if err := os.Remove(c.passwordFile); err != nil { + errs = append(errs, err) + } + c.passwordFile = "" + } + + // Reset other fields + c.host = "" + c.port = 0 + c.timeout = 0 + c.username = "" + c.password = "" + c.client = nil + + // Return joined errors if any occurred + if len(errs) > 0 { + return errkit.Join(errs...) + } + return nil +} From 663a8e9d49d5668307eff3c37f70a6e1a5ef88a5 Mon Sep 17 00:00:00 2001 From: Mzack9999 Date: Thu, 21 Aug 2025 20:05:14 +0200 Subject: [PATCH 2/5] adding unauth list modules + auth list files in module --- go.mod | 15 +- go.sum | 30 ++-- pkg/js/generated/go/librsync/rsync.go | 1 + pkg/js/generated/ts/rsync.ts | 56 ++++++- pkg/js/libs/rsync/rsync.go | 211 +++++++++++++------------- 5 files changed, 180 insertions(+), 133 deletions(-) diff --git a/go.mod b/go.mod index 0d622a321a..9328475fb6 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/olekukonko/tablewriter v1.0.8 github.com/pkg/errors v0.9.1 github.com/projectdiscovery/clistats v0.1.1 - github.com/projectdiscovery/fastdialer v0.4.4 + github.com/projectdiscovery/fastdialer v0.4.6 github.com/projectdiscovery/hmap v0.0.92 github.com/projectdiscovery/interactsh v1.2.4 github.com/projectdiscovery/rawhttp v0.1.90 @@ -74,7 +74,6 @@ require ( github.com/go-pg/pg v8.0.7+incompatible github.com/go-sql-driver/mysql v1.9.3 github.com/goccy/go-json v0.10.5 - github.com/gokrazy/rsync v0.2.10 github.com/google/uuid v1.6.0 github.com/h2non/filetype v1.1.3 github.com/invopop/yaml v0.3.1 @@ -99,7 +98,7 @@ require ( github.com/projectdiscovery/httpx v1.7.0 github.com/projectdiscovery/mapcidr v1.1.34 github.com/projectdiscovery/n3iwf v0.0.0-20230523120440-b8cd232ff1f5 - github.com/projectdiscovery/networkpolicy v0.1.18 + github.com/projectdiscovery/networkpolicy v0.1.20 github.com/projectdiscovery/ratelimit v0.0.81 github.com/projectdiscovery/rdap v0.9.0 github.com/projectdiscovery/sarif v0.0.1 @@ -133,9 +132,9 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect - github.com/BurntSushi/toml v1.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Mzack9999/go-http-digest-auth-client v0.6.1-0.20220414142836-eb8883508809 // indirect + github.com/Mzack9999/go-rsync v0.0.0-20250821180103-81ffa574ef4d // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/PuerkitoBio/goquery v1.10.3 // indirect @@ -187,7 +186,6 @@ require ( github.com/cloudwego/base64x v0.1.5 // indirect github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect github.com/containerd/continuity v0.4.5 // indirect - github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidmz/go-pageant v1.0.2 // indirect @@ -202,7 +200,7 @@ require ( github.com/felixge/fgprof v0.9.5 // indirect github.com/free5gc/util v1.0.5-0.20230511064842-2e120956883b // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/gaissmai/bart v0.20.5 // indirect + github.com/gaissmai/bart v0.23.1 // indirect github.com/geoffgarside/ber v1.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.9.1 // indirect @@ -226,7 +224,6 @@ require ( github.com/google/certificate-transparency-go v1.1.4 // indirect github.com/google/go-github/v30 v30.1.0 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect - github.com/google/renameio/v2 v2.0.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -247,6 +244,7 @@ require ( github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect + github.com/kaiakz/ubuffer v0.0.0-20200803053910-dd1083087166 // indirect github.com/kataras/jwt v0.1.10 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.18.0 // indirect @@ -254,7 +252,6 @@ require ( github.com/klauspost/pgzip v1.2.6 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/labstack/gommon v0.4.2 // indirect - github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/libdns/libdns v0.2.1 // indirect github.com/logrusorgru/aurora/v4 v4.0.0 // indirect @@ -272,7 +269,6 @@ require ( github.com/minio/minlz v1.0.0 // indirect github.com/minio/selfupdate v0.6.1-0.20230907112617-f11e74f84ca7 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mmcloughlin/md4 v0.1.2 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/user v0.3.0 // indirect github.com/moby/term v0.5.0 // indirect @@ -347,7 +343,6 @@ require ( golang.org/x/arch v0.3.0 // indirect golang.org/x/sync v0.15.0 // indirect gopkg.in/djherbis/times.v1 v1.3.0 // indirect - kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 // indirect mellium.im/sasl v0.3.2 // indirect ) diff --git a/go.sum b/go.sum index 507b19ae48..265b14f9e3 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,6 @@ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mo github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= @@ -85,6 +83,8 @@ github.com/Mzack9999/gcache v0.0.0-20230410081825-519e28eab057 h1:KFac3SiGbId8ub github.com/Mzack9999/gcache v0.0.0-20230410081825-519e28eab057/go.mod h1:iLB2pivrPICvLOuROKmlqURtFIEsoJZaMidQfCG1+D4= github.com/Mzack9999/go-http-digest-auth-client v0.6.1-0.20220414142836-eb8883508809 h1:ZbFL+BDfBqegi+/Ssh7im5+aQfBRx6it+kHnC7jaDU8= github.com/Mzack9999/go-http-digest-auth-client v0.6.1-0.20220414142836-eb8883508809/go.mod h1:upgc3Zs45jBDnBT4tVRgRcgm26ABpaP7MoTSdgysca4= +github.com/Mzack9999/go-rsync v0.0.0-20250821180103-81ffa574ef4d h1:DofPB5AcjTnOU538A/YD86/dfqSNTvQsAXgwagxmpu4= +github.com/Mzack9999/go-rsync v0.0.0-20250821180103-81ffa574ef4d/go.mod h1:uzdh/m6XQJI7qRvufeBPDa+lj5SVCJO8B9eLxTbtI5U= github.com/Mzack9999/goja v0.0.0-20250507184235-e46100e9c697 h1:54I+OF5vS4a/rxnUrN5J3hi0VEYKcrTlpc8JosDyP+c= github.com/Mzack9999/goja v0.0.0-20250507184235-e46100e9c697/go.mod h1:yNqYRqxYkSROY1J+LX+A0tOSA/6soXQs5m8hZSqYBac= github.com/Mzack9999/goja_nodejs v0.0.0-20250507184139-66bcbf65c883 h1:+Is1AS20q3naP+qJophNpxuvx1daFOx9C0kLIuI0GVk= @@ -278,8 +278,6 @@ github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdk github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08/go.mod h1:pCxVEbcm3AMg7ejXyorUXi6HQCzOIBf7zEDVPtw0/U4= github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4= github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= -github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= -github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= @@ -336,8 +334,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/gaissmai/bart v0.20.5 h1:ehoWZWQ7j//qt0K0Zs4i9hpoPpbgqsMQiR8W2QPJh+c= -github.com/gaissmai/bart v0.20.5/go.mod h1:cEed+ge8dalcbpi8wtS9x9m2hn/fNJH5suhdGQOHnYk= +github.com/gaissmai/bart v0.23.1 h1:8+EYZZcm9xObBgCIBb8f5sg65qVtphg7VcbMOjuvNrE= +github.com/gaissmai/bart v0.23.1/go.mod h1:RpLtt3lWq1BoRz3AAyDAJ7jhLWBkYhVCfi+ximB2t68= github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9w= github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc= github.com/getkin/kin-openapi v0.132.0 h1:3ISeLMsQzcb5v26yeJrBcdTCEQTag36ZjaGk7MIRUwk= @@ -418,8 +416,6 @@ github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gokrazy/rsync v0.2.10 h1:9wXJmvKACwmfIq/ent6C/AiG5n+WonOfQPAKzxv5dUU= -github.com/gokrazy/rsync v0.2.10/go.mod h1:nrvfy+3qYcxt92pGtVa38uKlQ0dl2SrXEmtIaY/vCHA= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -505,8 +501,6 @@ github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0Z github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= -github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -595,6 +589,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kaiakz/ubuffer v0.0.0-20200803053910-dd1083087166 h1:IAukUBAVLUWBcexOYgkTD/EjMkfnNos7g7LFpyIdHJI= +github.com/kaiakz/ubuffer v0.0.0-20200803053910-dd1083087166/go.mod h1:T4xUEny5PVedYIbkMAKYEBjMyDsOvvP0qK4s324AKA8= github.com/kataras/jwt v0.1.10 h1:GBXOF9RVInDPhCFBiDumRG9Tt27l7ugLeLo8HL5SeKQ= github.com/kataras/jwt v0.1.10/go.mod h1:xkimAtDhU/aGlQqjwvgtg+VyuPwMiyZHaY8LJRh0mYo= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= @@ -633,8 +629,6 @@ github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcX github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= -github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3 h1:zcMi8R8vP0WrrXlFMNUBpDy/ydo3sTnCcUPowq1XmSc= -github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3/go.mod h1:RSub3ourNF8Hf+swvw49Catm3s7HVf4hzdFxDUnEzdA= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= @@ -690,8 +684,6 @@ github.com/minio/selfupdate v0.6.1-0.20230907112617-f11e74f84ca7/go.mod h1:bO02G github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mmcloughlin/md4 v0.1.2 h1:kGYl+iNbxhyz4u76ka9a+0TXP9KWt/LmnM0QhZwhcBo= -github.com/mmcloughlin/md4 v0.1.2/go.mod h1:AAxFX59fddW0IguqNzWlf1lazh1+rXeIt/Bj49cqDTQ= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= @@ -781,8 +773,8 @@ github.com/projectdiscovery/clistats v0.1.1 h1:8mwbdbwTU4aT88TJvwIzTpiNeow3XnAB7 github.com/projectdiscovery/clistats v0.1.1/go.mod h1:4LtTC9Oy//RiuT1+76MfTg8Hqs7FQp1JIGBM3nHK6a0= github.com/projectdiscovery/dsl v0.5.0 h1:3HHY14FNmdwWXq3pi9dd8JjUHQzskZjLD/pZKVx5Vi4= github.com/projectdiscovery/dsl v0.5.0/go.mod h1:Fr+zIQJfMNy+RTj5KFgozfvDaiQQEKMyrKXl75aGgxY= -github.com/projectdiscovery/fastdialer v0.4.4 h1:QeVbOnTMPhc/IOkkj2AP2q9hu5E1oCBPiLwEvPSR6A8= -github.com/projectdiscovery/fastdialer v0.4.4/go.mod h1:a0FNUOcmW6g6JhjaJ2+YkCpFFkQeCbetq/d9Zo4G3rQ= +github.com/projectdiscovery/fastdialer v0.4.6 h1:7cw47IyrkVHCEM80dBDhjT4YNsPY2IAZD2Sg11QM0Wk= +github.com/projectdiscovery/fastdialer v0.4.6/go.mod h1:IRbTB9d2GNT1EyxA16b/HJpqYbnNXk6hsH8CRZkdukc= github.com/projectdiscovery/fasttemplate v0.0.2 h1:h2cISk5xDhlJEinlBQS6RRx0vOlOirB2y3Yu4PJzpiA= github.com/projectdiscovery/fasttemplate v0.0.2/go.mod h1:XYWWVMxnItd+r0GbjA1GCsUopMw1/XusuQxdyAIHMCw= github.com/projectdiscovery/freeport v0.0.7 h1:Q6uXo/j8SaV/GlAHkEYQi8WQoPXyJWxyspx+aFmz9Qk= @@ -813,8 +805,8 @@ github.com/projectdiscovery/mapcidr v1.1.34 h1:udr83vQ7oz3kEOwlsU6NC6o08leJzSDQt github.com/projectdiscovery/mapcidr v1.1.34/go.mod h1:1+1R6OkKSAKtWDXE9RvxXtXPoajXTYX0eiEdkqlhQqQ= github.com/projectdiscovery/n3iwf v0.0.0-20230523120440-b8cd232ff1f5 h1:L/e8z8yw1pfT6bg35NiN7yd1XKtJap5Nk6lMwQ0RNi8= github.com/projectdiscovery/n3iwf v0.0.0-20230523120440-b8cd232ff1f5/go.mod h1:pGW2ncnTxTxHtP9wzcIJAB+3/NMp6IiuQWd2NK7K+oc= -github.com/projectdiscovery/networkpolicy v0.1.18 h1:DAeP73SvcuT4evaohNS7BPELw+VtvcVt4PaTK3fC1qA= -github.com/projectdiscovery/networkpolicy v0.1.18/go.mod h1:2yWanKsU2oBZ75ch94IsEQy6hByFp+3oTiSyC6ew3TE= +github.com/projectdiscovery/networkpolicy v0.1.20 h1:dPUk3FKoAehMnFvphAZLq6khDCbPYPJnD6PPTcjp5nU= +github.com/projectdiscovery/networkpolicy v0.1.20/go.mod h1:laPi8mLbgCbYZ0kYQU4fkWCFQdFbx24ci7yBQA8Hcww= github.com/projectdiscovery/ratelimit v0.0.81 h1:u6lW+rAhS/UO0amHTYmYLipPK8NEotA9521hdojBtgI= github.com/projectdiscovery/ratelimit v0.0.81/go.mod h1:tK04WXHuC4i6AsFkByInODSNf45gd9sfaMHzmy2bAsA= github.com/projectdiscovery/rawhttp v0.1.90 h1:LOSZ6PUH08tnKmWsIwvwv1Z/4zkiYKYOSZ6n+8RFKtw= @@ -1517,8 +1509,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 h1:HsB2G/rEQiYyo1bGoQqHZ/Bvd6x1rERQTNdPr1FyWjI= -kernel.org/pub/linux/libs/security/libcap/psx v1.2.70/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0= mellium.im/sasl v0.3.2/go.mod h1:NKXDi1zkr+BlMHLQjY3ofYuU4KSPFxknb8mfEu6SveY= moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= diff --git a/pkg/js/generated/go/librsync/rsync.go b/pkg/js/generated/go/librsync/rsync.go index 6c269fcb00..ffc6f0a616 100644 --- a/pkg/js/generated/go/librsync/rsync.go +++ b/pkg/js/generated/go/librsync/rsync.go @@ -21,6 +21,7 @@ func init() { // Objects / Classes "IsRsyncResponse": gojs.GetClassConstructor[lib_rsync.IsRsyncResponse](&lib_rsync.IsRsyncResponse{}), + "RsyncClient": gojs.GetClassConstructor[lib_rsync.RsyncClient](&lib_rsync.RsyncClient{}), }, ).Register() } diff --git a/pkg/js/generated/ts/rsync.ts b/pkg/js/generated/ts/rsync.ts index afe2146803..6cb675b0d6 100755 --- a/pkg/js/generated/ts/rsync.ts +++ b/pkg/js/generated/ts/rsync.ts @@ -13,7 +13,61 @@ export function IsRsync(host: string, port: number): IsRsyncResponse | null { return null; } - +/** + * RsyncClient is a client for RSYNC servers. + * Internally client uses https://github.com/gokrazy/rsync driver. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const client = new rsync.RsyncClient(); + * ``` + */ +export class RsyncClient { + + // Constructor of RsyncClient + constructor() {} + + /** + * Connect establishes a connection to the rsync server with authentication. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const client = new rsync.RsyncClient(); + * const connected = client.Connect('acme.com', 873, 'username', 'password', 'backup'); + * ``` + */ + public Connect(host: string, port: number, username: string, password: string, module: string): boolean | null { + return null; + } + + /** + * ListModules lists available modules on the rsync server. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const client = new rsync.RsyncClient(); + * const modules = client.ListModules('acme.com', 873, 'username', 'password'); + * log(toJSON(modules)); + * ``` + */ + public ListModules(host: string, port: number, username: string, password: string): string[] | null { + return null; + } + + /** + * ListFilesInModule lists files in a specific module on the rsync server. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const client = new rsync.RsyncClient(); + * const files = client.ListFilesInModule('acme.com', 873, 'username', 'password', 'backup'); + * log(toJSON(files)); + * ``` + */ + public ListFilesInModule(host: string, port: number, username: string, password: string, module: string): string[] | null { + return null; + } +} /** * IsRsyncResponse is the response from the IsRsync function. diff --git a/pkg/js/libs/rsync/rsync.go b/pkg/js/libs/rsync/rsync.go index b00a588912..1dddd80333 100644 --- a/pkg/js/libs/rsync/rsync.go +++ b/pkg/js/libs/rsync/rsync.go @@ -1,19 +1,19 @@ package rsync import ( + "bytes" "context" "fmt" + "log/slog" "net" - "os" "strconv" "time" - rsyncclient "github.com/gokrazy/rsync/rsyncclient" + rsynclib "github.com/Mzack9999/go-rsync/rsync" + "github.com/praetorian-inc/fingerprintx/pkg/plugins" "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/rsync" "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" - "github.com/projectdiscovery/utils/errkit" - fileutil "github.com/projectdiscovery/utils/file" ) type ( @@ -24,16 +24,7 @@ type ( // const rsync = require('nuclei/rsync'); // const client = new rsync.RsyncClient(); // ``` - RsyncClient struct { - connection net.Conn - host string - port int - timeout time.Duration - username string - password string - client *rsyncclient.Client - passwordFile string - } + RsyncClient struct{} // IsRsyncResponse is the response from the IsRsync function. // this is returned by IsRsync function. @@ -47,9 +38,23 @@ type ( IsRsync bool Banner string } + + // ListSharesResponse is the response from the ListShares function. + // this is returned by ListShares function. + // @example + // ```javascript + // const rsync = require('nuclei/rsync'); + // const client = new rsync.RsyncClient(); + // const listShares = client.ListShares('acme.com', 873); + // log(toJSON(listShares)); + RsyncListResponse struct { + Modules []string + Files []string + Output string + } ) -func connect(executionId string, host string, port int) (net.Conn, error) { +func connectWithFastDialer(executionId string, host string, port int) (net.Conn, error) { dialer := protocolstate.GetDialersWithId(executionId) if dialer == nil { return nil, fmt.Errorf("dialers not initialized for %s", executionId) @@ -74,7 +79,7 @@ func isRsync(executionId string, host string, port int) (IsRsyncResponse, error) resp := IsRsyncResponse{} timeout := 5 * time.Second - conn, err := connect(executionId, host, port) + conn, err := connectWithFastDialer(executionId, host, port) if err != nil { return resp, err } @@ -95,112 +100,114 @@ func isRsync(executionId string, host string, port int) (IsRsyncResponse, error) return resp, nil } -// Connect establishes a connection to the rsync server. +// ListModules lists the modules of a Rsync server. // @example // ```javascript // const rsync = require('nuclei/rsync'); // const client = new rsync.RsyncClient(); -// const connected = client.Connect('acme.com', 873, 'username', 'password'); +// const listModules = client.ListModules('acme.com', 873, 'username', 'password'); +// log(toJSON(listModules)); // ``` -func (c *RsyncClient) Connect(ctx context.Context, host string, port int, username, password string) (bool, error) { +func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) { executionId := ctx.Value("executionId").(string) - conn, err := connect(executionId, host, port) - if err != nil { - return false, err - } + return listModules(executionId, host, port, username, password) +} - // Create minimal rsync client with auth - args := []string{"--list-only"} - if username != "" { - args = append(args, "--user", username) - } - if password != "" { - // Create a temporary password file - tempFileName, err := fileutil.GetTempFileName() - if err != nil { - _ = conn.Close() - return false, fmt.Errorf("failed to get temporary filename: %v", err) - } - - // Write password to the file - err = os.WriteFile(tempFileName, []byte(password), 0600) - if err != nil { - _ = os.Remove(tempFileName) - _ = conn.Close() - return false, fmt.Errorf("failed to write password to file: %v", err) - } - - // Use the actual filename instead of stdin - args = append(args, "--password-file", tempFileName) - c.passwordFile = tempFileName +// ListShares lists the shares of a Rsync server. +// @example +// ```javascript +// const rsync = require('nuclei/rsync'); +// const client = new rsync.RsyncClient(); +// const listShares = client.ListFilesInModule('acme.com', 873, 'username', 'password', '/'); +// log(toJSON(listShares)); +// ``` +func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) { + executionId := ctx.Value("executionId").(string) + return listFilesInModule(executionId, host, port, username, password, module) +} + +func listModules(executionId string, host string, port int, username string, password string) (RsyncListResponse, error) { + fastDialer := protocolstate.GetDialersWithId(executionId) + if fastDialer == nil { + return RsyncListResponse{}, fmt.Errorf("dialers not initialized for %s", executionId) } - client, err := rsyncclient.New(args) + address := net.JoinHostPort(host, strconv.Itoa(port)) + + // Create a bytes buffer for logging + var logBuffer bytes.Buffer + + // Create a custom slog handler that writes to the buffer + logHandler := slog.NewTextHandler(&logBuffer, &slog.HandlerOptions{ + Level: slog.LevelDebug, + }) + + // Create a logger that writes to our buffer + logger := slog.New(logHandler) + + sr, err := rsynclib.ListModules(address, + rsynclib.WithClientAuth(username, password), + rsynclib.WithLogger(logger), + rsynclib.WithFastDialer(fastDialer.Fastdialer), + ) if err != nil { - _ = conn.Close() - return false, fmt.Errorf("failed to create rsync client: %v", err) + return RsyncListResponse{}, fmt.Errorf("connect failed: %v", err) } - // Test authentication with minimal command - _, err = client.Run(ctx, conn, []string{"/"}) - if err != nil { - _ = conn.Close() - if c.passwordFile != "" { - _ = os.Remove(c.passwordFile) - } - return false, fmt.Errorf("authentication failed: %v", err) + result := RsyncListResponse{ + Modules: make([]string, len(sr)), + Output: logBuffer.String(), } - c.connection = conn - c.host = host - c.port = port - c.timeout = 30 * time.Second - c.username = username - c.password = password - c.client = client + for i, item := range sr { + result.Modules[i] = string(item.Name) + } - return true, nil + return result, nil } -// Close closes the rsync connection and cleans up temporary files. -// @example -// ```javascript -// const rsync = require('nuclei/rsync'); -// const client = new rsync.RsyncClient(); -// client.Connect('acme.com', 873, 'username', 'password'); -// // ... use client ... -// client.Close(); -// ``` -func (c *RsyncClient) Close() error { - var errs []error - - // Close the connection - if c.connection != nil { - if err := c.connection.Close(); err != nil { - errs = append(errs, err) - } - c.connection = nil +func listFilesInModule(executionId string, host string, port int, username string, password string, module string) (RsyncListResponse, error) { + fastDialer := protocolstate.GetDialersWithId(executionId) + if fastDialer == nil { + return RsyncListResponse{}, fmt.Errorf("dialers not initialized for %s", executionId) } - // Clean up temporary password file - if c.passwordFile != "" { - if err := os.Remove(c.passwordFile); err != nil { - errs = append(errs, err) - } - c.passwordFile = "" + address := net.JoinHostPort(host, strconv.Itoa(port)) + + // Create a bytes buffer for logging + var logBuffer bytes.Buffer + + // Create a custom slog handler that writes to the buffer + logHandler := slog.NewTextHandler(&logBuffer, &slog.HandlerOptions{ + Level: slog.LevelDebug, + }) + + // Create a logger that writes to our buffer + logger := slog.New(logHandler) + + sr, err := rsynclib.SocketClient(nil, address, module, ".", + rsynclib.WithClientAuth(username, password), + rsynclib.WithLogger(logger), + rsynclib.WithFastDialer(fastDialer.Fastdialer), + ) + if err != nil { + return RsyncListResponse{}, fmt.Errorf("connect failed: %v", err) } - // Reset other fields - c.host = "" - c.port = 0 - c.timeout = 0 - c.username = "" - c.password = "" - c.client = nil - - // Return joined errors if any occurred - if len(errs) > 0 { - return errkit.Join(errs...) + // Try to list files to test authentication + list, err := sr.List() + if err != nil { + return RsyncListResponse{}, fmt.Errorf("authentication failed: %v", err) } - return nil + + result := RsyncListResponse{ + Files: make([]string, len(list)), + Output: logBuffer.String(), + } + + for i, item := range list { + result.Files[i] = string(item.Path) + } + + return result, nil } From 68605c210b9c48f22985de4bb2cfb5d9c1bf12ab Mon Sep 17 00:00:00 2001 From: Mzack9999 Date: Thu, 21 Aug 2025 20:40:23 +0200 Subject: [PATCH 3/5] example --- cmd/nuclei/rsync.yaml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 cmd/nuclei/rsync.yaml diff --git a/cmd/nuclei/rsync.yaml b/cmd/nuclei/rsync.yaml new file mode 100644 index 0000000000..d67e8f49c4 --- /dev/null +++ b/cmd/nuclei/rsync.yaml @@ -0,0 +1,28 @@ +id: rsync-list-shares + +info: + name: Rsync Basic Auth - Detect + author: ciccio + severity: info + +javascript: + - code: | + const rsync = require('nuclei/rsync'); + const client = new rsync.RsyncClient(); + const moduleResponse = client.ListModules(Host, Port, Username, Password); + log(to_json(moduleResponse)); + for (const module of moduleResponse.Modules) { + const fileResponse = client.ListFilesInModule(Host, Port, Username, Password, module); + log(to_json(fileResponse)); + } + + args: + Host: "{{Host}}" + Port: "873" + Username: "{{Username}}" + Password: "{{Password}}" + + matchers: + - type: dsl + dsl: + - "success == true" \ No newline at end of file From fd3c304136dfbf9040f1ea269d90b1f650d73d04 Mon Sep 17 00:00:00 2001 From: Mzack9999 Date: Wed, 27 Aug 2025 17:43:46 +0200 Subject: [PATCH 4/5] adding rsync test --- cmd/integration-test/javascript.go | 51 +++++++++++++++++++ cmd/nuclei/rsync.yaml | 28 ---------- .../protocols/javascript/rsync-test.yaml | 21 ++++++++ 3 files changed, 72 insertions(+), 28 deletions(-) delete mode 100644 cmd/nuclei/rsync.yaml create mode 100644 integration_tests/protocols/javascript/rsync-test.yaml diff --git a/cmd/integration-test/javascript.go b/cmd/integration-test/javascript.go index e45f122c30..817231e6d3 100644 --- a/cmd/integration-test/javascript.go +++ b/cmd/integration-test/javascript.go @@ -15,11 +15,13 @@ var jsTestcases = []TestCaseInfo{ {Path: "protocols/javascript/ssh-server-fingerprint.yaml", TestCase: &javascriptSSHServerFingerprint{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }}, {Path: "protocols/javascript/net-multi-step.yaml", TestCase: &networkMultiStep{}}, {Path: "protocols/javascript/net-https.yaml", TestCase: &javascriptNetHttps{}}, + {Path: "protocols/javascript/rsync-test.yaml", TestCase: &javascriptRsyncTest{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }}, } var ( redisResource *dockertest.Resource sshResource *dockertest.Resource + rsyncResource *dockertest.Resource pool *dockertest.Pool defaultRetry = 3 ) @@ -98,6 +100,38 @@ func (j *javascriptSSHServerFingerprint) Execute(filePath string) error { return multierr.Combine(errs...) } +type javascriptRsyncTest struct{} + +func (j *javascriptRsyncTest) Execute(filePath string) error { + if rsyncResource == nil || pool == nil { + // skip test as rsync is not running + return nil + } + tempPort := rsyncResource.GetPort("873/tcp") + finalURL := "localhost:" + tempPort + defer purge(rsyncResource) + errs := []error{} + for i := 0; i < defaultRetry; i++ { + results := []string{} + var err error + _ = pool.Retry(func() error { + //let rsync server start + time.Sleep(3 * time.Second) + results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug) + return nil + }) + if err != nil { + return err + } + if err := expectResultsCount(results, 1); err == nil { + return nil + } else { + errs = append(errs, err) + } + } + return multierr.Combine(errs...) +} + // purge any given resource if it is not nil func purge(resource *dockertest.Resource) { if resource != nil && pool != nil { @@ -163,4 +197,21 @@ func init() { if err := sshResource.Expire(30); err != nil { log.Printf("Could not expire resource: %s", err) } + + // setup a temporary rsync server + rsyncResource, err = pool.RunWithOptions(&dockertest.RunOptions{ + Repository: "alpine", + Tag: "latest", + Cmd: []string{"sh", "-c", "apk add --no-cache rsync shadow && useradd -m rsyncuser && echo 'rsyncuser:mysecret' | chpasswd && echo 'rsyncuser:MySecret123' > /etc/rsyncd.secrets && chmod 600 /etc/rsyncd.secrets && echo -e '[data]\\n path = /data\\n comment = Local Rsync Share\\n read only = false\\n auth users = rsyncuser\\n secrets file = /etc/rsyncd.secrets' > /etc/rsyncd.conf && mkdir -p /data && exec rsync --daemon --no-detach --config=/etc/rsyncd.conf"}, + Platform: "linux/amd64", + }) + if err != nil { + log.Printf("Could not start Rsync resource: %s", err) + return + } + // by default expire after 30 sec + if err := rsyncResource.Expire(30); err != nil { + log.Printf("Could not expire Rsync resource: %s", err) + } + } diff --git a/cmd/nuclei/rsync.yaml b/cmd/nuclei/rsync.yaml deleted file mode 100644 index d67e8f49c4..0000000000 --- a/cmd/nuclei/rsync.yaml +++ /dev/null @@ -1,28 +0,0 @@ -id: rsync-list-shares - -info: - name: Rsync Basic Auth - Detect - author: ciccio - severity: info - -javascript: - - code: | - const rsync = require('nuclei/rsync'); - const client = new rsync.RsyncClient(); - const moduleResponse = client.ListModules(Host, Port, Username, Password); - log(to_json(moduleResponse)); - for (const module of moduleResponse.Modules) { - const fileResponse = client.ListFilesInModule(Host, Port, Username, Password, module); - log(to_json(fileResponse)); - } - - args: - Host: "{{Host}}" - Port: "873" - Username: "{{Username}}" - Password: "{{Password}}" - - matchers: - - type: dsl - dsl: - - "success == true" \ No newline at end of file diff --git a/integration_tests/protocols/javascript/rsync-test.yaml b/integration_tests/protocols/javascript/rsync-test.yaml new file mode 100644 index 0000000000..ce4ae4895e --- /dev/null +++ b/integration_tests/protocols/javascript/rsync-test.yaml @@ -0,0 +1,21 @@ +id: rsync-test + +info: + name: Rsync Test + author: pdteam + severity: info + +javascript: + - code: | + const rsync = require('nuclei/rsync'); + rsync.IsRsync(Host, Port); + + args: + Host: "{{Host}}" + Port: "873" + + matchers: + - type: dsl + dsl: + - "success == true" + \ No newline at end of file From 47f45d330144b70f272cd284d30cb1b456ff0ef2 Mon Sep 17 00:00:00 2001 From: Mzack9999 Date: Wed, 27 Aug 2025 17:45:54 +0200 Subject: [PATCH 5/5] bump go.mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index fe50f42aa6..b77b3a8ff5 100644 --- a/go.mod +++ b/go.mod @@ -50,6 +50,7 @@ require ( github.com/DataDog/gostackparse v0.7.0 github.com/Masterminds/semver/v3 v3.4.0 github.com/Mzack9999/gcache v0.0.0-20230410081825-519e28eab057 + github.com/Mzack9999/go-rsync v0.0.0-20250821180103-81ffa574ef4d github.com/Mzack9999/goja v0.0.0-20250507184235-e46100e9c697 github.com/Mzack9999/goja_nodejs v0.0.0-20250507184139-66bcbf65c883 github.com/alitto/pond v1.9.2 @@ -136,7 +137,6 @@ require ( github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Mzack9999/go-http-digest-auth-client v0.6.1-0.20220414142836-eb8883508809 // indirect - github.com/Mzack9999/go-rsync v0.0.0-20250821180103-81ffa574ef4d // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/PuerkitoBio/goquery v1.10.3 // indirect