diff --git a/Changelog.md b/Changelog.md
@@ -5,6 +5,7 @@
- fix(scan): adding --no-dirbusting ~ @djnnvx
- feat(meta): adding run-web-recon script ~ @djnnvx
- feat(cmd): adding fingerprint subcommand ~ @djnnvx
+- feat(cmd): adding prune subcommand ~ @djnnvx
## v0.0.3
diff --git a/cli/parser.go b/cli/parser.go
@@ -9,11 +9,36 @@ import (
"evil.djnn.sh/djnn/yellow/helpers"
"evil.djnn.sh/djnn/yellow/osint"
+ "evil.djnn.sh/djnn/yellow/prune"
"evil.djnn.sh/djnn/yellow/scan"
)
func GetParser(opts *StandardOptions) *cobra.Command {
+ var pruneCmd = &cobra.Command{
+ Use: "prune",
+ Short: "filters a file full of domains",
+ Long: "filters a file full of domains to only get the reachable domains",
+ Args: cobra.MinimumNArgs(0),
+ Run: func(cmd *cobra.Command, args []string) {
+
+ if opts.TargetFilePath == "" {
+ fmt.Println("[!] Error: target cannot be empty. Please run with --file [something]")
+ fmt.Println("\nIf you're confused, feel free to use --help option. :)~")
+ os.Exit(1)
+ }
+
+ pruneOpts := prune.PruneOpts{}
+ pruneOpts.SetProxy(opts.Proxy)
+ pruneOpts.SetDryRun(opts.RunDry)
+ pruneOpts.SetForceInsecure(opts.UseHttpInsecure)
+ pruneOpts.SetInFilePath(opts.TargetFilePath)
+ pruneOpts.SetOutFilePath(opts.OutName)
+
+ pruneOpts.Run()
+ },
+ }
+
var fingerprintCmd = &cobra.Command{
Use: "fingerprint",
Short: "Runs fingerprinting against websites",
@@ -21,7 +46,7 @@ func GetParser(opts *StandardOptions) *cobra.Command {
Args: cobra.MinimumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
- if opts.OutDirName == "" && opts.TargetFilePath == "" {
+ if opts.OutName == "" && opts.TargetFilePath == "" {
fmt.Println("[!] Error: target cannot be empty. Please run with --target [something] or --file [something]")
fmt.Println("\nIf you're confused, feel free to use --help option. :)~")
os.Exit(1)
@@ -30,13 +55,13 @@ func GetParser(opts *StandardOptions) *cobra.Command {
helper.CheckProxy(opts.Proxy)
helper.DisplayNetInfo()
- if opts.OutDirName == "" || !helper.Exists(opts.OutDirName) {
+ if opts.OutName == "" || !helper.Exists(opts.OutName) {
println("[!] collected assets will be sent to current working directory")
}
scanOpts := scan.ScanOpts{}
- scanOpts.SetDomain(opts.OutDirName)
- scanOpts.SetScanPath(opts.OutDirName)
+ scanOpts.SetDomain(opts.OutName)
+ scanOpts.SetScanPath(opts.OutName)
scanOpts.SetProxy(opts.Proxy)
scanOpts.SetDryRun(opts.RunDry)
scanOpts.SetRateLimit(opts.RateLimit)
@@ -67,7 +92,7 @@ func GetParser(opts *StandardOptions) *cobra.Command {
Args: cobra.MinimumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
- if opts.OutDirName == "" && opts.TargetFilePath == "" {
+ if opts.OutName == "" && opts.TargetFilePath == "" {
fmt.Println("[!] Error: target cannot be empty. Please run with --target [something] or --file [something]")
fmt.Println("\nIf you're confused, feel free to use --help option. :)~")
os.Exit(1)
@@ -76,13 +101,13 @@ func GetParser(opts *StandardOptions) *cobra.Command {
helper.CheckProxy(opts.Proxy)
helper.DisplayNetInfo()
- if opts.OutDirName == "" || !helper.Exists(opts.OutDirName) {
+ if opts.OutName == "" || !helper.Exists(opts.OutName) {
println("[!] collected assets will be sent to current working directory")
}
scanOpts := scan.ScanOpts{}
- scanOpts.SetDomain(opts.OutDirName)
- scanOpts.SetScanPath(opts.OutDirName)
+ scanOpts.SetDomain(opts.OutName)
+ scanOpts.SetScanPath(opts.OutName)
scanOpts.SetProxy(opts.Proxy)
scanOpts.SetDryRun(opts.RunDry)
scanOpts.SetRateLimit(opts.RateLimit)
@@ -113,7 +138,7 @@ func GetParser(opts *StandardOptions) *cobra.Command {
Args: cobra.MinimumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
- if opts.OutDirName == "" && opts.TargetFilePath == "" {
+ if opts.OutName == "" && opts.TargetFilePath == "" {
fmt.Println("[!] Error: target cannot be empty. Please run with --target [something] or --file [something]")
fmt.Println("\nIf you're confused, feel free to use --help option. :)~")
os.Exit(1)
@@ -122,20 +147,20 @@ func GetParser(opts *StandardOptions) *cobra.Command {
helper.CheckProxy(opts.Proxy)
helper.DisplayNetInfo()
- if opts.OutDirName == "" || !helper.Exists(opts.OutDirName) {
+ if opts.OutName == "" || !helper.Exists(opts.OutName) {
println("[!] collected assets will be sent to current working directory")
}
osintOpts := osint.OsintOpts{}
- osintOpts.SetDomain(opts.OutDirName)
- osintOpts.SetScanPath(opts.OutDirName)
+ osintOpts.SetDomain(opts.OutName)
+ osintOpts.SetScanPath(opts.OutName)
osintOpts.SetProxy(opts.Proxy)
osintOpts.SetDryRun(opts.RunDry)
osintOpts.SetRateLimit(opts.RateLimit)
// if used create subcommand, put the results in scans
- if helper.Exists(opts.OutDirName + "/scans/") {
- osintOpts.SetScanPath(opts.OutDirName + "/scans")
+ if helper.Exists(opts.OutName + "/scans/") {
+ osintOpts.SetScanPath(opts.OutName + "/scans")
}
if opts.TargetFilePath == "" {
@@ -161,19 +186,19 @@ func GetParser(opts *StandardOptions) *cobra.Command {
Args: cobra.MinimumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
- if opts.OutDirName == "" {
+ if opts.OutName == "" {
fmt.Println("[!] Error: target cannot be empty. Please run with --target [something]")
fmt.Println("\nIf you're confused, feel free to use --help option. :)~")
os.Exit(1)
}
- if strings.Contains(opts.OutDirName, ",") {
- directories := strings.Split(opts.OutDirName, ",")
+ if strings.Contains(opts.OutName, ",") {
+ directories := strings.Split(opts.OutName, ",")
for _, d := range directories {
helper.SetUpDirectoryArchitecture(d)
}
} else {
- helper.SetUpDirectoryArchitecture(opts.OutDirName)
+ helper.SetUpDirectoryArchitecture(opts.OutName)
}
fmt.Println("[+] Done. Happy hunting :)~")
@@ -182,17 +207,17 @@ func GetParser(opts *StandardOptions) *cobra.Command {
defaults := GetDefaultOptions()
var rootCmd = createDirectories
- rootCmd.Flags().StringVarP(&opts.OutDirName, "dir-name", "d", defaults.OutDirName, "Directory name to create (you can also put multiple names and separate them with a ,)")
+ rootCmd.Flags().StringVarP(&opts.OutName, "dir-name", "d", defaults.OutName, "Directory name to create (you can also put multiple names and separate them with a ,)")
rootCmd.AddCommand(osintCmd)
- osintCmd.Flags().StringVarP(&opts.OutDirName, "dir-name", "d", defaults.OutDirName, "Outfile directory name (if no target-file is specified, will also be target domain)")
+ osintCmd.Flags().StringVarP(&opts.OutName, "dir-name", "d", defaults.OutName, "Outfile directory name (if no target-file is specified, will also be target domain)")
osintCmd.Flags().StringVarP(&opts.Proxy, "proxy", "p", defaults.Proxy, "Proxy URL (used for the tools supporting it. Other will prompt a warning msg)")
osintCmd.Flags().BoolVarP(&opts.RunDry, "dry", "", defaults.RunDry, "Run a dry-run (test mode)")
osintCmd.Flags().Int32VarP(&opts.RateLimit, "rate-limit", "r", defaults.RateLimit, "Requests rate-limit (used for the tools supporting it. Other will prompt a warning msg)")
osintCmd.Flags().StringVarP(&opts.TargetFilePath, "file", "f", defaults.TargetFilePath, "File containing list of targets (should be a list of IP Addresses or domains)")
rootCmd.AddCommand(scanCmd)
- scanCmd.Flags().StringVarP(&opts.OutDirName, "dir-name", "d", defaults.OutDirName, "Outfile directory name (if no target-file is specified, will also be target domain)")
+ scanCmd.Flags().StringVarP(&opts.OutName, "dir-name", "d", defaults.OutName, "Outfile directory name (if no target-file is specified, will also be target domain)")
scanCmd.Flags().StringVarP(&opts.Proxy, "proxy", "p", defaults.Proxy, "Proxy URL (used for the tools supporting it. Other will prompt a warning msg)")
scanCmd.Flags().BoolVarP(&opts.RunDry, "dry", "", defaults.RunDry, "Run a dry-run (test mode)")
scanCmd.Flags().BoolVarP(&opts.NoGobuster, "disable-dirbusting", "", defaults.NoGobuster, "Disable directory bruteforce (sometimes you don't need it yk...)")
@@ -201,8 +226,15 @@ func GetParser(opts *StandardOptions) *cobra.Command {
scanCmd.Flags().StringVarP(&opts.WordlistPath, "wordlist", "w", defaults.WordlistPath, "Wordlist to use")
scanCmd.Flags().StringVarP(&opts.TargetFilePath, "file", "f", defaults.TargetFilePath, "File containing list of targets (should be a list of IP Addresses or domains)")
+ rootCmd.AddCommand(pruneCmd)
+ pruneCmd.Flags().StringVarP(&opts.OutName, "dir-name", "d", defaults.OutName, "Outfile directory name (if no target-file is specified, will also be target domain)")
+ pruneCmd.Flags().StringVarP(&opts.Proxy, "proxy", "p", defaults.Proxy, "Proxy URL (used for the tools supporting it. Other will prompt a warning msg)")
+ pruneCmd.Flags().BoolVarP(&opts.UseHttpInsecure, "insecure", "k", defaults.UseHttpInsecure, "Ignore SSL warnings and force http")
+ pruneCmd.Flags().StringVarP(&opts.TargetFilePath, "file", "f", defaults.TargetFilePath, "File containing list of targets (should be a list of IP Addresses or domains)")
+ pruneCmd.Flags().StringVarP(&opts.OutName, "out", "o", defaults.OutName, "output file path")
+
rootCmd.AddCommand(fingerprintCmd)
- fingerprintCmd.Flags().StringVarP(&opts.OutDirName, "dir-name", "d", defaults.OutDirName, "Outfile directory name (if no target-file is specified, will also be target domain)")
+ fingerprintCmd.Flags().StringVarP(&opts.OutName, "dir-name", "d", defaults.OutName, "Outfile directory name (if no target-file is specified, will also be target domain)")
fingerprintCmd.Flags().StringVarP(&opts.Proxy, "proxy", "p", defaults.Proxy, "Proxy URL (used for the tools supporting it. Other will prompt a warning msg)")
fingerprintCmd.Flags().BoolVarP(&opts.UseHttpInsecure, "insecure", "k", defaults.UseHttpInsecure, "Ignore SSL warnings and force http")
fingerprintCmd.Flags().StringVarP(&opts.TargetFilePath, "file", "f", defaults.TargetFilePath, "File containing list of targets (should be a list of IP Addresses or domains)")
diff --git a/cli/types.go b/cli/types.go
@@ -3,8 +3,9 @@ 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
- OutDirName string
+ // if no target file is specified for OSINT command, will use that instead.
+ // Can be Outfile or OutDir
+ OutName string
// Run a dry-run (test mode)
RunDry bool
@@ -30,7 +31,7 @@ type StandardOptions struct {
func GetDefaultOptions() StandardOptions {
opts := StandardOptions{
- OutDirName: "",
+ OutName: "",
RunDry: false,
Proxy: "",
UseHttpInsecure: false,
diff --git a/prune/run.go b/prune/run.go
@@ -0,0 +1,70 @@
+package prune
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ helper "evil.djnn.sh/djnn/yellow/helpers"
+)
+
+type PruneOpts struct {
+ proxy string
+ dryRun bool
+ forceInsecure bool
+
+ inFilePath string
+ outFilePath string
+}
+
+func (opts *PruneOpts) SetInFilePath(data string) {
+ opts.inFilePath = data
+}
+
+func (opts *PruneOpts) SetOutFilePath(data string) {
+ opts.outFilePath = data
+}
+
+func (opts *PruneOpts) SetForceInsecure(data bool) {
+ opts.forceInsecure = data
+}
+
+func (opts *PruneOpts) SetProxy(data string) {
+ opts.proxy = data
+}
+
+func (opts *PruneOpts) SetDryRun(data bool) {
+ opts.dryRun = data
+}
+
+func (opts *PruneOpts) Run() {
+
+ helper.CheckProxy(opts.proxy)
+ helper.DisplayNetInfo()
+
+ results := make([]string, 0)
+ scanner := helper.LoadTargetFile(opts.inFilePath)
+ defer scanner.Close()
+
+ for scanner.Scan() {
+ targetDomain := scanner.Text()
+ httpAddr := "https://" + targetDomain
+ if opts.forceInsecure {
+ httpAddr = "http://" + targetDomain
+ }
+
+ if !helper.HasUnavailableWebInterface(httpAddr) {
+ fmt.Printf("[+] %s is alive !\n", targetDomain)
+ results = append(results, targetDomain)
+ }
+ }
+
+ content := strings.Join(results, "\n")
+ err := os.WriteFile(opts.outFilePath, []byte(content), 0644)
+ if err != nil {
+ fmt.Printf("Error writing to file: %v\n", err)
+ return
+ }
+
+ fmt.Printf("[+] Done. Saved %d alive domains\n", len(results))
+}
| | | |