2222# RC info
2323
2424progname = os .path .basename (argv [0 ])
25- VERSION = "v1.5" # Program version
25+ VERSION = "v1.5" # Program version
2626files_array = [] # Array options with file names
2727name_array = [] # Array options with database names
2828path_array = [] # Array options with paths to database files
@@ -34,18 +34,25 @@ def scrapeRC():
3434 """
3535 divider = []
3636
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 )
4956
5057 for i in settings :
5158 if (i == "" or i [0 ] == "#" ):
@@ -62,17 +69,8 @@ def scrapeRC():
6269
6370 # This section is to remove database paths that do not exist
6471 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 ]))):
7674 files_array .pop (i )
7775 name_array .pop (i )
7876 path_array .pop (i )
@@ -151,7 +149,8 @@ def scrapeRC():
151149 help = "Display the EDB-ID value rather than local path." )
152150parser .add_argument ("--nmap" , metavar = "file.xml" , nargs = "?" , type = argparse .FileType ("r" ), default = None , const = os .sys .stdin ,
153151 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 ))
155154parser .add_argument ("--exclude" , nargs = "*" , type = str , default = list (), metavar = "[terms]" ,
156155 help = "Remove certain terms from the results. Option best added after all other terms have been gathered." )
157156
@@ -171,7 +170,7 @@ def update():
171170
172171 # update via git
173172 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" )
175174 print ("[i] Git Pull Complete" )
176175 os .chdir (cwd )
177176 return
@@ -183,7 +182,7 @@ def update():
183182def drawline ():
184183 """ Draws a line in the terminal.
185184 """
186- line = "" * (int (COL ) - 1 )
185+ line = "" * (int (COL ) - 1 )
187186 print (line )
188187
189188
@@ -193,7 +192,7 @@ def drawline(lim):
193192 """
194193 line = "-" * lim
195194 line += "+"
196- line += "-" * (COL - lim - 2 ) # -2 for terminal padding
195+ line += "-" * (COL - lim - 2 ) # -2 for terminal padding
197196 print (line )
198197
199198
@@ -203,19 +202,24 @@ def highlightTerm(line, term):
203202 @term: the term that will be found in line and used to highlight the line\n
204203 @autoComp: [optional] if true, then it will output the string with the flags already turned into ANSI
205204 """
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
215219 return line
216220
217221
218- def separater (lim , line1 :str , line2 :str ):
222+ def separater (lim , line1 : str , line2 : str ):
219223 """ Splits the two texts to fit perfectly within the terminal width
220224 """
221225 lim = int (lim )
@@ -224,10 +228,17 @@ def separater(lim, line1:str, line2:str):
224228 print (line )
225229 return
226230
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+
231242 # increase lim by markers to not include highlights in series
232243 last_mark = 0
233244 while (line1 .find ("\033 [91m" , last_mark , line1_length + 5 ) >= 0 ):
@@ -246,9 +257,9 @@ def separater(lim, line1:str, line2:str):
246257 line2_length += 4
247258 last_mark = line2 .find ("\033 [0m" , last_mark , line2_length + 4 ) + 4
248259
249-
250260 # 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 )
252263 line = fstring .format (title = line1 , path = line2 )
253264 print (line )
254265
@@ -461,6 +472,8 @@ def nmapxml(file=""):
461472 if no file name is given, then it tries stdin\n
462473 @return: returns true if it fails
463474 """
475+ import xml .etree .ElementTree as ET
476+
464477 global terms
465478 global STDIN
466479
@@ -486,47 +499,41 @@ def nmapxml(file=""):
486499 if content == "" or content [:5 ] != "<?xml" :
487500 STDIN = content
488501 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
497502 # Read XML file
498503
499504 # ## Feedback to enduser
500505 if (type (file ) == str ):
501- print ("[i] Reading: " + highlightTerm (str (file ), str (file ), True ))
506+ print ("[i] Reading: " + highlightTerm (str (file ), str (file )))
502507 else :
503- print ("[i] Reading: " + highlightTerm (file .name , file .name , True ))
508+ print ("[i] Reading: " + highlightTerm (file .name , file .name ))
504509 tmpaddr = ""
505510 tmpname = ""
506511 # ## 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 )
509513
510- hostsheet = xmlsheet . find_all ("host" )
514+ hostsheet = root . findall ("host" )
511515 for host in hostsheet :
512516 # made these lines to separate searches by machine
513- tmpaddr = host .find ("address" ).get ( "addr" )
517+ tmpaddr = host .find ("address" ).attrib [ "addr" ]
514518 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" ]
517522 tmpname = highlightTerm (tmpname , tmpname )
518- except :
519- tmpname = " "
520523 print ("Finding exploits for " + tmpaddr +
521524 " (" + 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" )))
526532 validTerm (terms )
527533 print ("Searching terms:" , terms ) # displays terms found by xml
528534 searchsploitout () # tests search terms by machine
529535 terms = [] # emptys search terms for next search
536+
530537 return True
531538
532539
@@ -693,7 +700,7 @@ def run():
693700 elif parseArgs .examine != None :
694701 examine (parseArgs .examine )
695702 return
696-
703+
697704 # formatting exclusions
698705 if not parseArgs .case :
699706 for i in range (len (parseArgs .exclude )):
0 commit comments