22
22
# RC info
23
23
24
24
progname = os .path .basename (argv [0 ])
25
- VERSION = "v1.5" # Program version
25
+ VERSION = "v1.5" # Program version
26
26
files_array = [] # Array options with file names
27
27
name_array = [] # Array options with database names
28
28
path_array = [] # Array options with paths to database files
@@ -34,18 +34,25 @@ def scrapeRC():
34
34
"""
35
35
divider = []
36
36
37
- try :
38
- settingsFile = open ("/etc/.searchsploit_rc" , "r" )
39
- except :
40
- try :
41
- settingsFile = open (os .path .expanduser ("~/.searchsploit_rc" ), "r" )
42
- except :
43
- settingsFile = open (os .path .abspath (
44
- os .sys .path [0 ] + "/.searchsploit_rc" ), "r" )
45
- # Checks for config in home directory
46
-
47
- settings = settingsFile .read ().split ("\n " )
48
- settingsFile .close ()
37
+ paths = [
38
+ "/etc/.searchsploit_rc" ,
39
+ os .path .expanduser ("~/.searchsploit_rc" ),
40
+ os .path .expanduser ("~/.local/.searchsploit_rc" ),
41
+ os .path .abspath (os .path .join (os .sys .path [0 ], ".searchsploit_rc" ))
42
+ ]
43
+
44
+ for p in paths :
45
+ if os .path .exists (p ):
46
+ with open (p , "r" ) as settingsFile :
47
+ settings = settingsFile .read ().split ("\n " )
48
+ settingsFile .close ()
49
+ break
50
+ else :
51
+ print ("ERROR: Cannot find .searchsploit_rc\n Please make sure it is located in one of its well known locations." )
52
+ print ("It can be anywhere in one of these locations:" )
53
+ for p in paths :
54
+ print ("\" {0}\" " .format (p ))
55
+ exit (2 )
49
56
50
57
for i in settings :
51
58
if (i == "" or i [0 ] == "#" ):
@@ -62,17 +69,8 @@ def scrapeRC():
62
69
63
70
# This section is to remove database paths that do not exist
64
71
larray = len (files_array )
65
- for i in range (larray - 1 , 0 , - 1 ):
66
- try :
67
- tempRead = open (os .path .abspath (os .path .join (path_array [i ], files_array [i ])),
68
- "r" , encoding = "utf8" )
69
- tempRead .read ()
70
- tempRead .close ()
71
- except :
72
- try :
73
- tempRead .close ()
74
- except :
75
- pass
72
+ for i in range (larray - 1 , - 1 , - 1 ):
73
+ if not os .path .exists (os .path .abspath (os .path .join (path_array [i ], files_array [i ]))):
76
74
files_array .pop (i )
77
75
name_array .pop (i )
78
76
path_array .pop (i )
@@ -151,7 +149,8 @@ def scrapeRC():
151
149
help = "Display the EDB-ID value rather than local path." )
152
150
parser .add_argument ("--nmap" , metavar = "file.xml" , nargs = "?" , type = argparse .FileType ("r" ), default = None , const = os .sys .stdin ,
153
151
help = "Checks all results in Nmap's XML output with service version (e.g.: nmap -sV -oX file.xml).\n Use \" -v\" (verbose) to try even more combinations" )
154
- parser .add_argument ("--version" , action = "version" , version = "%(prog)s {0}" .format (VERSION ))
152
+ parser .add_argument ("--version" , action = "version" ,
153
+ version = "%(prog)s {0}" .format (VERSION ))
155
154
parser .add_argument ("--exclude" , nargs = "*" , type = str , default = list (), metavar = "[terms]" ,
156
155
help = "Remove certain terms from the results. Option best added after all other terms have been gathered." )
157
156
@@ -171,7 +170,7 @@ def update():
171
170
172
171
# update via git
173
172
os .chdir (path_array [i ]) # set path to repos directory
174
- os .system ("git pull -v upstream master" )
173
+ os .system ("git pull -v origin master" )
175
174
print ("[i] Git Pull Complete" )
176
175
os .chdir (cwd )
177
176
return
@@ -183,7 +182,7 @@ def update():
183
182
def drawline ():
184
183
""" Draws a line in the terminal.
185
184
"""
186
- line = "" * (int (COL ) - 1 )
185
+ line = "" * (int (COL ) - 1 )
187
186
print (line )
188
187
189
188
@@ -193,7 +192,7 @@ def drawline(lim):
193
192
"""
194
193
line = "-" * lim
195
194
line += "+"
196
- line += "-" * (COL - lim - 2 ) # -2 for terminal padding
195
+ line += "-" * (COL - lim - 2 ) # -2 for terminal padding
197
196
print (line )
198
197
199
198
@@ -203,19 +202,24 @@ def highlightTerm(line, term):
203
202
@term: the term that will be found in line and used to highlight the line\n
204
203
@autoComp: [optional] if true, then it will output the string with the flags already turned into ANSI
205
204
"""
206
- try :
207
- term = term .lower ()
208
- part1 = line [:line .lower ().index (term )]
209
- part2 = line [line .lower ().index (
210
- term ): line .lower ().index (term ) + len (term )]
211
- part3 = line [line .lower ().index (term ) + len (term ):]
212
- line = part1 + '\033 [91m' + part2 + '\033 [0m' + part3
213
- except :
214
- line = line
205
+ # immediate override if colour option is used
206
+ if not parseArgs .colour :
207
+ return line
208
+
209
+ marker = 0 # marks where the term is first found
210
+ term = term .lower ()
211
+
212
+ while (line .lower ().find (term , marker ) >= 0 ):
213
+ marker = line .lower ().find (term , marker ) # update location of new found term
214
+ part1 = line [:marker ]
215
+ part2 = line [marker : marker + len (term )]
216
+ part3 = line [marker + len (term ):]
217
+ line = "{0}\033 [91m{1}\033 [0m{2}" .format (part1 , part2 , part3 )
218
+ marker += len (term ) + 4
215
219
return line
216
220
217
221
218
- def separater (lim , line1 :str , line2 :str ):
222
+ def separater (lim , line1 : str , line2 : str ):
219
223
""" Splits the two texts to fit perfectly within the terminal width
220
224
"""
221
225
lim = int (lim )
@@ -224,10 +228,17 @@ def separater(lim, line1:str, line2:str):
224
228
print (line )
225
229
return
226
230
227
- line1_length = lim - 1 # subtract 1 for padding
228
- line2_length = int (COL ) - lim - 2 - 1 # -2 for divider padding and -1 for terminal padding
229
- format_string = "{{title:{title_length}.{title_length}s}}\033 [0m | {{path:{path_length}.{path_length}s}}\033 [0m"
230
-
231
+ line1_length = lim - 1 # subtract 1 for padding
232
+ # -2 for divider padding and -1 for terminal padding
233
+ line2_length = int (COL ) - lim - 2 - 1
234
+ format_string = "{{title:{title_length}.{title_length}s}}\033 [0m | {{path:{path_length}.{path_length}s}}\033 [0m"
235
+
236
+ # Escape options for colour
237
+ if not parseArgs .colour :
238
+ print ("{{0:{0}.{0}s}} | {{1:{1}.{1}s}}" .format (
239
+ line1_length , line2_length ).format (line1 , line2 ))
240
+ return
241
+
231
242
# increase lim by markers to not include highlights in series
232
243
last_mark = 0
233
244
while (line1 .find ("\033 [91m" , last_mark , line1_length + 5 ) >= 0 ):
@@ -246,9 +257,9 @@ def separater(lim, line1:str, line2:str):
246
257
line2_length += 4
247
258
last_mark = line2 .find ("\033 [0m" , last_mark , line2_length + 4 ) + 4
248
259
249
-
250
260
# Creating format string for print
251
- fstring = format_string .format (title_length = line1_length , path_length = line2_length )
261
+ fstring = format_string .format (
262
+ title_length = line1_length , path_length = line2_length )
252
263
line = fstring .format (title = line1 , path = line2 )
253
264
print (line )
254
265
@@ -461,6 +472,8 @@ def nmapxml(file=""):
461
472
if no file name is given, then it tries stdin\n
462
473
@return: returns true if it fails
463
474
"""
475
+ import xml .etree .ElementTree as ET
476
+
464
477
global terms
465
478
global STDIN
466
479
@@ -486,47 +499,41 @@ def nmapxml(file=""):
486
499
if content == "" or content [:5 ] != "<?xml" :
487
500
STDIN = content
488
501
return False
489
- # making sure beautiful soup is importable first
490
- try :
491
- from bs4 import BeautifulSoup
492
- except :
493
- print (
494
- "Error: you need to have beautifulsoup installed to properly use this program" )
495
- print ("To install beautifulsoup, run 'pip install beautifulsoup4' in your commandline." )
496
- return False
497
502
# Read XML file
498
503
499
504
# ## Feedback to enduser
500
505
if (type (file ) == str ):
501
- print ("[i] Reading: " + highlightTerm (str (file ), str (file ), True ))
506
+ print ("[i] Reading: " + highlightTerm (str (file ), str (file )))
502
507
else :
503
- print ("[i] Reading: " + highlightTerm (file .name , file .name , True ))
508
+ print ("[i] Reading: " + highlightTerm (file .name , file .name ))
504
509
tmpaddr = ""
505
510
tmpname = ""
506
511
# ## Read in XMP (IP, name, service, and version)
507
- # xx This time with beautiful soup!
508
- xmlsheet = BeautifulSoup (content , "lxml" )
512
+ root = ET .fromstring (content )
509
513
510
- hostsheet = xmlsheet . find_all ("host" )
514
+ hostsheet = root . findall ("host" )
511
515
for host in hostsheet :
512
516
# made these lines to separate searches by machine
513
- tmpaddr = host .find ("address" ).get ( "addr" )
517
+ tmpaddr = host .find ("address" ).attrib [ "addr" ]
514
518
tmpaddr = highlightTerm (tmpaddr , tmpaddr )
515
- try :
516
- tmpname = host .find ("hostname" ).get ("name" )
519
+
520
+ if (host .find ("hostnames/hostname" ) != None ):
521
+ tmpname = host .find ("hostnames/hostname" ).attrib ["name" ]
517
522
tmpname = highlightTerm (tmpname , tmpname )
518
- except :
519
- tmpname = " "
520
523
print ("Finding exploits for " + tmpaddr +
521
524
" (" + tmpname + ")" ) # print name of machine
522
- for service in host .find_all ("service" ):
523
- terms .append (str (service .get ("name" )))
524
- terms .append (str (service .get ("product" )))
525
- terms .append (str (service .get ("version" )))
525
+ for service in host .findall ("ports/port/service" ):
526
+ if "name" in service .attrib .keys ():
527
+ terms .append (str (service .attrib ["name" ]))
528
+ if "product" in service .attrib .keys ():
529
+ terms .append (str (service .get ("product" )))
530
+ if "version" in service .attrib .keys ():
531
+ terms .append (str (service .get ("version" )))
526
532
validTerm (terms )
527
533
print ("Searching terms:" , terms ) # displays terms found by xml
528
534
searchsploitout () # tests search terms by machine
529
535
terms = [] # emptys search terms for next search
536
+
530
537
return True
531
538
532
539
@@ -693,7 +700,7 @@ def run():
693
700
elif parseArgs .examine != None :
694
701
examine (parseArgs .examine )
695
702
return
696
-
703
+
697
704
# formatting exclusions
698
705
if not parseArgs .case :
699
706
for i in range (len (parseArgs .exclude )):
0 commit comments