驅動簽名學習

 

簡述如何通過CryptAPI實現簽名的生成,並打到pe文件裏,時間戳部分還沒實現。

獲取PE文件簽名信息的工程:https://github.com/leeqwind/PESignAnalyzer

下面是一個有效的簽名信息

參考圖片中的簽名,簽名信息包含有時間戳,版本,摘要算法,後面跟着3小塊證書信息。可以看出證書的來源

issuer是頒發者,subject是頒發給。Mirosoft Code Verification Root 頒發給 VeriSign Class 3 Public Primary Certification Authority - G5 頒發給 VeriSign Class 3 Code Signing 2010 CA 頒發給 Qihoo 360 Software (Beijin) Company Limited。

編程實現細節:

簽名的存放信息在pe結構中的OptionalHeader中DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY],大小和偏移;

例如:size=0x1000,VirtualAddress=0x8000;表示在文件偏移0x8000處存放安全信息,大小爲0x1000,其結構信息參考https://docs.microsoft.com/zh-cn/windows/win32/api/wintrust/ns-wintrust-win_certificate?redirectedfrom=MSDN

簽名的生成,一個函數可以搞定SignerSignEx,參考https://docs.microsoft.com/zh-cn/windows/win32/seccrypto/signersignex?redirectedfrom=MSDN

sys和exe的有效簽名是不一樣的。微軟提供的例子好像只能給app簽名有效,給sys簽名還是加不上。這個時候用前面的工具查看簽名信息,證書信息只有一小塊,要補齊另外2塊,纔是完整的有效驅動簽名。補齊另外2塊實際上就是把證書來源補齊。

在SignerSignEx成功的基礎上ppSignerContext會返回簽名信息(是最後有效簽名的一部分),用CryptMsgControl(*,*,CMSG_CTRL_ADD_CERT,*)添加另外2個證書信息(這個的自己去找了),得到最後有效的簽名(注意長度以8字節對齊)

得到完整的簽名後,按照相關格式填到pe文件中,最後計算整個文件的checksum 保存到OptionalHeader中CheckSum中。

大功告成。

這個方法是學習wosigncode(比signtool好用多了)。還有另外一種方法是學習signtool的https://stackoverflow.com/questions/32210675/how-to-sign-an-exe-with-additional-certificates-using-cryptoapi-and-signersign,但是我按照上面的提示沒得成功,可惜了。

補充:如何完善證書鏈中的證書信息?

證書鏈的構成:spc(軟件頒發者證書)--->Intermediate CA(中級證書頒發機構的證書)--->root   CA(根證書)

一般spc包含在.pfx的文件中,這個應該比較好獲取;Itermediate CA證書包含spc證書頒發者的信息,獲取spc對應的Intermediate CA 可以通過調用CertGetCertificateChain(*),然後去CURRENT_USER ,“Ca”下找;root CA 可以去網上下,root CA 只有20幾個。

在mmc中查看Intermediate CA

 

最後是可惡的 時間戳:

爲了避免簽名被篡改,得給簽名再來個簽名---時間戳.時間戳簽名的組成是(時間戳服務器上的時間+第一個簽名的摘要(message digest+)的hash,再由時間戳證書對hash進行簽名,最後將結果返回給時間戳的請求者 。具體的細節可以參考網上公開的時間戳服務器(c#寫的)和CryptMsgVerifyCountersignatureEncoded()的實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章