10
10
from arjun .core .bruter import bruter
11
11
from arjun .core .exporter import exporter
12
12
from arjun .core .requester import requester
13
- from arjun .core .anomaly import define
13
+ from arjun .core .anomaly import define , compare
14
14
from arjun .core .utils import fetch_params , stable_request , random_str , slicer , confirm , populate , reader , nullify , prepare_requests , compatible_path
15
15
16
16
from arjun .plugins .heuristic import heuristic
24
24
parser .add_argument ('-oT' , help = 'Path for text output file.' , dest = 'text_file' )
25
25
parser .add_argument ('-oB' , help = 'Port for output to Burp Suite Proxy. Default port is 8080.' , dest = 'burp_port' , nargs = '?' , const = 8080 )
26
26
parser .add_argument ('-d' , help = 'Delay between requests in seconds. (default: 0)' , dest = 'delay' , type = float , default = 0 )
27
- parser .add_argument ('-t' , help = 'Number of concurrent threads. (default: 2 )' , dest = 'threads' , type = int , default = 2 )
27
+ parser .add_argument ('-t' , help = 'Number of concurrent threads. (default: 5 )' , dest = 'threads' , type = int , default = 5 )
28
28
parser .add_argument ('-w' , help = 'Wordlist file path. (default: {arjundir}/db/large.txt)' , dest = 'wordlist' , default = arjun_dir + '/db/large.txt' )
29
29
parser .add_argument ('-m' , help = 'Request method to use: GET/POST/XML/JSON. (default: GET)' , dest = 'method' , default = 'GET' )
30
30
parser .add_argument ('-i' , help = 'Import target URLs from file.' , dest = 'import_file' , nargs = '?' , const = True )
31
31
parser .add_argument ('-T' , help = 'HTTP request timeout in seconds. (default: 15)' , dest = 'timeout' , type = float , default = 15 )
32
- parser .add_argument ('-c' , help = 'Chunk size. The number of parameters to be sent at once' , type = int , dest = 'chunks' , default = 300 )
32
+ parser .add_argument ('-c' , help = 'Chunk size. The number of parameters to be sent at once' , type = int , dest = 'chunks' , default = 500 )
33
33
parser .add_argument ('-q' , help = 'Quiet mode. No output.' , dest = 'quiet' , action = 'store_true' )
34
34
parser .add_argument ('--headers' , help = 'Add headers. Separate multiple headers with a new line.' , dest = 'headers' , nargs = '?' , const = True )
35
35
parser .add_argument ('--passive' , help = 'Collect parameter names from passive sources like wayback, commoncrawl and otx.' , dest = 'passive' , nargs = '?' , const = '-' )
@@ -102,7 +102,7 @@ def narrower(request, factors, param_groups):
102
102
return anomalous_params
103
103
104
104
105
- def initialize (request , wordlist ):
105
+ def initialize (request , wordlist , single_url = False ):
106
106
"""
107
107
handles parameter finding process for a single request object
108
108
returns 'skipped' (on error), list on success
@@ -118,27 +118,37 @@ def initialize(request, wordlist):
118
118
else :
119
119
fuzz = random_str (6 )
120
120
response_1 = requester (request , {fuzz : fuzz [::- 1 ]})
121
- print ('%s Analysing HTTP response for anomalies' % run )
121
+ if single_url :
122
+ print ('%s Analysing HTTP response for anomalies' % run )
122
123
fuzz = random_str (6 )
123
124
response_2 = requester (request , {fuzz : fuzz [::- 1 ]})
124
125
if type (response_1 ) == str or type (response_2 ) == str :
125
126
return 'skipped'
126
127
factors = define (response_1 , response_2 , fuzz , fuzz [::- 1 ], wordlist )
127
- print ('%s Analysing HTTP response for potential parameter names' % run )
128
+ if single_url :
129
+ print ('%s Analysing HTTP response for potential parameter names' % run )
128
130
found = heuristic (response_1 .text , wordlist )
129
131
if found :
130
132
num = len (found )
131
133
s = 's' if num > 1 else ''
132
134
print ('%s Heuristic scanner found %i parameter%s: %s' % (good , num , s , ', ' .join (found )))
133
- print ('%s Logicforcing the URL endpoint' % run )
135
+ if single_url :
136
+ print ('%s Logicforcing the URL endpoint' % run )
134
137
populated = populate (wordlist )
135
138
param_groups = slicer (populated , int (len (wordlist )/ mem .var ['chunks' ]))
139
+ prev_chunk_count = len (param_groups )
136
140
last_params = []
137
141
while True :
138
142
param_groups = narrower (request , factors , param_groups )
143
+ if len (param_groups ) > prev_chunk_count :
144
+ response_3 = requester (request , {fuzz : fuzz [::- 1 ]})
145
+ if compare (response_3 , factors , [fuzz ]) != '' :
146
+ print ('%s Target is misbehaving. Try the --stable swtich.' % bad )
147
+ return []
139
148
if mem .var ['kill' ]:
140
149
return 'skipped'
141
150
param_groups = confirm (param_groups , last_params )
151
+ prev_chunk_count = len (param_groups )
142
152
if not param_groups :
143
153
break
144
154
confirmed_params = []
@@ -147,7 +157,7 @@ def initialize(request, wordlist):
147
157
if reason :
148
158
name = list (param .keys ())[0 ]
149
159
confirmed_params .append (name )
150
- print ('%s name : %s, factor : %s' % (res , name , reason ))
160
+ print ('%s parameter detected : %s, based on : %s' % (res , name , reason ))
151
161
return confirmed_params
152
162
153
163
@@ -169,12 +179,17 @@ def main():
169
179
final_result [url ]['params' ] = these_params
170
180
final_result [url ]['method' ] = request ['method' ]
171
181
final_result [url ]['headers' ] = request ['headers' ]
182
+ exporter (final_result )
183
+ else :
184
+ print ('%s No parameters were discovered.' % info )
172
185
elif type (request ) == list :
173
186
# in case of multiple targets
187
+ count = 0
174
188
for each in request :
189
+ count += 1
175
190
url = each ['url' ]
176
191
mem .var ['kill' ] = False
177
- print ('%s Scanning: %s' % (run , url ))
192
+ print ('%s Scanning %d/%d : %s' % (run , count , len ( request ) , url ))
178
193
these_params = initialize (each , list (wordlist ))
179
194
if these_params == 'skipped' :
180
195
print ('%s Skipped %s due to errors' % (bad , url ))
@@ -183,12 +198,16 @@ def main():
183
198
final_result [url ]['params' ] = these_params
184
199
final_result [url ]['method' ] = each ['method' ]
185
200
final_result [url ]['headers' ] = each ['headers' ]
186
- print ('%s Parameters found: %s' % (good , ', ' .join (final_result [url ])))
201
+ exporter (final_result )
202
+ print ('%s Parameters found: %s\n ' % (good , ', ' .join (final_result [url ]['params' ])))
203
+ if not mem .var ['json_file' ]:
204
+ final_result = {}
205
+ continue
206
+ else :
207
+ print ('%s No parameters were discovered.\n ' % info )
187
208
except KeyboardInterrupt :
188
209
exit ()
189
210
190
- exporter (final_result )
191
-
192
211
193
212
if __name__ == '__main__' :
194
213
main ()
0 commit comments