2021-02-25 18:02:43 +00:00
|
|
|
package testutils
|
|
|
|
|
|
|
|
import (
|
2022-01-27 20:29:28 +00:00
|
|
|
"crypto/tls"
|
2021-07-30 09:59:12 +00:00
|
|
|
"errors"
|
2021-10-01 15:23:06 +00:00
|
|
|
"fmt"
|
2021-02-25 18:02:43 +00:00
|
|
|
"net"
|
2021-11-01 10:17:20 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2021-02-25 18:02:43 +00:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
2021-07-30 09:59:12 +00:00
|
|
|
"regexp"
|
2021-02-25 18:02:43 +00:00
|
|
|
"strings"
|
2021-11-01 10:17:20 +00:00
|
|
|
|
|
|
|
"github.com/gobwas/ws"
|
2021-11-01 10:21:56 +00:00
|
|
|
"github.com/julienschmidt/httprouter"
|
2021-02-25 18:02:43 +00:00
|
|
|
)
|
|
|
|
|
2021-10-01 15:23:06 +00:00
|
|
|
// RunNucleiTemplateAndGetResults returns a list of results for a template
|
|
|
|
func RunNucleiTemplateAndGetResults(template, url string, debug bool, extra ...string) ([]string, error) {
|
2021-10-14 21:30:51 +00:00
|
|
|
return RunNucleiAndGetResults(true, template, url, debug, extra...)
|
2021-10-01 15:23:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RunNucleiWorkflowAndGetResults returns a list of results for a workflow
|
|
|
|
func RunNucleiWorkflowAndGetResults(template, url string, debug bool, extra ...string) ([]string, error) {
|
2021-10-14 21:30:51 +00:00
|
|
|
return RunNucleiAndGetResults(false, template, url, debug, extra...)
|
2021-10-01 15:23:06 +00:00
|
|
|
}
|
|
|
|
|
2021-10-14 21:30:51 +00:00
|
|
|
func RunNucleiAndGetResults(isTemplate bool, template, url string, debug bool, extra ...string) ([]string, error) {
|
2021-10-01 15:23:06 +00:00
|
|
|
var templateOrWorkflowFlag string
|
|
|
|
if isTemplate {
|
|
|
|
templateOrWorkflowFlag = "-t"
|
|
|
|
} else {
|
|
|
|
templateOrWorkflowFlag = "-w"
|
|
|
|
}
|
|
|
|
|
2021-10-14 21:30:51 +00:00
|
|
|
return RunNucleiBareArgsAndGetResults(debug, append([]string{
|
|
|
|
templateOrWorkflowFlag,
|
|
|
|
template,
|
|
|
|
"-target",
|
|
|
|
url,
|
|
|
|
}, extra...)...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func RunNucleiBareArgsAndGetResults(debug bool, extra ...string) ([]string, error) {
|
|
|
|
cmd := exec.Command("./nuclei")
|
2021-12-14 16:13:53 +00:00
|
|
|
cmd.Args = append(cmd.Args, extra...)
|
2021-02-25 18:02:43 +00:00
|
|
|
if debug {
|
2021-10-14 21:30:51 +00:00
|
|
|
cmd.Args = append(cmd.Args, "-debug")
|
2021-02-25 18:02:43 +00:00
|
|
|
cmd.Stderr = os.Stderr
|
2021-10-01 15:23:06 +00:00
|
|
|
fmt.Println(cmd.String())
|
2021-10-14 21:30:51 +00:00
|
|
|
} else {
|
|
|
|
cmd.Args = append(cmd.Args, "-silent")
|
2021-02-25 18:02:43 +00:00
|
|
|
}
|
|
|
|
data, err := cmd.Output()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-10-01 15:23:06 +00:00
|
|
|
var parts []string
|
2021-03-05 06:38:31 +00:00
|
|
|
items := strings.Split(string(data), "\n")
|
|
|
|
for _, i := range items {
|
|
|
|
if i != "" {
|
|
|
|
parts = append(parts, i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return parts, nil
|
|
|
|
}
|
|
|
|
|
2021-09-03 14:44:00 +00:00
|
|
|
var templateLoaded = regexp.MustCompile(`(?:Templates|Workflows) loaded[^:]*: (\d+)`)
|
2021-07-30 09:59:12 +00:00
|
|
|
|
2021-09-03 14:25:50 +00:00
|
|
|
// RunNucleiBinaryAndGetLoadedTemplates returns a list of results for a template
|
2021-10-01 15:23:06 +00:00
|
|
|
func RunNucleiBinaryAndGetLoadedTemplates(nucleiBinary string, debug bool, args []string) (string, error) {
|
2021-07-30 09:59:12 +00:00
|
|
|
cmd := exec.Command(nucleiBinary, args...)
|
2021-10-01 15:23:06 +00:00
|
|
|
if debug {
|
2021-12-14 16:13:53 +00:00
|
|
|
cmd.Args = append(cmd.Args, "-debug")
|
2021-10-01 15:23:06 +00:00
|
|
|
fmt.Println(cmd.String())
|
|
|
|
}
|
2021-07-30 09:59:12 +00:00
|
|
|
data, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
matches := templateLoaded.FindAllStringSubmatch(string(data), -1)
|
|
|
|
if len(matches) == 0 {
|
|
|
|
return "", errors.New("no matches found")
|
|
|
|
}
|
|
|
|
return matches[0][1], nil
|
|
|
|
}
|
|
|
|
|
2021-02-25 18:02:43 +00:00
|
|
|
// TestCase is a single integration test case
|
|
|
|
type TestCase interface {
|
2021-02-26 07:43:11 +00:00
|
|
|
// Execute executes a test case and returns any errors if occurred
|
2021-02-25 18:02:43 +00:00
|
|
|
Execute(filePath string) error
|
|
|
|
}
|
|
|
|
|
|
|
|
// TCPServer creates a new tcp server that returns a response
|
|
|
|
type TCPServer struct {
|
|
|
|
URL string
|
|
|
|
listener net.Listener
|
|
|
|
}
|
|
|
|
|
2022-01-27 20:29:28 +00:00
|
|
|
// keys taken from https://pascal.bach.ch/2015/12/17/from-tcp-to-tls-in-go/
|
|
|
|
const serverKey = `-----BEGIN EC PARAMETERS-----
|
|
|
|
BggqhkjOPQMBBw==
|
|
|
|
-----END EC PARAMETERS-----
|
|
|
|
-----BEGIN EC PRIVATE KEY-----
|
|
|
|
MHcCAQEEIHg+g2unjA5BkDtXSN9ShN7kbPlbCcqcYdDu+QeV8XWuoAoGCCqGSM49
|
|
|
|
AwEHoUQDQgAEcZpodWh3SEs5Hh3rrEiu1LZOYSaNIWO34MgRxvqwz1FMpLxNlx0G
|
|
|
|
cSqrxhPubawptX5MSr02ft32kfOlYbaF5Q==
|
|
|
|
-----END EC PRIVATE KEY-----
|
|
|
|
`
|
|
|
|
|
|
|
|
const serverCert = `-----BEGIN CERTIFICATE-----
|
|
|
|
MIIB+TCCAZ+gAwIBAgIJAL05LKXo6PrrMAoGCCqGSM49BAMCMFkxCzAJBgNVBAYT
|
|
|
|
AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
|
|
|
|
aXRzIFB0eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNTEyMDgxNDAxMTNa
|
|
|
|
Fw0yNTEyMDUxNDAxMTNaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0
|
|
|
|
YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMM
|
|
|
|
CWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHGaaHVod0hLOR4d
|
|
|
|
66xIrtS2TmEmjSFjt+DIEcb6sM9RTKS8TZcdBnEqq8YT7m2sKbV+TEq9Nn7d9pHz
|
|
|
|
pWG2heWjUDBOMB0GA1UdDgQWBBR0fqrecDJ44D/fiYJiOeBzfoqEijAfBgNVHSME
|
|
|
|
GDAWgBR0fqrecDJ44D/fiYJiOeBzfoqEijAMBgNVHRMEBTADAQH/MAoGCCqGSM49
|
|
|
|
BAMCA0gAMEUCIEKzVMF3JqjQjuM2rX7Rx8hancI5KJhwfeKu1xbyR7XaAiEA2UT7
|
|
|
|
1xOP035EcraRmWPe7tO0LpXgMxlh2VItpc2uc2w=
|
|
|
|
-----END CERTIFICATE-----
|
|
|
|
`
|
|
|
|
|
2021-02-25 18:02:43 +00:00
|
|
|
// NewTCPServer creates a new TCP server from a handler
|
2022-01-27 20:29:28 +00:00
|
|
|
func NewTCPServer(withTls bool, port int, handler func(conn net.Conn)) *TCPServer {
|
2021-02-25 18:02:43 +00:00
|
|
|
server := &TCPServer{}
|
|
|
|
|
2022-01-27 20:29:28 +00:00
|
|
|
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
|
2021-02-25 18:02:43 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
server.URL = l.Addr().String()
|
|
|
|
server.listener = l
|
|
|
|
|
2022-01-27 20:29:28 +00:00
|
|
|
cer, err := tls.X509KeyPair([]byte(serverCert), []byte(serverKey))
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
config := &tls.Config{Certificates: []tls.Certificate{cer}}
|
|
|
|
|
2021-02-25 18:02:43 +00:00
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
// Listen for an incoming connection.
|
|
|
|
conn, err := l.Accept()
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// Handle connections in a new goroutine.
|
2022-01-27 20:29:28 +00:00
|
|
|
if withTls {
|
|
|
|
connTls := tls.Server(conn, config)
|
|
|
|
go handler(connTls)
|
|
|
|
} else {
|
|
|
|
go handler(conn)
|
|
|
|
}
|
2021-02-25 18:02:43 +00:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
return server
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close closes the TCP server
|
|
|
|
func (s *TCPServer) Close() {
|
|
|
|
s.listener.Close()
|
|
|
|
}
|
2021-11-01 10:17:20 +00:00
|
|
|
|
|
|
|
// NewWebsocketServer creates a new websocket server from a handler
|
2021-11-01 10:21:56 +00:00
|
|
|
func NewWebsocketServer(path string, handler func(conn net.Conn), originValidate func(origin string) bool, port ...int) *httptest.Server {
|
|
|
|
handlerFunc := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2021-11-01 10:17:20 +00:00
|
|
|
if value := r.Header.Get("Origin"); value != "" && !originValidate(value) {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
conn, _, _, err := ws.UpgradeHTTP(r, w)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
go func() {
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
|
handler(conn)
|
|
|
|
}()
|
2021-11-01 10:21:56 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
if path != "" {
|
2021-11-02 21:04:48 +00:00
|
|
|
router := httprouter.New()
|
2021-11-01 10:21:56 +00:00
|
|
|
router.HandlerFunc("*", "/test", handlerFunc)
|
2021-11-02 21:04:48 +00:00
|
|
|
return httptest.NewServer(router)
|
2021-11-01 10:21:56 +00:00
|
|
|
}
|
2021-11-02 21:04:48 +00:00
|
|
|
return httptest.NewServer(handlerFunc)
|
2021-11-01 10:17:20 +00:00
|
|
|
}
|