forked from sidaf/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnmap_web_dirbrute.py
executable file
·147 lines (117 loc) · 4.35 KB
/
nmap_web_dirbrute.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python2
# vim: set fileencoding=utf-8 :
###########
# IMPORTS #
###########
from __future__ import print_function
import sys
import argparse
import os
import urllib2
import httplib
import random
import string
from subprocess import check_output, CalledProcessError
import modules.nmap as nmap
from tqdm import tqdm
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
pass
else:
ssl._create_default_https_context = _create_unverified_https_context
#############
# FUNCTIONS #
#############
def header(*objects):
print("\033[01;01m[*]\033[00m", *objects, file=sys.stdout)
def error(*objects):
print("\033[01;31m ✖ \033[00m", *objects, file=sys.stderr)
def success(*objects):
print("\033[01;32m ✔ \033[00m", *objects, file=sys.stdout)
def info(*objects):
print("\033[01;34m ➜ \033[00m", *objects, file=sys.stdout)
def random_alpha(size=7):
return ''.join([random.choice(string.ascii_letters) for n in xrange(size)])
def random_alpha_numeric(size=7):
return ''.join([random.choice(string.ascii_letters +
string.digits) for n in xrange(size)])
def detect_404(url):
try:
response = urllib2.urlopen("{0}/{1}".format(url, random_alpha()))
length1 = response.headers['content-length']
except urllib2.HTTPError:
return -1
except KeyError:
return None
try:
response = urllib2.urlopen("{0}/{1}".format(url, random_alpha()))
length2 = response.headers['content-length']
except urllib2.HTTPError:
return -1
if length1 == length2:
return length1
else:
return None
def brute_dir(urls, wordlist):
for url in urls:
header("Attempting to discover resources on {0}".format(url))
detected = detect_404(url)
if not detected:
error("Could not detect valid 404, skipping {0}".format(url))
continue
#for word in tqdm(wordlist):
for word in wordlist:
uri = "{0}/{1}".format(url, word)
try:
response = urllib2.urlopen(uri)
if response:
if detected == -1 or response.headers['content-length'] != detected:
if 'content-length' in response.headers:
success("{0} [Code: {1} | Length: {2}]".format(uri, response.getcode(),
response.headers['content-length']))
else:
success("{0} [Code: {1} | Length: unknown]".format(uri, response.getcode()))
except urllib2.HTTPError, e:
if e.code == 401:
info("{0} [Code {1}]".format(uri, e.code))
except httplib.BadStatusLine:
error("Bad status line received from {0}".format(uri))
########
# MAIN #
########
if __name__ == '__main__':
desc = 'Parse nmap xml output and attempt to brute force directories on ' \
'all web servers.'
parser = argparse.ArgumentParser(description=desc)
required = parser.add_argument_group('required arguments')
required.add_argument('-w', '--wordlist',
action='store',
help='wordlist file',
metavar='WORDLIST',
required=True)
parser.add_argument('files',
action='store',
nargs='+',
help='nmap xml file(s) to parse',
metavar='INPUT')
args = parser.parse_args()
for xml in args.files:
if not os.path.isfile(xml):
error("File '%s' does not exist!" % xml)
exit()
if not os.access(xml, os.R_OK):
error("File '%s' is not readable!" % xml)
exit()
if not os.path.isfile(args.wordlist):
error("File '%s' does not exist!" % args.wordlist)
exit()
if not os.access(args.wordlist, os.R_OK):
error("File '%s' is not readable!" % args.wordlist)
exit()
web_servers = nmap.parse_web_servers(args.files)
# TODO: Do vhost lookup on all IP addresses and then add to list
with open(args.wordlist, 'r') as file_in:
words = filter(None, (line.rstrip() for line in file_in))
brute_dir(web_servers, words)