Path: blob/dev/cmd/integration-test/javascript.go
2843 views
package main12import (3"log"4"time"56"github.com/ory/dockertest/v3"7"github.com/projectdiscovery/nuclei/v3/pkg/testutils"8osutils "github.com/projectdiscovery/utils/os"9"go.uber.org/multierr"10)1112var jsTestcases = []TestCaseInfo{13{Path: "protocols/javascript/redis-pass-brute.yaml", TestCase: &javascriptRedisPassBrute{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},14{Path: "protocols/javascript/ssh-server-fingerprint.yaml", TestCase: &javascriptSSHServerFingerprint{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},15{Path: "protocols/javascript/net-multi-step.yaml", TestCase: &networkMultiStep{}},16{Path: "protocols/javascript/net-https.yaml", TestCase: &javascriptNetHttps{}},17{Path: "protocols/javascript/rsync-test.yaml", TestCase: &javascriptRsyncTest{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},18{Path: "protocols/javascript/oracle-auth-test.yaml", TestCase: &javascriptOracleAuthTest{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},19{Path: "protocols/javascript/vnc-pass-brute.yaml", TestCase: &javascriptVncPassBrute{}},20{Path: "protocols/javascript/postgres-pass-brute.yaml", TestCase: &javascriptPostgresPassBrute{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},21{Path: "protocols/javascript/mysql-connect.yaml", TestCase: &javascriptMySQLConnect{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},22{Path: "protocols/javascript/multi-ports.yaml", TestCase: &javascriptMultiPortsSSH{}},23{Path: "protocols/javascript/no-port-args.yaml", TestCase: &javascriptNoPortArgs{}},24{Path: "protocols/javascript/telnet-auth-test.yaml", TestCase: &javascriptTelnetAuthTest{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},25}2627var (28redisResource *dockertest.Resource29sshResource *dockertest.Resource30oracleResource *dockertest.Resource31vncResource *dockertest.Resource32telnetResource *dockertest.Resource33postgresResource *dockertest.Resource34mysqlResource *dockertest.Resource35rsyncResource *dockertest.Resource36pool *dockertest.Pool37defaultRetry = 338)3940type javascriptNetHttps struct{}4142func (j *javascriptNetHttps) Execute(filePath string) error {43results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "scanme.sh", debug)44if err != nil {45return err46}47return expectResultsCount(results, 1)48}4950type javascriptRedisPassBrute struct{}5152func (j *javascriptRedisPassBrute) Execute(filePath string) error {53if redisResource == nil || pool == nil {54// skip test as redis is not running55return nil56}57tempPort := redisResource.GetPort("6379/tcp")58finalURL := "localhost:" + tempPort59defer purge(redisResource)60errs := []error{}61for i := 0; i < defaultRetry; i++ {62results := []string{}63var err error64_ = pool.Retry(func() error {65//let ssh server start66time.Sleep(3 * time.Second)67results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)68return nil69})70if err != nil {71return err72}73if err := expectResultsCount(results, 1); err == nil {74return nil75} else {76errs = append(errs, err)77}78}79return multierr.Combine(errs...)80}8182type javascriptSSHServerFingerprint struct{}8384func (j *javascriptSSHServerFingerprint) Execute(filePath string) error {85if sshResource == nil || pool == nil {86// skip test as redis is not running87return nil88}89tempPort := sshResource.GetPort("2222/tcp")90finalURL := "localhost:" + tempPort91defer purge(sshResource)92errs := []error{}93for i := 0; i < defaultRetry; i++ {94results := []string{}95var err error96_ = pool.Retry(func() error {97//let ssh server start98time.Sleep(3 * time.Second)99results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)100return nil101})102if err != nil {103return err104}105if err := expectResultsCount(results, 1); err == nil {106return nil107} else {108errs = append(errs, err)109}110}111return multierr.Combine(errs...)112}113114type javascriptOracleAuthTest struct{}115116func (j *javascriptOracleAuthTest) Execute(filePath string) error {117if oracleResource == nil || pool == nil {118// skip test as oracle is not running119return nil120}121tempPort := oracleResource.GetPort("1521/tcp")122finalURL := "localhost:" + tempPort123defer purge(oracleResource)124125errs := []error{}126for i := 0; i < defaultRetry; i++ {127results := []string{}128var err error129_ = pool.Retry(func() error {130// let oracle server start131time.Sleep(3 * time.Second)132results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)133return nil134})135if err != nil {136return err137}138if err := expectResultsCount(results, 1); err == nil {139return nil140} else {141errs = append(errs, err)142}143}144return multierr.Combine(errs...)145}146147type javascriptVncPassBrute struct{}148149func (j *javascriptVncPassBrute) Execute(filePath string) error {150if vncResource == nil || pool == nil {151// skip test as vnc is not running152return nil153}154tempPort := vncResource.GetPort("5900/tcp")155finalURL := "localhost:" + tempPort156defer purge(vncResource)157errs := []error{}158for i := 0; i < defaultRetry; i++ {159results := []string{}160var err error161_ = pool.Retry(func() error {162//let ssh server start163time.Sleep(3 * time.Second)164results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)165return nil166})167if err != nil {168return err169}170if err := expectResultsCount(results, 1); err == nil {171return nil172} else {173errs = append(errs, err)174}175}176return multierr.Combine(errs...)177}178179type javascriptPostgresPassBrute struct{}180181func (j *javascriptPostgresPassBrute) Execute(filePath string) error {182if postgresResource == nil || pool == nil {183// skip test as postgres is not running184return nil185}186tempPort := postgresResource.GetPort("5432/tcp")187finalURL := "localhost:" + tempPort188defer purge(postgresResource)189errs := []error{}190for i := 0; i < defaultRetry; i++ {191results := []string{}192var err error193_ = pool.Retry(func() error {194//let postgres server start195time.Sleep(3 * time.Second)196results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)197return nil198})199if err != nil {200return err201}202if err := expectResultsCount(results, 1); err == nil {203return nil204} else {205errs = append(errs, err)206}207}208return multierr.Combine(errs...)209}210211type javascriptMySQLConnect struct{}212213func (j *javascriptMySQLConnect) Execute(filePath string) error {214if mysqlResource == nil || pool == nil {215// skip test as mysql is not running216return nil217}218tempPort := mysqlResource.GetPort("3306/tcp")219finalURL := "localhost:" + tempPort220defer purge(mysqlResource)221errs := []error{}222for i := 0; i < defaultRetry; i++ {223results := []string{}224var err error225_ = pool.Retry(func() error {226//let mysql server start227time.Sleep(5 * time.Second)228results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)229return nil230})231if err != nil {232return err233}234if err := expectResultsCount(results, 1); err == nil {235return nil236} else {237errs = append(errs, err)238}239}240return multierr.Combine(errs...)241}242243type javascriptMultiPortsSSH struct{}244245func (j *javascriptMultiPortsSSH) Execute(filePath string) error {246// use scanme.sh as target to ensure we match on the 2nd default port 22247results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "scanme.sh", debug)248if err != nil {249return err250}251return expectResultsCount(results, 1)252}253254type javascriptNoPortArgs struct{}255256func (j *javascriptNoPortArgs) Execute(filePath string) error {257results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "yo.dawg", debug)258if err != nil {259return err260}261return expectResultsCount(results, 1)262}263264type javascriptRsyncTest struct{}265266func (j *javascriptRsyncTest) Execute(filePath string) error {267if rsyncResource == nil || pool == nil {268// skip test as rsync is not running269return nil270}271tempPort := rsyncResource.GetPort("873/tcp")272finalURL := "localhost:" + tempPort273defer purge(rsyncResource)274errs := []error{}275for i := 0; i < defaultRetry; i++ {276results := []string{}277var err error278_ = pool.Retry(func() error {279//let rsync server start280time.Sleep(3 * time.Second)281results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)282return nil283})284if err != nil {285return err286}287if err := expectResultsCount(results, 1); err == nil {288return nil289} else {290errs = append(errs, err)291}292}293return multierr.Combine(errs...)294}295296type javascriptTelnetAuthTest struct{}297298func (j *javascriptTelnetAuthTest) Execute(filePath string) error {299if telnetResource == nil || pool == nil {300// skip test as telnet is not running301return nil302}303tempPort := telnetResource.GetPort("23/tcp")304finalURL := "localhost:" + tempPort305defer purge(telnetResource)306errs := []error{}307for i := 0; i < defaultRetry; i++ {308results := []string{}309var err error310_ = pool.Retry(func() error {311//let telnet server start312time.Sleep(3 * time.Second)313results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)314return nil315})316if err != nil {317return err318}319if err := expectResultsCount(results, 1); err == nil {320return nil321} else {322errs = append(errs, err)323}324}325return multierr.Combine(errs...)326}327328// purge any given resource if it is not nil329func purge(resource *dockertest.Resource) {330if resource != nil && pool != nil {331containerName := resource.Container.Name332_ = pool.Client.StopContainer(resource.Container.ID, 0)333err := pool.Purge(resource)334if err != nil {335log.Printf("Could not purge resource: %s", err)336}337_ = pool.RemoveContainerByName(containerName)338}339}340341func init() {342// uses a sensible default on windows (tcp/http) and linux/osx (socket)343pool, err := dockertest.NewPool("")344if err != nil {345log.Printf("something went wrong with dockertest: %s", err)346return347}348349// uses pool to try to connect to Docker350err = pool.Client.Ping()351if err != nil {352log.Printf("Could not connect to Docker: %s", err)353}354355// setup a temporary redis instance356redisResource, err = pool.RunWithOptions(&dockertest.RunOptions{357Repository: "redis",358Tag: "latest",359Cmd: []string{"redis-server", "--requirepass", "iamadmin"},360Platform: "linux/amd64",361})362if err != nil {363log.Printf("Could not start resource: %s", err)364return365}366// by default expire after 30 sec367if err := redisResource.Expire(30); err != nil {368log.Printf("Could not expire resource: %s", err)369}370371// setup a temporary ssh server372sshResource, err = pool.RunWithOptions(&dockertest.RunOptions{373Repository: "lscr.io/linuxserver/openssh-server",374Tag: "latest",375Env: []string{376"PUID=1000",377"PGID=1000",378"TZ=Etc/UTC",379"PASSWORD_ACCESS=true",380"USER_NAME=admin",381"USER_PASSWORD=admin",382},383Platform: "linux/amd64",384})385if err != nil {386log.Printf("Could not start resource: %s", err)387return388}389// by default expire after 30 sec390if err := sshResource.Expire(30); err != nil {391log.Printf("Could not expire resource: %s", err)392}393394// setup a temporary oracle instance395oracleResource, err = pool.RunWithOptions(&dockertest.RunOptions{396Repository: "gvenzl/oracle-xe",397Tag: "latest",398Env: []string{399"ORACLE_PASSWORD=mysecret",400},401Platform: "linux/amd64",402})403if err != nil {404log.Printf("Could not start Oracle resource: %s", err)405return406}407408// by default expire after 30 sec409if err := oracleResource.Expire(30); err != nil {410log.Printf("Could not expire Oracle resource: %s", err)411}412413// setup a temporary vnc server414vncResource, err = pool.RunWithOptions(&dockertest.RunOptions{415Repository: "dorowu/ubuntu-desktop-lxde-vnc",416Tag: "latest",417Env: []string{418"VNC_PASSWORD=mysecret",419},420Platform: "linux/amd64",421})422if err != nil {423log.Printf("Could not start resource: %s", err)424return425}426// by default expire after 30 sec427if err := vncResource.Expire(30); err != nil {428log.Printf("Could not expire resource: %s", err)429}430431// setup a temporary postgres instance432postgresResource, err = pool.RunWithOptions(&dockertest.RunOptions{433Repository: "postgres",434Tag: "latest",435Env: []string{436"POSTGRES_PASSWORD=postgres",437"POSTGRES_USER=postgres",438},439Platform: "linux/amd64",440})441if err != nil {442log.Printf("Could not start postgres resource: %s", err)443return444}445// by default expire after 30 sec446if err := postgresResource.Expire(30); err != nil {447log.Printf("Could not expire postgres resource: %s", err)448}449450// setup a temporary mysql instance451mysqlResource, err = pool.RunWithOptions(&dockertest.RunOptions{452Repository: "mysql",453Tag: "latest",454Env: []string{455"MYSQL_ROOT_PASSWORD=secret",456},457Platform: "linux/amd64",458})459if err != nil {460log.Printf("Could not start mysql resource: %s", err)461return462}463// by default expire after 30 sec464if err := mysqlResource.Expire(30); err != nil {465log.Printf("Could not expire mysql resource: %s", err)466}467468// setup a temporary rsync server469rsyncResource, err = pool.RunWithOptions(&dockertest.RunOptions{470Repository: "alpine",471Tag: "latest",472Cmd: []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"},473Platform: "linux/amd64",474})475if err != nil {476log.Printf("Could not start Rsync resource: %s", err)477return478}479// by default expire after 30 sec480if err := rsyncResource.Expire(30); err != nil {481log.Printf("Could not expire Rsync resource: %s", err)482}483484// setup a temporary telnet server485// username: dev486// password: mysecret487telnetResource, err = pool.RunWithOptions(&dockertest.RunOptions{488Repository: "alpine",489Tag: "latest",490Cmd: []string{"sh", "-c", "apk add --no-cache busybox-extras shadow && useradd -m dev && echo 'dev:mysecret' | chpasswd && exec /usr/sbin/telnetd -F -p 23 -l /bin/login"},491Platform: "linux/amd64",492})493if err != nil {494log.Printf("Could not start Telnet resource: %s", err)495return496}497// by default expire after 30 sec498if err := telnetResource.Expire(30); err != nil {499log.Printf("Could not expire Telnet resource: %s", err)500}501}502503504