mirror of https://github.com/daffainfo/nuclei.git
167 lines
4.4 KiB
Go
167 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/ory/dockertest/v3"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/testutils"
|
|
osutils "github.com/projectdiscovery/utils/os"
|
|
"go.uber.org/multierr"
|
|
)
|
|
|
|
var jsTestcases = []TestCaseInfo{
|
|
{Path: "protocols/javascript/redis-pass-brute.yaml", TestCase: &javascriptRedisPassBrute{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},
|
|
{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{}},
|
|
}
|
|
|
|
var (
|
|
redisResource *dockertest.Resource
|
|
sshResource *dockertest.Resource
|
|
pool *dockertest.Pool
|
|
defaultRetry = 3
|
|
)
|
|
|
|
type javascriptNetHttps struct{}
|
|
|
|
func (j *javascriptNetHttps) Execute(filePath string) error {
|
|
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "scanme.sh", debug)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return expectResultsCount(results, 1)
|
|
}
|
|
|
|
type javascriptRedisPassBrute struct{}
|
|
|
|
func (j *javascriptRedisPassBrute) Execute(filePath string) error {
|
|
if redisResource == nil || pool == nil {
|
|
// skip test as redis is not running
|
|
return nil
|
|
}
|
|
tempPort := redisResource.GetPort("6379/tcp")
|
|
finalURL := "localhost:" + tempPort
|
|
defer purge(redisResource)
|
|
errs := []error{}
|
|
for i := 0; i < defaultRetry; i++ {
|
|
results := []string{}
|
|
var err error
|
|
_ = pool.Retry(func() error {
|
|
//let ssh 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...)
|
|
}
|
|
|
|
type javascriptSSHServerFingerprint struct{}
|
|
|
|
func (j *javascriptSSHServerFingerprint) Execute(filePath string) error {
|
|
if sshResource == nil || pool == nil {
|
|
// skip test as redis is not running
|
|
return nil
|
|
}
|
|
tempPort := sshResource.GetPort("2222/tcp")
|
|
finalURL := "localhost:" + tempPort
|
|
defer purge(sshResource)
|
|
errs := []error{}
|
|
for i := 0; i < defaultRetry; i++ {
|
|
results := []string{}
|
|
var err error
|
|
_ = pool.Retry(func() error {
|
|
//let ssh 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 {
|
|
containerName := resource.Container.Name
|
|
_ = pool.Client.StopContainer(resource.Container.ID, 0)
|
|
err := pool.Purge(resource)
|
|
if err != nil {
|
|
log.Printf("Could not purge resource: %s", err)
|
|
}
|
|
_ = pool.RemoveContainerByName(containerName)
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
|
|
pool, err := dockertest.NewPool("")
|
|
if err != nil {
|
|
log.Printf("something went wrong with dockertest: %s", err)
|
|
return
|
|
}
|
|
|
|
// uses pool to try to connect to Docker
|
|
err = pool.Client.Ping()
|
|
if err != nil {
|
|
log.Printf("Could not connect to Docker: %s", err)
|
|
}
|
|
|
|
// setup a temporary redis instance
|
|
redisResource, err = pool.RunWithOptions(&dockertest.RunOptions{
|
|
Repository: "redis",
|
|
Tag: "latest",
|
|
Cmd: []string{"redis-server", "--requirepass", "iamadmin"},
|
|
Platform: "linux/amd64",
|
|
})
|
|
if err != nil {
|
|
log.Printf("Could not start resource: %s", err)
|
|
return
|
|
}
|
|
// by default expire after 30 sec
|
|
if err := redisResource.Expire(30); err != nil {
|
|
log.Printf("Could not expire resource: %s", err)
|
|
}
|
|
|
|
// setup a temporary ssh server
|
|
sshResource, err = pool.RunWithOptions(&dockertest.RunOptions{
|
|
Repository: "lscr.io/linuxserver/openssh-server",
|
|
Tag: "latest",
|
|
Env: []string{
|
|
"PUID=1000",
|
|
"PGID=1000",
|
|
"TZ=Etc/UTC",
|
|
"PASSWORD_ACCESS=true",
|
|
"USER_NAME=admin",
|
|
"USER_PASSWORD=admin",
|
|
},
|
|
Platform: "linux/amd64",
|
|
})
|
|
if err != nil {
|
|
log.Printf("Could not start resource: %s", err)
|
|
return
|
|
}
|
|
// by default expire after 30 sec
|
|
if err := sshResource.Expire(30); err != nil {
|
|
log.Printf("Could not expire resource: %s", err)
|
|
}
|
|
}
|