Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions cmd/integration-test/javascript.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var jsTestcases = []TestCaseInfo{
{Path: "protocols/javascript/oracle-auth-test.yaml", TestCase: &javascriptOracleAuthTest{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},
{Path: "protocols/javascript/vnc-pass-brute.yaml", TestCase: &javascriptVncPassBrute{}},
{Path: "protocols/javascript/postgres-pass-brute.yaml", TestCase: &javascriptPostgresPassBrute{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},
{Path: "protocols/javascript/mysql-connect.yaml", TestCase: &javascriptMySQLConnect{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},
{Path: "protocols/javascript/multi-ports.yaml", TestCase: &javascriptMultiPortsSSH{}},
{Path: "protocols/javascript/no-port-args.yaml", TestCase: &javascriptNoPortArgs{}},
}
Expand All @@ -28,6 +29,7 @@ var (
oracleResource *dockertest.Resource
vncResource *dockertest.Resource
postgresResource *dockertest.Resource
mysqlResource *dockertest.Resource
pool *dockertest.Pool
defaultRetry = 3
)
Expand Down Expand Up @@ -203,6 +205,38 @@ func (j *javascriptPostgresPassBrute) Execute(filePath string) error {
return multierr.Combine(errs...)
}

type javascriptMySQLConnect struct{}

func (j *javascriptMySQLConnect) Execute(filePath string) error {
if mysqlResource == nil || pool == nil {
// skip test as mysql is not running
return nil
}
tempPort := mysqlResource.GetPort("3306/tcp")
finalURL := "localhost:" + tempPort
defer purge(mysqlResource)
errs := []error{}
for i := 0; i < defaultRetry; i++ {
results := []string{}
var err error
_ = pool.Retry(func() error {
//let mysql server start
time.Sleep(5 * 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...)
}

type javascriptMultiPortsSSH struct{}

func (j *javascriptMultiPortsSSH) Execute(filePath string) error {
Expand Down Expand Up @@ -345,4 +379,22 @@ func init() {
if err := postgresResource.Expire(30); err != nil {
log.Printf("Could not expire postgres resource: %s", err)
}

// setup a temporary mysql instance
mysqlResource, err = pool.RunWithOptions(&dockertest.RunOptions{
Repository: "mysql",
Tag: "latest",
Env: []string{
"MYSQL_ROOT_PASSWORD=secret",
},
Platform: "linux/amd64",
})
if err != nil {
log.Printf("Could not start mysql resource: %s", err)
return
}
// by default expire after 30 sec
if err := mysqlResource.Expire(30); err != nil {
log.Printf("Could not expire mysql resource: %s", err)
}
}
23 changes: 23 additions & 0 deletions integration_tests/protocols/javascript/mysql-connect.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
id: mysql-connect

info:
name: MySQL Connect Test
author: pdteam
severity: high

javascript:
- pre-condition: |
isPortOpen(Host, Port)
code: |
const mysql = require('nuclei/mysql');
const client = new mysql.MySQLClient;
success = client.Connect(Host, Port, User, Pass);
args:
Host: "{{Host}}"
Port: "3306"
User: "root"
Pass: "secret"
matchers:
- type: dsl
dsl:
- "success == true"
4 changes: 2 additions & 2 deletions pkg/js/libs/mssql/memo.mssql.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func memoizedconnect(executionId string, host string, port int, username string, password string, dbName string) (bool, error) {
hash := "connect" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName)
hash := "connect" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connect(executionId, host, port, username, password, dbName)
Expand All @@ -27,7 +27,7 @@ func memoizedconnect(executionId string, host string, port int, username string,
}

func memoizedisMssql(executionId string, host string, port int) (bool, error) {
hash := "isMssql" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isMssql" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isMssql(executionId, host, port)
Expand Down
4 changes: 2 additions & 2 deletions pkg/js/libs/mysql/memo.mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func memoizedisMySQL(executionId string, host string, port int) (bool, error) {
hash := "isMySQL" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isMySQL" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isMySQL(executionId, host, port)
Expand All @@ -25,7 +25,7 @@ func memoizedisMySQL(executionId string, host string, port int) (bool, error) {
}

func memoizedfingerprintMySQL(executionId string, host string, port int) (MySQLInfo, error) {
hash := "fingerprintMySQL" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "fingerprintMySQL" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return fingerprintMySQL(executionId, host, port)
Expand Down
6 changes: 3 additions & 3 deletions pkg/js/libs/mysql/memo.mysql_private.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)

func memoizedconnectWithDSN(dsn string) (bool, error) {
hash := "connectWithDSN" + ":" + fmt.Sprint(dsn)
func memoizedconnectWithDSN(executionId string, dsn string) (bool, error) {
hash := "connectWithDSN" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(dsn)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connectWithDSN(dsn)
return connectWithDSN(executionId, dsn)
})
if err != nil {
return false, err
Expand Down
7 changes: 4 additions & 3 deletions pkg/js/libs/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (c *MySQLClient) Connect(ctx context.Context, host string, port int, userna
if err != nil {
return false, err
}
return connectWithDSN(dsn)
return connectWithDSN(executionId, dsn)
}

type (
Expand Down Expand Up @@ -190,8 +190,9 @@ func fingerprintMySQL(executionId string, host string, port int) (MySQLInfo, err
// const client = new mysql.MySQLClient;
// const connected = client.ConnectWithDSN('username:password@tcp(acme.com:3306)/');
// ```
func (c *MySQLClient) ConnectWithDSN(dsn string) (bool, error) {
return memoizedconnectWithDSN(dsn)
func (c *MySQLClient) ConnectWithDSN(ctx context.Context, dsn string) (bool, error) {
executionId := ctx.Value("executionId").(string)
return memoizedconnectWithDSN(executionId, dsn)
}

// ExecuteQueryWithOpts connects to Mysql database using given credentials
Expand Down
6 changes: 4 additions & 2 deletions pkg/js/libs/mysql/mysql_private.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mysql

import (
"context"
"database/sql"
"fmt"
"net"
Expand Down Expand Up @@ -72,7 +73,7 @@ func BuildDSN(opts MySQLOptions) (string, error) {
}

// @memo
func connectWithDSN(dsn string) (bool, error) {
func connectWithDSN(executionId string, dsn string) (bool, error) {
db, err := sql.Open("mysql", dsn)
if err != nil {
return false, err
Expand All @@ -83,7 +84,8 @@ func connectWithDSN(dsn string) (bool, error) {
db.SetMaxOpenConns(1)
db.SetMaxIdleConns(0)

_, err = db.Exec("select 1")
ctx := context.WithValue(context.Background(), "executionId", executionId) // nolint: staticcheck
err = db.PingContext(ctx)
if err != nil {
return false, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/js/libs/oracle/memo.oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func memoizedisOracle(executionId string, host string, port int) (IsOracleResponse, error) {
hash := "isOracle" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isOracle" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isOracle(executionId, host, port)
Expand Down
2 changes: 1 addition & 1 deletion pkg/js/libs/pop3/memo.pop3.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func memoizedisPoP3(executionId string, host string, port int) (IsPOP3Response, error) {
hash := "isPoP3" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isPoP3" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isPoP3(executionId, host, port)
Expand Down
10 changes: 5 additions & 5 deletions pkg/js/libs/postgres/memo.postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import (
"errors"
"fmt"

_ "github.com/projectdiscovery/nuclei/v3/pkg/js/utils/pgwrap"

utils "github.com/projectdiscovery/nuclei/v3/pkg/js/utils"

_ "github.com/projectdiscovery/nuclei/v3/pkg/js/utils/pgwrap"

"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)

func memoizedisPostgres(executionId string, host string, port int) (bool, error) {
hash := "isPostgres" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isPostgres" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isPostgres(executionId, host, port)
Expand All @@ -29,7 +29,7 @@ func memoizedisPostgres(executionId string, host string, port int) (bool, error)
}

func memoizedexecuteQuery(executionId string, host string, port int, username string, password string, dbName string, query string) (*utils.SQLResult, error) {
hash := "executeQuery" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName) + ":" + fmt.Sprint(query)
hash := "executeQuery" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName) + ":" + fmt.Sprint(query)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return executeQuery(executionId, host, port, username, password, dbName, query)
Expand All @@ -45,7 +45,7 @@ func memoizedexecuteQuery(executionId string, host string, port int, username st
}

func memoizedconnect(executionId string, host string, port int, username string, password string, dbName string) (bool, error) {
hash := "connect" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName)
hash := "connect" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connect(executionId, host, port, username, password, dbName)
Expand Down
6 changes: 3 additions & 3 deletions pkg/js/libs/rdp/memo.rdp.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func memoizedisRDP(executionId string, host string, port int) (IsRDPResponse, error) {
hash := "isRDP" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isRDP" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isRDP(executionId, host, port)
Expand All @@ -25,7 +25,7 @@ func memoizedisRDP(executionId string, host string, port int) (IsRDPResponse, er
}

func memoizedcheckRDPAuth(executionId string, host string, port int) (CheckRDPAuthResponse, error) {
hash := "checkRDPAuth" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "checkRDPAuth" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return checkRDPAuth(executionId, host, port)
Expand All @@ -41,7 +41,7 @@ func memoizedcheckRDPAuth(executionId string, host string, port int) (CheckRDPAu
}

func memoizedcheckRDPEncryption(executionId string, host string, port int) (RDPEncryptionResponse, error) {
hash := "checkRDPEncryption" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "checkRDPEncryption" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return checkRDPEncryption(executionId, host, port)
Expand Down
8 changes: 4 additions & 4 deletions pkg/js/libs/redis/memo.redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func memoizedgetServerInfo(executionId string, host string, port int) (string, error) {
hash := "getServerInfo" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "getServerInfo" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return getServerInfo(executionId, host, port)
Expand All @@ -25,7 +25,7 @@ func memoizedgetServerInfo(executionId string, host string, port int) (string, e
}

func memoizedconnect(executionId string, host string, port int, password string) (bool, error) {
hash := "connect" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(password)
hash := "connect" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(password)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connect(executionId, host, port, password)
Expand All @@ -41,7 +41,7 @@ func memoizedconnect(executionId string, host string, port int, password string)
}

func memoizedgetServerInfoAuth(executionId string, host string, port int, password string) (string, error) {
hash := "getServerInfoAuth" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(password)
hash := "getServerInfoAuth" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(password)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return getServerInfoAuth(executionId, host, port, password)
Expand All @@ -57,7 +57,7 @@ func memoizedgetServerInfoAuth(executionId string, host string, port int, passwo
}

func memoizedisAuthenticated(executionId string, host string, port int) (bool, error) {
hash := "isAuthenticated" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isAuthenticated" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isAuthenticated(executionId, host, port)
Expand Down
2 changes: 1 addition & 1 deletion pkg/js/libs/rsync/memo.rsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func memoizedisRsync(executionId string, host string, port int) (IsRsyncResponse, error) {
hash := "isRsync" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isRsync" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isRsync(executionId, host, port)
Expand Down
4 changes: 2 additions & 2 deletions pkg/js/libs/smb/memo.smb.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func memoizedconnectSMBInfoMode(executionId string, host string, port int) (*smb.SMBLog, error) {
hash := "connectSMBInfoMode" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "connectSMBInfoMode" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connectSMBInfoMode(executionId, host, port)
Expand All @@ -27,7 +27,7 @@ func memoizedconnectSMBInfoMode(executionId string, host string, port int) (*smb
}

func memoizedlistShares(executionId string, host string, port int, user string, password string) ([]string, error) {
hash := "listShares" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(user) + ":" + fmt.Sprint(password)
hash := "listShares" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(user) + ":" + fmt.Sprint(password)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return listShares(executionId, host, port, user, password)
Expand Down
2 changes: 1 addition & 1 deletion pkg/js/libs/smb/memo.smb_private.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func memoizedcollectSMBv2Metadata(executionId string, host string, port int, timeout time.Duration) (*plugins.ServiceSMB, error) {
hash := "collectSMBv2Metadata" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(timeout)
hash := "collectSMBv2Metadata" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(timeout)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return collectSMBv2Metadata(executionId, host, port, timeout)
Expand Down
3 changes: 2 additions & 1 deletion pkg/js/libs/smb/memo.smbghost.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package smb

import (
"errors"

"fmt"

"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)

func memoizeddetectSMBGhost(executionId string, host string, port int) (bool, error) {
hash := "detectSMBGhost" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "detectSMBGhost" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return detectSMBGhost(executionId, host, port)
Expand Down
2 changes: 1 addition & 1 deletion pkg/js/libs/telnet/memo.telnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func memoizedisTelnet(executionId string, host string, port int) (IsTelnetResponse, error) {
hash := "isTelnet" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isTelnet" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isTelnet(executionId, host, port)
Expand Down
2 changes: 1 addition & 1 deletion pkg/js/libs/vnc/memo.vnc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func memoizedisVNC(executionId string, host string, port int) (IsVNCResponse, error) {
hash := "isVNC" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
hash := "isVNC" + ":" + fmt.Sprint(executionId) + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)

v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isVNC(executionId, host, port)
Expand Down
Loading
Loading