如何解码PDF流?

40

我想分析一个PDF文件中使用的通过/FlateDecode编码的流对象。

是否有任何工具可以解码PDF中使用的这种编码(例如ASCII85decode、LZWDecode、RunlenghtDecode等)?

流内容很可能是PE文件结构,PDF可能会在后续的攻击中使用它。

另外,PDF中有两个xref表,这是可以的,但是在xref之后还有两个%%EOF。

这些存在是否正常?(注意:第二个xref使用/prev名称指向第一个xref。)

xref指向第二个xref

xref 
5 6
0000000618 00000 n
0000000658 00000 n
0000000701 00000 n
0000000798 00000 n
0000045112 00000 n
0000045219 00000 n
1 1
0000045753 00000 n
3 1
0000045838 00000 n
trailer
>
startxref
46090
%%EOF

第二个xref

xref
0 5
0000000000 65535 f
0000000010 00000 n
0000000067 00000 n
0000000136 00000 n
0000000373 00000 n
trailer
>
startxref
429
%%EOF
7个回答

22
  1. "Two xref tables and two %%EOF"?

    This alone is not an indication of a malicious PDF file. There can by two or even more instances of each, if the file was generated via the "incremental update" feature. (Each digitally signed PDF file is like that, and each file which was changed in Acrobat and saved by using the 'Save' button/menu instead of the 'Save as...' button/menu is like that too.)

  2. "How to decode a compressed PDF stream from a specific object"?

    Have a look at Didier Stevens' Python script pdf-parser.py. With this command line tool, you can dump the decoded stream of any PDF object into a file. Example command to dump the stream of PDF object number 13:

    pdf-parser.py -o 13 -f -d obj13.dump my.pdf
    

“每个数字签名的PDF文件都是这样吗?” - 不一定。只有在签名后添加更改而不破坏签名时,才严格需要增量更新。 - mkl
@mkl:你能给我展示一个已签名的PDF文件的例子吗?在签名后,你添加了更改,但这些更改不会破坏签名。 - Kurt Pfeifle
1
举个例子,PDF文件中有两个有效的集成签名。在已经签署的文档中添加另一个签名显然是一种签署后的更改。例如,请参见此SD DSS示例文件 - mkl
pdf-parser.py 对我很有用。https://gist.github.com/averagesecurityguy/ba8d9ed3c59c1deffbd1390dafa5a3c2 类似,但在某些 PDF 文件上会出现错误。您可以使用 zlib 压缩流。 - mrtechmaker
这给了我“不支持的过滤器:[/FlateDecode /DCTDecode]”和“不支持的过滤器:['/JBIG2Decode']”错误。 - SirHawrk

19

A 文件结尾应该包含一条 %%EOF 注释,其他注释(以 % 开头的任何行)可以出现在文件的任何位置。因此,是的,两条 %%EOF 注释都是完全有效的。这在PDF参考手册中有记录。请查看第112页的1.7 PDF参考手册中的示例3.11,其中包含您描述的结构。这是一个已经增量更新的PDF文件。

请注意,更新版本的PDF可能具有交叉引用流,它们本身是压缩的。

解码PDF文件的最简单方法是使用专为此目的而设计的工具,例如MuPDF可以使用 "mutool clean -d <input pdf file> <output PDF file>" 命令进行解压 (-d) PDF文件中所有已压缩的流,并将输出写入新的PDF文件。

否则,您需要使用类似zlib的工具进行Flate和LZW解压缩,还需要编写自己的RunLength解压缩以及ASCIIHex85解压缩。更不用说如果您想要解码图像,则需要使用JBIG、JPEG和JPEG2000等格式。


感谢您的回答,KenS。 - rebel87
4
有些相当愚蠢的人给原帖点了踩,同时还投票关闭了它。请给这个问题点赞以平衡这种情况... - Kurt Pfeifle

5
您可以使用RUPS来分析PDF并导出或查看已解码的流。关于%%EOF,您可以有与PDF添加数相同数量的EOF。

感谢 Paulo 的回答。 - rebel87
有些相當愚蠢的人對OP的問題進行了負投票,並投票要關閉它。請給問題點個贊,以平衡一下... - Kurt Pfeifle

4
关于工具,正如其他答案中所述,有许多工具可用于解压流(在命令行或其他方式上)。但是,还有许多工具可以通过允许您浏览对象树并轻松查看压缩流中的内容来轻松检查PDF文件。我使用过的两个工具是:
1)callas pdfToolbox Desktop(注意,我与这家公司有关联)。pdfToolbox有一个“浏览PDF”选项,允许您查看与页面相关的对象,直到包括实际页面操作符。
2)Enfocus Browser。该工具将允许您打开PDF文件的对象树根,然后以非常类似于Mac上文件系统的Finder的方式呈现对象层次结构。Browser甚至允许您编辑PDF文件(在这种情况下,您应该真正了解自己在做什么),通过编辑低级对象、创建新对象或更改流的内容。非常酷。
“有人指出,在我之前的回答中提到的Enfocus浏览器已经不可用,但实际上它是可以使用的。您只需要创建一个Enfocus帐户,就可以从这里下载它:https://www.enfocus.com/en/support/downloads/old-product-installers。”

1

有另一种情况,您可能会有两个%%EOF,其中文档不一定会被增量更新。

根据 ISO 32000-1:2008 PDF(1.7)官方标准的附录F,该附录详细介绍了“线性PDF”的内部结构:文件中有2个%%EOF。第一个出现在线性化参数字典之后的开头。该部分称为“第一页交叉引用尾随”。

引用此文件:

第一页的尾随内容应包含有效的Size和Root条目,以及显示文档所需的任何其他条目。 Size值应是第一页交叉引用表和主交叉引用表中条目数量的总和。第一页的尾随内容可以选择以startxref、整数和%%EOF结尾,就像普通尾随内容一样。这些信息将被忽略


-1

您可以复制粘贴PDF数据流,并使用this在线服务立即查看渲染。


-1

在Linux上,您可以使用mutool,它包含在mupdf-tools软件包中。 运行:

mutool clean -d inputfile.pdf out.pdf

将创建文件out.pdf并解码所有流。mutool还可以使用show命令提取和解码单个流,但我没有使用过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接