Skip to content

Commit 4acd89b

Browse files
committed
Save output to a file for brute forcing ADFS
1 parent 5a30dba commit 4acd89b

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

src/adfs/brute.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@ import (
99
)
1010

1111
// Brute will bruteforce or spray passwords on the specified users.
12-
func (options *Options) Brute() {
12+
func (options *Options) Brute() []string {
1313
log = options.Log
1414
var wg sync.WaitGroup
15+
var validusers []string
16+
mux := &sync.Mutex{}
17+
1518
// If the target is not specified, we will try to find the ADFS URL with the endpoint getuserrealm
1619
if options.Target == "" {
1720
options.Target = options.findTarget(options.Domain)
1821
if options.Target == "" {
1922
log.Error("The ADFS URL was not found")
20-
return
23+
return validusers
2124
}
2225
log.Verbose("An ADFS instance has been found on " + options.Target)
2326
}
@@ -40,11 +43,18 @@ func (options *Options) Brute() {
4043
time.Sleep(time.Duration(options.Sleep) * time.Second)
4144
}
4245
if options.NoBruteforce {
43-
options.brute(email, passwordList[j])
46+
if options.brute(email, passwordList[j]) {
47+
mux.Lock()
48+
validusers = append(validusers, email)
49+
mux.Unlock()
50+
}
4451

4552
} else {
4653
for _, password := range passwordList {
4754
if options.brute(email, password) {
55+
mux.Lock()
56+
validusers = append(validusers, email)
57+
mux.Unlock()
4858
break // No need to continue if password is valid
4959
}
5060
}
@@ -65,5 +75,6 @@ func (options *Options) Brute() {
6575

6676
close(queue)
6777
wg.Wait()
78+
return validusers
6879

6980
}

src/cmd/brute/adfs.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ go run main.go bruteSpray adfs -t adfs.contoso.com -u [email protected] -p A
3434
adfsOptions.NoBruteforce = noBruteforce
3535
adfsOptions.Sleep = sleep
3636
adfsOptions.Proxy = proxy
37-
adfsOptions.Brute()
37+
validUsers = adfsOptions.Brute()
3838
},
3939
}
4040

src/cmd/brute/bruteSpray.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"net/http"
77
"net/url"
88
"os"
9+
"strings"
910

1011
"github.com/spf13/cobra"
1112
)
@@ -16,14 +17,22 @@ var debug bool
1617
var noBruteforce bool
1718
var sleep int
1819
var proxy func(*http.Request) (*url.URL, error)
19-
20+
var validUsers []string
21+
var output string
2022
var proxyString string
2123

2224
// BruteSprayCmd represents the bruteSpray command
2325
var BruteSprayCmd = &cobra.Command{
2426
Use: "bruteSpray",
2527
Short: "Spray a password or bruteforce a user's password",
2628
Long: `Different services are supported. The authentication could be on an ADFS instance, an o365 or an OWA.`,
29+
PersistentPostRun: func(cmd *cobra.Command, args []string) {
30+
if output != "" {
31+
if err := os.WriteFile(output, []byte(strings.Join(validUsers, "\n")), 0666); err != nil {
32+
fmt.Println(err)
33+
}
34+
}
35+
},
2736
}
2837

2938
func init() {
@@ -32,6 +41,7 @@ func init() {
3241
cobra.OnInitialize(initProxy)
3342
BruteSprayCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Verbose")
3443
BruteSprayCmd.PersistentFlags().BoolVar(&debug, "debug", false, "Debug")
44+
BruteSprayCmd.PersistentFlags().StringVarP(&output, "output-file", "o", "", "The out file for valid emails")
3545
BruteSprayCmd.PersistentFlags().BoolVarP(&noBruteforce, "no-bruteforce", "n", false, "No spray when using file for username and password (user1 => password1, user2 => password2)")
3646
BruteSprayCmd.PersistentFlags().IntVarP(&sleep, "sleep", "s", 0, "Sleep in seconds before sending an authentication request")
3747
BruteSprayCmd.PersistentFlags().StringVar(&proxyString, "proxy", "", "Sleep in seconds before sending an authentication request")

0 commit comments

Comments
 (0)