PDF签名系列(1):PDF签名机制的漏洞分析
來(lái)源:PDF簽名系列(1):PDF簽名機(jī)制的漏洞分析 - 知乎
研究PDF文件的簽名機(jī)制有一段時(shí)間了,剛開(kāi)始學(xué)習(xí)的時(shí)候就看到有提到說(shuō),被簽名的PDF內(nèi)容的Range gap,會(huì)成為這個(gè)機(jī)制的漏洞,但是一直不能完全參透。直到昨天看到一篇文章的分析,才對(duì)這個(gè)問(wèn)題有了一個(gè)更清晰的認(rèn)識(shí),所以做一個(gè)小小總結(jié)整理。
這里假設(shè)讀者對(duì)PDF文件格式和數(shù)字簽名的原理有一定了解。
首先,我們來(lái)看一下PDF文檔里的Signature Dictionary:
我們知道,PDF文件是由一系列Objects組成的,通過(guò)objects的互相引用,組織成了一個(gè)文檔的appearance. 對(duì)于一個(gè)簽過(guò)名的文檔來(lái)說(shuō),最重要的就是上圖這樣一個(gè)dictionary類型的object.
用一張圖來(lái)簡(jiǎn)單說(shuō)明一下PDF的簽名機(jī)制。
上圖是一個(gè)加入了數(shù)字簽名的PDF文檔內(nèi)容。被簽名的文檔內(nèi)容是整個(gè)文檔,但是除去了Contents入口下面的具體值。簡(jiǎn)單來(lái)說(shuō),是對(duì)圖中藍(lán)色部分的所有內(nèi)容做哈希,然后對(duì)哈希做簽名,最后把簽名值以及相關(guān)內(nèi)容寫(xiě)進(jìn)圖中粉色部分。
好了,這樣的方法,有什么漏洞呢?
先簡(jiǎn)單描繪一下PDF文檔的簽名流程:
1. 把文檔序列化成一個(gè)字節(jié)串,中間預(yù)留出合適的空間存放簽名值,此步驟稱為preliminary serialization
2. 將字節(jié)串預(yù)留的空間去掉,生成新的字節(jié)串,稱為signing serialization
3. 根據(jù)signing serilization生成簽名數(shù)據(jù)塊寫(xiě)入步驟一的preliminary serialization。簽名完畢。
下面來(lái)詳細(xì)描述下這個(gè)機(jī)制隱含的一個(gè)漏洞:
假設(shè)生成兩個(gè)preliminary serilization字節(jié)串A1,A2;可以看到文檔里包含兩個(gè)catalog.
Note:一般來(lái)說(shuō),catalog是整個(gè)PDF的入口,所有用來(lái)顯示PDF所用到的內(nèi)容object都是從catalog開(kāi)始逐級(jí)引用的。所以理論上來(lái)說(shuō),文檔內(nèi)容里允許有冗余的object,也就是說(shuō),此object雖然在文檔中定義了,但是在顯示的時(shí)候,并沒(méi)有被引用到。
另外,我們可以知道,object的相對(duì)位置是可以改變的,只要修改了xreftable里對(duì)object的offset的描述,那么最終顯示的效果是一樣的。
?
我們可以看到,通過(guò)將A1和A2中的gap去掉,生成signing serialization B1和B2之后,B1和B2可以是完全一樣的字節(jié)串。因此最終的簽名值也會(huì)是一樣的。
當(dāng)簽名值被嵌入回原來(lái)的A1和A2之后,生成了最終簽名文件C1和C2.
可以看到,C1和C2是兩個(gè)不同的文檔了,雖然是相同的xreftable,相同的catalog的offset,但是C1索引到了catalog1,C2索引到了catalog2,所以C1和C2渲染出來(lái)的文檔可以是totally不同的內(nèi)容。但是簽名值確實(shí)對(duì)兩個(gè)文檔都是合法的簽名值,這有悖于數(shù)字簽名的原則。
思考下這個(gè)問(wèn)題的根源來(lái)自PDF文檔允許冗余的object存在,所以這個(gè)漏洞能否存在取決于是否認(rèn)為這是PDF符合語(yǔ)法規(guī)范的。
參考文檔:
Collisions in PDF Signatures
?
總結(jié)
以上是生活随笔為你收集整理的PDF签名系列(1):PDF签名机制的漏洞分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java 数字计算精度问题
- 下一篇: 带暂停功能的音频播放代码参考