yellow.git


yellow

~ opinionated web scanning pipeline for pentesters in a hurry
git clone https://github.com/djnnvx/yellow.git
log | files | refs | archive | README | LICENSE

commit 1b34469d748420716f7cfbf1807efb1d071c8386
parent 4243133a8e44f9b8b95a4775f0410bb6dd02f828
Author: djnn <[email protected]>
Date: Tue, 3 Dec 2024 16:16:04 +0900

feat(cli): adding initial CreateDirectories command

Diffstat:
Acli/parser.go | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acli/types.go | 40++++++++++++++++++++++++++++++++++++++++
Mgo.mod | 7++++++-
Mgo.sum | 12++++++++++--
Ahelpers/directories.go | 32++++++++++++++++++++++++++++++++
Ahelpers/strings.go | 19+++++++++++++++++++
Mmain.go | 9+++++++--

7 files changed, 170 insertions(+), 5 deletions(-)

diff --git a/cli/parser.go b/cli/parser.go
@@ -0,0 +1,56 @@
+package cli
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/spf13/cobra"
+
+	helpers "evil.djnn.sh/djnn/yellow/helpers"
+)
+
+func GetParser(opts *StandardOptions) *cobra.Command {
+
+	var createDirectories = &cobra.Command{
+		Use:   "create",
+		Short: "creates work tree to perform scanning, OSINT, and other targets",
+		Long:  "Obtain a clean-cut architecture at the launch of your assessments",
+		Args:  cobra.MinimumNArgs(0),
+		Run: func(cmd *cobra.Command, args []string) {
+
+			dirname := "./" + helpers.ReplaceWithHyphen(opts.TargetName)
+			fmt.Println("[+] setting up directory architecture for ", dirname)
+
+			_ = os.MkdirAll(dirname, 0775)
+			helpers.CreateDirectory(dirname, []helpers.Folder{
+				{
+					Name:     "scans",
+					Children: helpers.FolderNameFactory("nmap", "infra", "web", "ssl", "screenshots", "nessus"),
+				},
+				{
+					Name:     "extracted",
+					Children: helpers.FolderNameFactory("assets", "creds", "code"),
+				},
+				{
+					Name:     "www",
+					Children: helpers.FolderNameFactory("exploits", "tools"),
+				},
+			})
+
+			fmt.Println("[+] Done. Happy hunting :)~")
+		},
+	}
+
+	defaults := GetDefaultOptions()
+	var rootCmd = createDirectories
+
+	rootCmd.Flags().StringVarP(&opts.TargetName, "target", "t", defaults.TargetName, "Pentest target, will be the name of the directories created, for instance")
+	rootCmd.Flags().BoolVarP(&opts.RunDry, "dry", "d", defaults.RunDry, "Run a dry-run (test mode)")
+	rootCmd.Flags().StringVarP(&opts.Proxy, "proxy", "p", defaults.Proxy, "Proxy URL (used for the tools supporting it. Other will prompt a warning msg)")
+	rootCmd.Flags().BoolVarP(&opts.UseHttpInsecure, "insecure", "k", defaults.UseHttpInsecure, "Ignore SSL warnings and force http")
+	rootCmd.Flags().Int32VarP(&opts.RateLimit, "rate-limit", "r", defaults.RateLimit, "Requests rate-limit (used for the tools supporting it. Other will prompt a warning msg)")
+	rootCmd.Flags().StringVarP(&opts.WordlistPath, "wordlist", "w", defaults.WordlistPath, "Wordlist to use (if any)")
+	rootCmd.Flags().StringVarP(&opts.TargetFilePath, "file", "f", defaults.TargetFilePath, "File containing list of targets (should be a list of IP Addresses or domains)")
+
+	return rootCmd
+}
diff --git a/cli/types.go b/cli/types.go
@@ -0,0 +1,40 @@
+package cli
+
+type StandardOptions struct {
+
+	// Pentest target, will be the name of the directories created, for instance
+	// if no target file is specified for OSINT command, will use that instead
+	TargetName string
+
+	// Run a dry-run (test mode)
+	RunDry bool
+
+	// Proxy URL (used for the tools supporting it. Other will prompt a warning msg)
+	Proxy string
+
+	// Ignore SSL warnings and force http
+	UseHttpInsecure bool
+
+	// Requests rate-limit (used for the tools supporting it. Other will prompt a warning msg)
+	RateLimit int32
+
+	// Wordlist to use (if any)
+	WordlistPath string
+
+	// File containing list of targets (should be a list of IP Addresses or domains)
+	TargetFilePath string
+}
+
+func GetDefaultOptions() StandardOptions {
+	opts := StandardOptions{
+		TargetName:      "",
+		RunDry:          false,
+		Proxy:           "",
+		UseHttpInsecure: false,
+		RateLimit:       0,
+		WordlistPath:    "",
+		TargetFilePath:  "",
+	}
+
+	return opts
+}
diff --git a/go.mod b/go.mod
@@ -2,4 +2,9 @@ module evil.djnn.sh/djnn/yellow
 
 go 1.23
 
-require github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
+require github.com/spf13/cobra v1.8.1
+
+require (
+	github.com/inconshreveable/mousetrap v1.1.0 // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
+)
diff --git a/go.sum b/go.sum
@@ -1,2 +1,10 @@
-github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ=
-github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
+github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/helpers/directories.go b/helpers/directories.go
@@ -0,0 +1,32 @@
+package helper
+
+import (
+	"fmt"
+	"os"
+)
+
+type Folder struct {
+	Name     string
+	Children []Folder
+}
+
+func CreateDirectory(base string, folders []Folder) {
+	for _, f := range folders {
+		current := fmt.Sprintf("%s/%s", base, f.Name)
+		if e := os.Mkdir(current, 0775); e != nil {
+			fmt.Println(e)
+		}
+		if len(f.Children) != 0 {
+			CreateDirectory(current, f.Children)
+		}
+	}
+}
+
+func FolderNameFactory(names ...string) []Folder {
+	f := make([]Folder, len(names))
+	for _, name := range names {
+		f = append(f, Folder{Name: name})
+	}
+
+	return f
+}
diff --git a/helpers/strings.go b/helpers/strings.go
@@ -0,0 +1,19 @@
+package helper
+
+import (
+	"strings"
+	"unicode"
+)
+
+func ReplaceWithHyphen(input string) string {
+	var result strings.Builder
+	for _, r := range input {
+		if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '.' {
+			result.WriteRune(r)
+		} else {
+			result.WriteRune('-')
+		}
+	}
+
+	return result.String()
+}
diff --git a/main.go b/main.go
@@ -1,5 +1,8 @@
 package main
 
+import (
+	"evil.djnn.sh/djnn/yellow/cli"
+)
 
 // skid ascii art
 const ASCII_ART = `
@@ -29,9 +32,11 @@ const ASCII_ART = `
 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠛⠛⠛⠛⠛⠛⠛⠋⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
 `
 
-
 func main() {
-    println(ASCII_ART)
+	println(ASCII_ART)
 
+	opts := cli.GetDefaultOptions()
+	parser := cli.GetParser(&opts)
 
+	parser.ExecuteC()
 }