-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathurltesting.py
executable file
·118 lines (106 loc) · 4.04 KB
/
urltesting.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
# URLTesting library
# Copyright (C) 2005-2007, Jesse Burns. See accompanying LICENSE for info
# Written by Jesse Burns <jesse@isecpartners.com>
# Additions by Jonathan Wilkins <jwilkins@isecpartners.com>
"""
Performs testing on urls to determine if they provide directory listings
or allow uploading of data with HTTP PUT and assorted support functions
"""
import urlparse, StringIO, os, sys, re, time, sha, logging
import pycurl
DEBUG = False
log = logging.getLogger("proxmon")
# internal - create a curl object, with an associated output string,
# no interest in SSL certificate validity or following redirects and
# a 30 second timeout
def get_curl():
curl = pycurl.Curl()
output = StringIO.StringIO()
curl.setopt(pycurl.COOKIEFILE, 'proxmon.cj')
curl.setopt(pycurl.WRITEFUNCTION, output.write)
curl.setopt(pycurl.SSL_VERIFYHOST, 0)
curl.setopt(pycurl.SSL_VERIFYPEER, 0)
curl.setopt(pycurl.TIMEOUT, 30)
return (curl, output)
def url_exists(url):
not_found = ['not found on this server', 'file not found']
(c, b) = get_curl()
c.setopt(pycurl.URL, url)
try: c.perform()
except: return False
if 199 < c.getinfo(c.HTTP_CODE) < 300:
# XXX - check it's not really a 404 by scanning body
for x in not_found:
if re.search(x, b.getvalue(), re.IGNORECASE):
return False
return True
def file_contains(url, string):
(c, b) = get_curl()
c.setopt(pycurl.URL, url)
try: c.perform()
except: return False
if 199 < c.getinfo(c.HTTP_CODE) < 300:
if re.search(string, b.getvalue(), re.IGNORECASE):
return True
return False
def allows_upload(url):
filename = 'isec-tst.txt'
filecontent = """Test File - if this file exists, the directory it is contained
in is writable, which may not be desirable. It is suggested
that the administrator review the directory permissions."""
if(url_exists(url + filename)): # add hashcode at end and retry
filename += "." + sha.new(str(time.time())).hexdigest()
(c, b) = get_curl()
c.setopt(pycurl.URL, url + filename)
c.setopt(pycurl.UPLOAD, 1)
c.setopt(pycurl.READFUNCTION, StringIO.StringIO(filecontent).read)
filesize = len(filecontent)
c.setopt(pycurl.INFILESIZE, filesize)
try: c.perform()
except: return False
if (c.getinfo(c.HTTP_CODE) > 199 and c.getinfo(c.HTTP_CODE) < 300):
# download file to confirm upload actually worked
(c, b) = get_curl()
c.setopt(pycurl.URL, url+filename)
try: c.perform()
except: return False
if b.getvalue() == filecontent: return True
else: return False
if (DEBUG):
log.info(c.getinfo(c.HTTP_CODE), url)
return False
# heuristically determines if the page resulting from accessing this
# url is actually a directory listing.
def gives_directory_listing(url):
# these strings must be present for a page to be judged a directory listing
dir_substrings = ['Index of ', 'Parent Directory', 'Last modified']
# had included substring [DIR] but found it was not included in some mac web
# server directory listings
(c, b) = get_curl()
c.setopt(pycurl.URL, url)
try: c.perform()
except: return False
if (c.getinfo(c.HTTP_CODE) == 200):
for x in dir_substrings:
if (b.getvalue().find(x) >= 0): # required substring not found
return True
return False
if __name__ == '__main__':
t = ['http://google.com/', 'http://tod.rutech.ru/Daemon/',
# 'http://www.microsoft.com/', 'http://www.yahoo.com',
# 'http://www.globeandmail.com', 'http://crl.thawte.com/',
# 'http://www.ucalgary.ca/~hclarke/', 'http://www.isecpartners.com/picts/',
# 'http://www.isecpartners.com/', 'https://www.isecpartners.com/',
# 'https://www.isecpartners.com/picts/', 'http://www.google.com/',
# 'http://www.cnn.com', 'http://hdf.ncsa.uiuc.edu/HDF5/doc/PSandPDF/',
'http://www.google.com/nl/intl/_vti_bin',
'http://www.umich.edu/~archive/mac/']
print "Directory Listing Test"
for url in t:
print '\t' + url + ' returned ' + str(gives_directory_listing(url))
print "HTTP PUT test"
for url in ['http://scratch.bitland.net/put/', 'http://scratch.bitland.net/']:
print '\t' + url + ' returned ' + str(allows_upload(url))
print "Url exists"
for url in t:
print '\t' + url + ' returned ' + str(url_exists(url))