Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for docker support + Added ssl/tls verification flag #121

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
__pycache__
**/__pycache__
.vscode
Dockerfile
*.pyc
*.pyo
*.pyd
.Python
env
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.log
.git
.gitignore
.pytest_cache
.travis.yml
docker-envs
burp_extension
burp_extension.py
tests
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ node_modules
# Jython
*.class

# VS-code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

# Vim
# swap
.sw[a-p]
Expand Down
16 changes: 16 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Current File with Arguments",
"type": "debugpy",
"request": "launch",
"program": "tplmap.py",
"console": "integratedTerminal",
"args": "-u http://localhost/?name=so -k"
}
]
}
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM python:3.9

WORKDIR /app
COPY . /app

RUN useradd -ms /bin/bash user
RUN chown -R user:user /app
USER user

RUN python -m pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt

# Running the script when the container launches
ENTRYPOINT ["python", "tplmap.py"]

# Default cmd
CMD ["-h"]

22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
Tplmap
======

> This project is no longer maintained. I'm happy to merge new PRs as long they don't break the [test suite](https://github.com/epinna/tplmap/wiki/Run-the-test-suite).

Tplmap assists the exploitation of Code Injection and Server-Side Template Injection vulnerabilities with a number of sandbox escape techniques to get access to the underlying operating system.

The tool and its test suite are developed to research the SSTI vulnerability class and to be used as offensive security tool during web application penetration tests.
Expand Down Expand Up @@ -98,7 +96,7 @@ Use `--os-shell` option to launch a pseudo-terminal on the target.

```
$ ./tplmap.py --os-shell -u 'http://www.target.com/page?name=John'
[+] Tplmap 0.5
[+] Tplmap 0.3
Automatic Server-Side Template Injection Detection and Exploitation Tool

[+] Run commands on the operating system.
Expand All @@ -110,14 +108,21 @@ root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
```
### Using docker
You can use docker instead, if you encounter any issue with the script (mostly caused by python2 dependencies e.g yaml).
```console
$ docker build -t tplmap .
$ docker run --rm tplmap:latest -h
$ docker run --rm tplmap:latest -u 'http://www.target.com/page?name=jhon'
```

Supported template engines
--------------------------

Tplmap supports over 15 template engines, unsandboxed template engines and generic _eval()_-like injections.

| Engine | Remote Command Execution | Blind | Code evaluation | File read | File write |
|------------------------|---------------|-------------------|-----------------|-----------|------------|
| Template engine | Remote Command Execution | Blind | Code evaluation | File read | File write |
|------------------------|-------|-------------------|-----------------|-----------|------------|
| Mako | ✓ | ✓ | Python | ✓ | ✓ |
| Jinja2 | ✓ | ✓ | Python | ✓ | ✓ |
| Python (code eval) | ✓ | ✓ | Python | ✓ | ✓ |
Expand All @@ -134,10 +139,9 @@ Tplmap supports over 15 template engines, unsandboxed template engines and gener
| ERB | ✓ | ✓ | Ruby | ✓ | ✓ |
| Smarty (unsecured) | ✓ | ✓ | PHP | ✓ | ✓ |
| PHP (code eval) | ✓ | ✓ | PHP | ✓ | ✓ |
| Twig (<=1.19) | ✓ | ✓ | PHP | ✓ | ✓ |
| Freemarker | ✓ | ✓ | Java | ✓ | ✓ |
| Velocity | ✓ | ✓ | Java | ✓ | ✓ |
| Twig (>1.19) | × | × | × | × | × |
| Freemarker | ✓ | ✓ | × | ✓ | ✓ |
| Velocity | ✓ | ✓ | × | ✓ | ✓ |
| Twig | × | × | × | × | × |
| Smarty (secured) | × | × | × | × | × |
| Dust (> [email protected]) | × | × | × | × | × |

Expand Down
9 changes: 6 additions & 3 deletions core/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def __init__(self, args):

self.injs = []
self.inj_idx = 0
self.ssl_verf = self.args.get('ssl_verf')

proxy = self.args.get('proxy')
if proxy:
Expand Down Expand Up @@ -201,6 +202,7 @@ def req(self, injection):
post_params = deepcopy(self.post_params)
header_params = deepcopy(self.header_params)
url_params = self.base_url
ssl_verfication = self.ssl_verf

# Pick current injection by index
inj = deepcopy(self.injs[self.inj_idx])
Expand Down Expand Up @@ -298,9 +300,10 @@ def req(self, injection):
data = post_params,
headers = header_params,
proxies = self.proxies,
# By default, SSL check is skipped.
# TODO: add a -k curl-like option to set this.
verify = False
# By default, SSL check is not skipped.
# WARNING : Using this option makes the transfer insecure.
# TODO: add a -k curl-like option to set this. (Done)
verify = ssl_verfication
).text
except requests.exceptions.ConnectionError as e:
if e and e[0] and e[0][0] == 'Connection aborted.':
Expand Down
2 changes: 0 additions & 2 deletions core/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@
from plugins.languages.php import Php
from plugins.languages.python import Python
from plugins.languages.ruby import Ruby
from core.channel import Channel
from utils.loggers import log
from core.clis import Shell, MultilineShell
from core.tcpserver import TcpServer
import time
import telnetlib
import sys

Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ chardet==3.0.4
idna==2.8
requests==2.22.0
urllib3==1.24.1
wsgiref==0.1.2
2 changes: 0 additions & 2 deletions tests/basetest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from core.channel import Channel
Expand Down
2 changes: 0 additions & 2 deletions tests/test_channel.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.mako import Mako
Expand Down
1 change: 0 additions & 1 deletion tests/test_java_freemarker.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import unittest
import requests
import os
import sys

Expand Down
2 changes: 0 additions & 2 deletions tests/test_java_velocity.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.velocity import Velocity
Expand Down
2 changes: 0 additions & 2 deletions tests/test_node_dot.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.dot import Dot
Expand Down
2 changes: 0 additions & 2 deletions tests/test_node_dust.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.dust import Dust
Expand Down
2 changes: 0 additions & 2 deletions tests/test_node_ejs.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.ejs import Ejs
Expand Down
2 changes: 0 additions & 2 deletions tests/test_node_javascript.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.languages.javascript import Javascript
Expand Down
2 changes: 0 additions & 2 deletions tests/test_node_marko.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.marko import Marko
Expand Down
2 changes: 0 additions & 2 deletions tests/test_node_nunjucks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.nunjucks import Nunjucks
Expand Down
2 changes: 0 additions & 2 deletions tests/test_node_pug.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.pug import Pug
Expand Down
4 changes: 0 additions & 4 deletions tests/test_php_php.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.languages.php import Php
from core.channel import Channel
from core.checks import detect_template_injection
from basetest import BaseTest, EXTRA_DOWNLOAD


Expand Down
2 changes: 0 additions & 2 deletions tests/test_php_smarty_secured.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.smarty import Smarty
Expand Down
2 changes: 0 additions & 2 deletions tests/test_php_smarty_unsecured.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.smarty import Smarty
Expand Down
3 changes: 0 additions & 3 deletions tests/test_php_twig_secured.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.twig import Twig
from core.channel import Channel
from basetest import BaseTest

class TwigSecuredTest(unittest.TestCase, BaseTest):
Expand Down
3 changes: 0 additions & 3 deletions tests/test_php_twig_unsecured.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.engines.twig import Twig
from core.channel import Channel
from basetest import BaseTest

class TwigUnsecuredTest(unittest.TestCase, BaseTest):
Expand Down
5 changes: 0 additions & 5 deletions tests/test_py_jinja2.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(10, os.path.join(sys.path[0], '..'))
from plugins.engines.jinja2 import Jinja2
from core.channel import Channel
from utils import rand
from utils import strings
from basetest import BaseTest

class Jinja2Test(unittest.TestCase, BaseTest):
Expand Down
4 changes: 0 additions & 4 deletions tests/test_py_mako.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(10, os.path.join(sys.path[0], '..'))
from plugins.engines.mako import Mako
from core.channel import Channel
from utils import rand
from utils import strings
from basetest import BaseTest

class MakoTest(unittest.TestCase, BaseTest):
Expand Down
4 changes: 0 additions & 4 deletions tests/test_py_python.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(1, os.path.join(sys.path[0], '..'))
from plugins.languages.python import Python
from core.channel import Channel
from core.checks import detect_template_injection
from basetest import BaseTest


Expand Down
5 changes: 0 additions & 5 deletions tests/test_py_tornado.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import unittest
import requests
import os
import sys
import random

sys.path.insert(10, os.path.join(sys.path[0], '..'))
from plugins.engines.tornado import Tornado
from core.channel import Channel
from utils import rand
from utils import strings
from basetest import BaseTest

class TornadoTest(unittest.TestCase, BaseTest):
Expand Down
Loading