-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCMSDetect.py
More file actions
307 lines (259 loc) · 14.7 KB
/
Copy pathCMSDetect.py
File metadata and controls
307 lines (259 loc) · 14.7 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# CMSDetect // Python script to detect the CMS that website running // By Mr.Kara
# Note that the project is openSource , so you can take it and make it your own :v i don't mind
import requests
import argparse
try:
from termcolor import colored, cprint
except:
pass
# Print the banner
try:
banner = colored('''
_____ __ __ _____ _____ _ _
/ ____| \/ |/ ____| __ \ | | | |
| | | \ / | (___ | | | | ___| |_ ___ ___| |_
| | | |\/| |\___ \| | | |/ _ \ __/ _ \/ __| __|
| |____| | | |____) | |__| | __/ || __/ (__| |_
\_____|_| |_|_____/|_____/ \___|\__\___|\___|\__|
CMSDetect
Python script to detect the CMS that website running
By Mr.Kara ''', 'red')
print banner
except:
banner = '''
_____ __ __ _____ _____ _ _
/ ____| \/ |/ ____| __ \ | | | |
| | | \ / | (___ | | | | ___| |_ ___ ___| |_
| | | |\/| |\___ \| | | |/ _ \ __/ _ \/ __| __|
| |____| | | |____) | |__| | __/ || __/ (__| |_
\_____|_| |_|_____/|_____/ \___|\__\___|\___|\__|
CMSDetect
Python script to detect the CMS that website running
By Mr.Kara '''
print banner
# Mask the user agent so it doesn't show as python and get blocked, set global for request that need to allow for redirects
# Get function to swap the user agent
def get(websiteToScan):
global user_agent
user_agent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
}
return requests.get(websiteToScan, allow_redirects=False, headers=user_agent)
# Begin scan
def scan():
# Check to see if the site argument was specified
parser = argparse.ArgumentParser()
parser.add_argument("-s", "--site", help="Use this option to specify the domain or IP to scan.")
args = parser.parse_args()
if args.site is None:
# Get the input from the user
print
print "Please enter the site or IP you would like to scan below."
print "Examples - www.site.com, https://store.org/magento, 192.168.1.50"
websiteToScan = raw_input('Site to scan: ')
else:
websiteToScan = args.site
# Check the input for HTTP or HTTPS and then remove it, if nothing is found assume HTTP
if websiteToScan.startswith('http://'):
proto = 'http://'
# websiteToScan = websiteToScan.strip('http://')
websiteToScan = websiteToScan[7:]
elif websiteToScan.startswith('https://'):
proto = 'https://'
# websiteToScan = websiteToScan.strip('https://')
websiteToScan = websiteToScan[8:]
else:
proto = 'http://'
# Check the input for an ending / and remove it if found
if websiteToScan.endswith('/'):
websiteToScan = websiteToScan.strip('/')
# Combine the protocol and site
websiteToScan = proto + websiteToScan
# Check to see if the site is online
print
print "[+] Checking to see if the site is online..."
try:
onlineCheck = get(websiteToScan)
except requests.exceptions.ConnectionError as ex:
print "[!] " + websiteToScan + " appears to be offline."
else:
if onlineCheck.status_code == 200 or onlineCheck.status_code == 301 or onlineCheck.status_code == 302:
print " | " + websiteToScan + " appears to be online."
print
print "Beginning scan..."
print
print "[+] Checking to see if the site is redirecting..."
redirectCheck = requests.get(websiteToScan, headers=user_agent)
if len(redirectCheck.history) > 0:
if '301' in str(redirectCheck.history[0]) or '302' in str(redirectCheck.history[0]):
print "[!] The site entered appears to be redirecting, please verify the destination site to ensure accurate results!"
print "[!] It appears the site is redirecting to " + redirectCheck.url
elif 'meta http-equiv="REFRESH"' in redirectCheck.text:
print "[!] The site entered appears to be redirecting, please verify the destination site to ensure accurate results!"
else:
print " | Site does not appear to be redirecting..."
else:
print "[!] " + websiteToScan + " appears to be online but returned a " + str(
onlineCheck.status_code) + " error."
print
exit()
print
print "[+] Attempting to get the HTTP headers..."
# Pretty print the headers
for header in onlineCheck.headers:
try:
print " | " + header + " : " + onlineCheck.headers[header]
except Exception as ex:
print "[!] Error: " + ex.message
####################################################
# WordPress Scans
####################################################
print
print "[+] Running the WordPress scans..."
# Use requests.get allowing redirects otherwise will always fail
wpLoginCheck = requests.get(websiteToScan + '/wp-login.php', headers=user_agent)
if wpLoginCheck.status_code == 200 and "user_login" in wpLoginCheck.text and "404" not in wpLoginCheck.text:
print "[!] Detected: WordPress WP-Login page: " + websiteToScan + '/wp-login.php'
else:
print " | Not Detected: WordPress WP-Login page: " + websiteToScan + '/wp-login.php'
# Use requests.get allowing redirects otherwise will always fail
wpAdminCheck = requests.get(websiteToScan + '/wp-admin', headers=user_agent)
if wpAdminCheck.status_code == 200 and "user_login" in wpAdminCheck.text and "404" not in wpLoginCheck.text:
print "[!] Detected: WordPress WP-Admin page: " + websiteToScan + '/wp-admin'
else:
print " | Not Detected: WordPress WP-Admin page: " + websiteToScan + '/wp-admin'
wpAdminUpgradeCheck = get(websiteToScan + '/wp-admin/upgrade.php')
if wpAdminUpgradeCheck.status_code == 200 and "404" not in wpAdminUpgradeCheck.text:
print "[!] Detected: WordPress WP-Admin/upgrade.php page: " + websiteToScan + '/wp-admin/upgrade.php'
else:
print " | Not Detected: WordPress WP-Admin/upgrade.php page: " + websiteToScan + '/wp-admin/upgrade.php'
wpAdminReadMeCheck = get(websiteToScan + '/readme.html')
if wpAdminReadMeCheck.status_code == 200 and "404" not in wpAdminReadMeCheck.text:
print "[!] Detected: WordPress Readme.html: " + websiteToScan + '/readme.html'
else:
print " | Not Detected: WordPress Readme.html: " + websiteToScan + '/readme.html'
wpLinksCheck = get(websiteToScan)
if 'wp-' in wpLinksCheck.text:
print "[!] Detected: WordPress wp- style links detected on index"
else:
print " | Not Detected: WordPress wp- style links detected on index"
####################################################
# Joomla Scans
####################################################
print
print "[+] Running the Joomla scans..."
joomlaAdminCheck = get(websiteToScan + '/administrator/')
if joomlaAdminCheck.status_code == 200 and "mod-login-username" in joomlaAdminCheck.text and "404" not in joomlaAdminCheck.text:
print "[!] Detected: Potential Joomla administrator login page: " + websiteToScan + '/administrator/'
else:
print " | Not Detected: Joomla administrator login page: " + websiteToScan + '/administrator/'
joomlaReadMeCheck = get(websiteToScan + '/readme.txt')
if joomlaReadMeCheck.status_code == 200 and "joomla" in joomlaReadMeCheck.text and "404" not in joomlaReadMeCheck.text:
print "[!] Detected: Joomla Readme.txt: " + websiteToScan + '/readme.txt'
else:
print " | Not Detected: Joomla Readme.txt: " + websiteToScan + '/readme.txt'
joomlaTagCheck = get(websiteToScan)
if joomlaTagCheck.status_code == 200 and 'name="generator" content="Joomla' in joomlaTagCheck.text and "404" not in joomlaTagCheck.text:
print "[!] Detected: Generated by Joomla tag on index"
else:
print " | Not Detected: Generated by Joomla tag on index"
joomlaStringCheck = get(websiteToScan)
if joomlaStringCheck.status_code == 200 and "joomla" in joomlaStringCheck.text and "404" not in joomlaStringCheck.text:
print "[!] Detected: Joomla strings on index"
else:
print " | Not Detected: Joomla strings on index"
joomlaDirCheck = get(websiteToScan + '/media/com_joomlaupdate/')
if joomlaDirCheck.status_code == 403 and "404" not in joomlaDirCheck.text:
print "[!] Detected: Joomla media/com_joomlaupdate directories: " + websiteToScan + '/media/com_joomlaupdate/'
else:
print " | Not Detected: Joomla media/com_joomlaupdate directories: " + websiteToScan + '/media/com_joomlaupdate/'
####################################################
# Magento Scans
####################################################
print
print "[+] Running the Magento scans..."
magentoAdminCheck = get(websiteToScan + '/index.php/admin/')
if magentoAdminCheck.status_code == 200 and 'login' in magentoAdminCheck.text and "404" not in magentoAdminCheck.text:
print "[!] Detected: Potential Magento administrator login page: " + websiteToScan + '/index.php/admin'
else:
print " | Not Detected: Magento administrator login page: " + websiteToScan + '/index.php/admin'
magentoRelNotesCheck = get(websiteToScan + '/RELEASE_NOTES.txt')
if magentoRelNotesCheck.status_code == 200 and 'magento' in magentoRelNotesCheck.text:
print "[!] Detected: Magento Release_Notes.txt: " + websiteToScan + '/RELEASE_NOTES.txt'
else:
print " | Not Detected: Magento Release_Notes.txt: " + websiteToScan + '/RELEASE_NOTES.txt'
magentoCookieCheck = get(websiteToScan + '/js/mage/cookies.js')
if magentoCookieCheck.status_code == 200 and "404" not in magentoCookieCheck.text:
print "[!] Detected: Magento cookies.js: " + websiteToScan + '/js/mage/cookies.js'
else:
print " | Not Detected: Magento cookies.js: " + websiteToScan + '/js/mage/cookies.js'
magStringCheck = get(websiteToScan + '/index.php')
if magStringCheck.status_code == 200 and '/mage/' in magStringCheck.text or 'magento' in magStringCheck.text:
print "[!] Detected: Magento strings on index"
else:
print " | Not Detected: Magento strings on index"
# print magStringCheck.text
magentoStylesCSSCheck = get(websiteToScan + '/skin/frontend/default/default/css/styles.css')
if magentoStylesCSSCheck.status_code == 200 and "404" not in magentoStylesCSSCheck.text:
print "[!] Detected: Magento styles.css: " + websiteToScan + '/skin/frontend/default/default/css/styles.css'
else:
print " | Not Detected: Magento styles.css: " + websiteToScan + '/skin/frontend/default/default/css/styles.css'
mag404Check = get(websiteToScan + '/errors/design.xml')
if mag404Check.status_code == 200 and "magento" in mag404Check.text:
print "[!] Detected: Magento error page design.xml: " + websiteToScan + '/errors/design.xml'
else:
print " | Not Detected: Magento error page design.xml: " + websiteToScan + '/errors/design.xml'
####################################################
# Drupal Scans
####################################################
print
print "[+] Running the Drupal scans..."
drupalReadMeCheck = get(websiteToScan + '/readme.txt')
if drupalReadMeCheck.status_code == 200 and 'drupal' in drupalReadMeCheck.text and '404' not in drupalReadMeCheck.text:
print "[!] Detected: Drupal Readme.txt: " + websiteToScan + '/readme.txt'
else:
print " | Not Detected: Drupal Readme.txt: " + websiteToScan + '/readme.txt'
drupalTagCheck = get(websiteToScan)
if drupalTagCheck.status_code == 200 and 'name="Generator" content="Drupal' in drupalTagCheck.text:
print "[!] Detected: Generated by Drupal tag on index"
else:
print " | Not Detected: Generated by Drupal tag on index"
drupalCopyrightCheck = get(websiteToScan + '/core/COPYRIGHT.txt')
if drupalCopyrightCheck.status_code == 200 and 'Drupal' in drupalCopyrightCheck.text and '404' not in drupalCopyrightCheck.text:
print "[!] Detected: Drupal COPYRIGHT.txt: " + websiteToScan + '/core/COPYRIGHT.txt'
else:
print " | Not Detected: Drupal COPYRIGHT.txt: " + websiteToScan + '/core/COPYRIGHT.txt'
drupalReadme2Check = get(websiteToScan + '/modules/README.txt')
if drupalReadme2Check.status_code == 200 and 'drupal' in drupalReadme2Check.text and '404' not in drupalReadme2Check.text:
print "[!] Detected: Drupal modules/README.txt: " + websiteToScan + '/modules/README.txt'
else:
print " | Not Detected: Drupal modules/README.txt: " + websiteToScan + '/modules/README.txt'
drupalStringCheck = get(websiteToScan)
if drupalStringCheck.status_code == 200 and 'drupal' in drupalStringCheck.text:
print "[!] Detected: Drupal strings on index"
else:
print " | Not Detected: Drupal strings on index"
####################################################
# phpMyAdmin Scans
####################################################
print
print "[+] Running the phpMyAdmin scans..."
phpMyAdminCheck = get(websiteToScan)
if phpMyAdminCheck.status_code == 200 and 'phpmyadmin' in phpMyAdminCheck.text:
print "[!] Detected: phpMyAdmin index page"
else:
print " | Not Detected: phpMyAdmin index page"
pmaCheck = get(websiteToScan)
if pmaCheck.status_code == 200 and 'pmahomme' in pmaCheck.text or 'pma_' in pmaCheck.text:
print "[!] Detected: phpMyAdmin pmahomme and pma_ style links on index page"
else:
print " | Not Detected: phpMyAdmin pmahomme and pma_ style links on index page"
phpMyAdminConfigCheck = get(websiteToScan + '/config.inc.php')
if phpMyAdminConfigCheck.status_code == 200 and '404' not in phpMyAdminConfigCheck.text:
print "[!] Detected: phpMyAdmin configuration file: " + websiteToScan + '/config.inc.php'
else:
print " | Not Detected: phpMyAdmin configuration file: " + websiteToScan + '/config.inc.php'
print
print "Scan is now complete!"
print
scan()