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