From cf7e80028f8d43525aa743a8b04a0feea9d2fe7f Mon Sep 17 00:00:00 2001 From: Mark Lowe Date: Tue, 27 Feb 2024 17:49:30 +0000 Subject: [PATCH 1/2] Added support for processing a file of user:pass combos --- Talon.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 7 deletions(-) diff --git a/Talon.go b/Talon.go index 95bf240..f14be29 100644 --- a/Talon.go +++ b/Talon.go @@ -54,6 +54,7 @@ type FlagOptions struct { user string userfile string passfile string + combofile string lockout float64 attempts float64 domain string @@ -81,6 +82,7 @@ func options() *FlagOptions { user := flag.String("U", "", "Username to authenticate as") userfile := flag.String("Userfile", "", "File containing the list of usernames") passfile := flag.String("Passfile", "", "File containing the list of passwords") + combofile := flag.String("Combofile", "", "File containing list of user:pass combinations to try") lockout := flag.Float64("Lockout", 60, "Account lockout period in minutes") attempts := flag.Float64("A", 3, "Authentication attempts per lockout period") pass := flag.String("P", "", "Password to use") @@ -94,7 +96,7 @@ func options() *FlagOptions { flag.Parse() debugging = *debug debugWriter = os.Stdout - return &FlagOptions{host: *host, domain: *domain, user: *user, userfile: *userfile, hostfile: *hostfile, pass: *pass, outFile: *outFile, sleep: *sleep, enum: *enum, ldap: *ldap, kerb: *kerb, passfile: *passfile, lockout: *lockout, attempts: *attempts, lockerr: *lockerr} + return &FlagOptions{host: *host, domain: *domain, user: *user, userfile: *userfile, combofile: *combofile, hostfile: *hostfile, pass: *pass, outFile: *outFile, sleep: *sleep, enum: *enum, ldap: *ldap, kerb: *kerb, passfile: *passfile, lockout: *lockout, attempts: *attempts, lockerr: *lockerr} } func readfile(inputFile string) []string { @@ -102,7 +104,9 @@ func readfile(inputFile string) []string { if err != nil { log.Fatal(err) } - return strings.Split(string(output), "\n") + return strings.FieldsFunc(string(output), func(r rune) bool { + return r == '\n' || r == '\r' + }) } func check(e error) { @@ -126,6 +130,7 @@ func main() { var usernames []string var services []string var passwords []string + var combos []string services = []string{"KERB", "LDAP"} fmt.Println(` __________ ________ ___ ________ ________ @@ -137,7 +142,7 @@ func main() { \|__| \|__|\|__|\|_______|\|_______|\|__| \|__| (@Tyl0us) - Version: 3.2 `) + Version: 3.2-mod1 `) if opt.enum { services = []string{"KERB"} @@ -190,12 +195,20 @@ func main() { } } - if opt.user == "" && opt.userfile == "" { - log.Fatal("Error: Please provide an username or list of usernames") + if opt.user == "" && opt.userfile == "" && opt.combofile == "" { + log.Fatal("Error: Please provide a username, username file or a combofile") } - if (opt.pass == "" && opt.passfile == "") && opt.enum == false { - log.Fatal("Error: Please provide a password or select the enumeration option") + if (opt.pass == "" && opt.passfile == "") && opt.enum == false && opt.combofile == "" { + log.Fatal("Error: Please provide a password, select the enumeration option or provide a combofile") + } + + if (opt.user != "" || opt.userfile != "") && opt.combofile != "" { + log.Fatal("Error: Don't specify username or username file with Combofile") + } + + if (opt.pass != "" || opt.passfile != "") && opt.combofile != "" { + log.Fatal("Error: Don't specify password or password file with Combofile") } if opt.pass != "" { @@ -214,6 +227,17 @@ func main() { } } + if opt.combofile != "" { + printDebug("Reading combo file %s\n", opt.userfile) + fileCombos := readfile(opt.combofile) + printDebug("Appending combos %v\n", fileCombos) + for _, combo := range fileCombos { + if combo != "" { + combos = append(combos, combo) + } + } + } + if opt.user != "" { printDebug("Appending user %s\n", opt.user) usernames = append(usernames, opt.user) @@ -234,6 +258,62 @@ func main() { fmt.Print("\n") } + // Combo execution logic + if (opt.combofile != "") { + sleep := opt.sleep + domain := strings.ToUpper(opt.domain) + printDebug("Domain %v\tCombos %v\tHosts %v\tServices %v\n", domain, combos, hosts, services) + x := 0 + err := 0 + rand.Seed(time.Now().Unix()) + lenServices := len(services) - 1 + for _, combo := range combos { + n := 0 + if opt.hostfile != "" { + n = rand.Int() % (len(hosts) - 1) + } + if hosts[n] == "" { + return + } + + parts := strings.SplitN(combo, ":", 2) + if len(parts) != 2 { + fmt.Printf("[W] Ignoring combo with too many colons: %s", combo) + continue + } + username := parts[0] + password := parts[1] + + time.Sleep(time.Duration(sleep) * time.Second) + auth := setup(services[x], hosts[n], domain, username, password, opt.enum) + result, forfile, _ := auth.Login() + fmt.Println(result) + if strings.Contains(result, "User's Account Locked") && opt.enum != true { + err++ + if err == int(opt.lockerr) { + reader := bufio.NewReader(os.Stdin) + fmt.Printf("[*] %d Consecutive account lock out(s) detected - Do you want to continue.[y/n]: ", err) + text, _ := reader.ReadString('\n') + if strings.Contains(text, "y") { + err = 0 + continue + } + log.Fatal("Shutting down") + } + } + if opt.outFile != "" { + forfile = forfile + "\n" + writefile(opt.outFile, forfile) + } + if lenServices == x { + x = 0 + } else { + x++ + err = 0 + } + } + } + // Normal execution logic if (opt.pass != "" && opt.passfile == "") || opt.enum { sleep := opt.sleep From c3cc91d8899c52a9a7ad1995018bc4b2eecee8b9 Mon Sep 17 00:00:00 2001 From: Mark Lowe Date: Tue, 27 Feb 2024 17:51:46 +0000 Subject: [PATCH 2/2] Added -Combofile arguement --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c5efd1..1ee8018 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,8 @@ $ ./Talon -h Usage of ./Talon: -A float Authentication attempts per lockout period (default 3) + -Combofile string + File containing list of user:pass combinations to try -D string Fully qualified domain to use -E Enumerates which users are valid @@ -212,4 +214,4 @@ Will resume at 03-10-2022 16:43:35 * Version 1.3 released 05/03/2019 * Version 1.4 released 03/17/2020 * Version 2.0 public relase 06/18/2020 -* Version 3.0 relase 03/10/2022 \ No newline at end of file +* Version 3.0 relase 03/10/2022