Skip to content

Commit

Permalink
Version 1.1.1 (Improvements)
Browse files Browse the repository at this point in the history
Improved config functionality
Fixed crawling changing settings
Fixed automatic imports
Added warning for new python versions

A minor update with simple improvements and fixes
  • Loading branch information
vladko312 authored Apr 27, 2023
1 parent 5882e5a commit f37658e
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 30 deletions.
3 changes: 1 addition & 2 deletions core/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from utils.loggers import log
from urllib import parse
from copy import deepcopy
import utils.config
from utils.random_agent import get_agent


Expand Down Expand Up @@ -177,7 +176,7 @@ def req(self, injection):
result = ""
else:
raise
if utils.config.log_response:
if self.args.get("log_response", False):
log.debug(f"< {result}")
return result

Expand Down
14 changes: 8 additions & 6 deletions core/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,9 @@ def do_run(self, line):
for url in urls:
print()
log.log(23, f'Scanning url: {url}')
self.sstimap_options['url'] = url
self.channel = Channel(self.sstimap_options)
url_options = self.sstimap_options.copy()
url_options['url'] = url
self.channel = Channel(url_options)
self.current_plugin = checks.check_template_injection(self.channel)
if self.channel.data.get('engine'):
break # TODO: save vulnerabilities
Expand All @@ -218,10 +219,11 @@ def do_run(self, line):
for form in forms:
print()
log.log(23, f'Scanning form with url: {form[0]}')
self.sstimap_options['url'] = form[0]
self.sstimap_options['method'] = form[1]
self.sstimap_options['data'] = parse.parse_qs(form[2], keep_blank_values=True)
self.channel = Channel(self.sstimap_options)
url_options = self.sstimap_options.copy()
url_options['url'] = form[0]
url_options['method'] = form[1]
url_options['data'] = parse.parse_qs(form[2], keep_blank_values=True)
self.channel = Channel(url_options)
self.current_plugin = checks.check_template_injection(self.channel)
if self.channel.data.get('engine'):
break # TODO: save vulnerabilities
Expand Down
3 changes: 1 addition & 2 deletions core/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import threading
import time
import sys
import utils.config

loaded_plugins = {}

Expand Down Expand Up @@ -54,7 +53,7 @@ def __init__(self, channel):
self.render_req_tm = collections.deque([0.5], maxlen=5)
# The delay fortime-based blind injection. This will be added
# to the average response time for render values.
self.tm_delay = utils.config.time_based_blind_delay
self.tm_delay = self.channel.args.get('time_based_blind_delay', 4)
# Declare object attributes
self.actions = {}
self.contexts = []
Expand Down
24 changes: 15 additions & 9 deletions sstimap.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
if sys.version_info.major != 3 or sys.version_info.minor < 6:
print('\033[91m[!]\033[0m SSTImap was created for Python3.6 and above. Python'+str(sys.version_info.major)+'.'+str(sys.version_info.minor)+' is not supported!')
sys.exit()
if sys.version_info.minor > 11:
print('\033[33m[!]\033[0m This version of SSTImap was not tested with Python3.'+str(sys.version_info.minor))
import urllib
import importlib
import os
Expand All @@ -12,14 +14,16 @@
from core.interactive import InteractiveShell
from utils.loggers import log
from utils.crawler import crawl, find_page_forms
from utils.config import config_args
import traceback


version = '1.1.0'
version = '1.1.1'


def main():
args = vars(cliparser.options)
args = config_args(args)
args['version'] = version
if not (args['url'] or args['interactive']):
# no target specified
Expand All @@ -40,8 +44,9 @@ def main():
for url in urls:
print()
log.log(23, f'Scanning url: {url}')
args['url'] = url
channel = Channel(args)
url_args = args.copy()
url_args['url'] = url
channel = Channel(url_args)
checks.check_template_injection(channel)
if channel.data.get('engine'):
break # TODO: save vulnerabilities
Expand All @@ -52,10 +57,11 @@ def main():
for form in forms:
print()
log.log(23, f'Scanning form with url: {form[0]}')
args['url'] = form[0]
args['method'] = form[1]
args['data'] = urllib.parse.parse_qs(form[2], keep_blank_values=True)
channel = Channel(args)
url_args = args.copy()
url_args['url'] = form[0]
url_args['method'] = form[1]
url_args['data'] = urllib.parse.parse_qs(form[2], keep_blank_values=True)
channel = Channel(url_args)
checks.check_template_injection(channel)
if channel.data.get('engine'):
break # TODO: save vulnerabilities
Expand All @@ -68,10 +74,10 @@ def main():

def load_plugins():
importlib.invalidate_caches()
groups = os.scandir("plugins")
groups = os.scandir(f"{sys.path[0]}/plugins")
groups = filter(lambda x: x.is_dir(), groups)
for g in groups:
modules = os.scandir(f"plugins/{g.name}")
modules = os.scandir(f"{sys.path[0]}/plugins/{g.name}")
modules = filter(lambda x: (x.name.endswith(".py") and not x.name.startswith("_")), modules)
for m in modules:
importlib.import_module(f"plugins.{g.name}.{m.name[:-3]}")
Expand Down
10 changes: 5 additions & 5 deletions utils/cliparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ def banner():
target.add_argument("-i", "--interactive", action="store_true", dest="interactive",
help="Run SSTImap in interactive mode")
target.add_argument("-c", "--crawl", dest="crawl_depth", type=int,
help="Depth to crawl (default/0: don't crawl)", default=0)
help="Depth to crawl (default/0: don't crawl)")
target.add_argument("-f", "--forms", action="store_true", dest="forms",
help="Scan page(s) for forms")


request = parser.add_argument_group(title="request", description="These options can specify how to connect to the "
"target URL and add possible attack vectors")
request.add_argument("-M", "--marker", dest="marker",
help="Use string as injection marker (default '*')", default='*')
help="Use string as injection marker (default '*')")
request.add_argument("-d", "--data", action="append", dest="data",
help="POST data param to send (e.g. 'param=value') [Stackable]", default=[])
request.add_argument("-H", "--header", action="append", dest="headers", metavar="HEADER",
Expand All @@ -63,18 +63,18 @@ def banner():

detection = parser.add_argument_group(title="detection",
description="These options can be used to customize the detection phase.")
detection.add_argument("-l", "--level", dest="level", type=int, default=1,
detection.add_argument("-l", "--level", dest="level", type=int,
help="Level of escaping to perform (1-5, Default: 1)")
detection.add_argument("-L", "--force-level", dest="force_level", metavar=("LEVEL", "CLEVEL",),
help="Force a LEVEL and CLEVEL to test", nargs=2)
detection.add_argument("-e", "--engine", dest="engine",
help="Check only this backend template engine")
detection.add_argument("-r", "--technique", dest="technique",
help="Techniques R(endered) T(ime-based blind). Default: RT", default="RT")
help="Techniques R(endered) T(ime-based blind). Default: RT")
detection.add_argument("-P", "--legacy", "--legacy-payloads", dest="legacy", action="store_true",
help="Include old payloads, that no longer work with newer versions of the engines")
detection.add_argument("--crawl-exclude", dest="crawl_exclude", help="Regex in URLs to not crawl")
detection.add_argument("--crawl-domains", dest="crawl_domains", default="S",
detection.add_argument("--crawl-domains", dest="crawl_domains",
help="Crawl other domains: Y(es) / S(ubdomains) / N(o). Default: S")


Expand Down
37 changes: 31 additions & 6 deletions utils/config.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,47 @@
import os
import sys
import json

defaults = {
"crawl_depth": 0,
"marker": '*',
"level": 1,
"technique": "RT",
"crawl_domains": "S",
"log_response": False,
"time_based_blind_delay": 4
}
config = {}

config_folder = os.path.dirname(os.path.realpath(__file__))
user_config = {}

# TODO: fix this
with open(config_folder + "/../config.json", 'r') as stream:
with open(f"{sys.path[0]}/config.json", 'r') as stream:
try:
config = json.load(stream)
except json.JSONDecodeError as e:
print(f'[!][config] {e}')

base_path = os.path.expanduser(config.get("base_path", "~/.sstimap/"))
log_response = config.get("log_response", False)
time_based_blind_delay = config.get("time_based_blind_delay", 4)

if not os.path.isdir(base_path):
os.makedirs(base_path)

if os.path.exists(f"{base_path}/config.json"):
with open(f"{base_path}/config.json", 'r') as stream:
try:
user_config = json.load(stream)
except json.JSONDecodeError as e:
print(f'[!][user config] {e}')


def config_update(base, added):
for i in added:
if added[i] is not None or i not in base:
base[i] = added[i]


def config_args(args):
res = defaults.copy()
config_update(res, config)
config_update(res, user_config)
config_update(res, args)
return res

0 comments on commit f37658e

Please sign in to comment.