Skip to content

Commit 300da27

Browse files
committed
Add support for random user agent and specified agent (#41)
1 parent ab00ba6 commit 300da27

File tree

4 files changed

+36
-15
lines changed

4 files changed

+36
-15
lines changed

VHostScan.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from socket import gethostbyaddr
88
from lib.core.virtual_host_scanner import *
99
from lib.helpers.output_helper import *
10-
from lib.helpers.file_helper import get_combined_word_lists
10+
from lib.helpers.file_helper import get_combined_word_lists, load_random_user_agents
1111
from lib.core.__version__ import __version__
1212

1313

@@ -36,6 +36,8 @@ def main():
3636
parser.add_argument("--waf", dest="add_waf_bypass_headers", action="store_true", help="If set then simple WAF bypass headers will be sent.", default=False)
3737
parser.add_argument("-oN", dest="output_normal", help="Normal output printed to a file when the -oN option is specified with a filename argument." )
3838
parser.add_argument("-", dest="stdin", action="store_true", help="By passing a blank '-' you tell VHostScan to expect input from stdin (pipe).", default=False)
39+
parser.add_argument('--random-agent', dest='random_agent', action='store_true', help='If set, then each scan will use random user-agent from predefined list', default=False)
40+
parser.add_argument('--user-agent', dest='user_agent', type=str, help='User-agent for scans')
3941

4042
arguments = parser.parse_args()
4143
wordlist = []
@@ -64,6 +66,14 @@ def main():
6466
inputs=', '.join(word_list_types),
6567
))
6668

69+
user_agents = []
70+
if arguments.user_agent:
71+
print('[>] User-Agent specified, using it')
72+
user_agents = [arguments.user_agent]
73+
elif arguments.random_agent:
74+
print('[>] Random User-Agent flag set')
75+
user_agents = load_random_user_agents()
76+
6777
if(arguments.ssl):
6878
print("[>] SSL flag set, sending all results over HTTPS")
6979

@@ -83,7 +93,7 @@ def main():
8393
wordlist.extend(aliases)
8494

8595
scanner_args = vars(arguments)
86-
scanner_args.update({'target': arguments.target_hosts, 'wordlist': wordlist})
96+
scanner_args.update({'target': arguments.target_hosts, 'wordlist': wordlist, 'user_agents': user_agents})
8797
scanner = virtual_host_scanner(**scanner_args)
8898

8999
scanner.scan()

lib/core/virtual_host_scanner.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import os
2+
import random
3+
24
import requests
35
import hashlib
46
import pandas as pd
57
import time
68
from lib.core.discovered_host import *
79

10+
DEFAULT_USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
11+
812

913
class virtual_host_scanner(object):
1014
"""Virtual host scanning class
@@ -44,6 +48,9 @@ def __init__(self, target, wordlist, **kwargs):
4448
# store associated data for discovered hosts in array for oN, oJ, etc'
4549
self.hosts = []
4650

51+
# available user-agents
52+
self.user_agents = list(kwargs.get('user_agents', [DEFAULT_USER_AGENT]))
53+
4754
@property
4855
def ignore_http_codes(self):
4956
return self._ignore_http_codes
@@ -63,22 +70,19 @@ def scan(self):
6370
for virtual_host in self.wordlist:
6471
hostname = virtual_host.replace('%s', self.base_host)
6572

73+
headers = {
74+
'User-Agent': random.choice(self.user_agents),
75+
'Host': hostname if self.real_port == 80 else '{}:{}'.format(hostname, self.real_port),
76+
'Accept': '*/*'
77+
}
78+
6679
if self.add_waf_bypass_headers:
67-
headers = {
68-
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
69-
'Host': hostname if self.real_port == 80 else '{}:{}'.format(hostname, self.real_port),
70-
'Accept': '*/*',
80+
headers.update({
7181
'X-Originating-IP': '127.0.0.1',
7282
'X-Forwarded-For': '127.0.0.1',
7383
'X-Remote-IP': '127.0.0.1',
7484
'X-Remote-Addr': '127.0.0.1'
75-
}
76-
else:
77-
headers = {
78-
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
79-
'Host': hostname if self.real_port == 80 else '{}:{}'.format(hostname, self.real_port),
80-
'Accept': '*/*'
81-
}
85+
})
8286

8387
dest_url = '{}://{}:{}/'.format('https' if self.ssl else 'http', self.target, self.port)
8488

@@ -115,8 +119,8 @@ def scan(self):
115119
# add url and hash into array for likely matches
116120
self.results.append(hostname + ',' + page_hash)
117121

118-
#rate limit the connection, if the int is 0 it is ignored
119-
time.sleep(self.rate_limit)
122+
#rate limit the connection, if the int is 0 it is ignored
123+
time.sleep(self.rate_limit)
120124

121125
self.completed_scan=True
122126

lib/helpers/file_helper.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,8 @@ def get_combined_word_lists(argument):
5555
'file_paths': files,
5656
'words': words,
5757
}
58+
59+
60+
def load_random_user_agents():
61+
with open('./lib/ua-random-list.txt') as f:
62+
return f.readlines()

lib/ua-random-list.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
2+
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0

0 commit comments

Comments
 (0)