[okular] [Bug 398096] New: Especially crafted Okular archives may lead to an arbitrary file creation on the user workstation

Joran Hervé bugzilla_noreply at kde.org
Fri Aug 31 13:52:24 BST 2018


https://bugs.kde.org/show_bug.cgi?id=398096

            Bug ID: 398096
           Summary: Especially crafted Okular archives may lead to an
                    arbitrary file creation on the user workstation
           Product: okular
           Version: unspecified
          Platform: Other
                OS: Linux
            Status: UNCONFIRMED
          Severity: major
          Priority: NOR
         Component: general
          Assignee: okular-devel at kde.org
          Reporter: joran.herve at gmail.com
  Target Milestone: ---

Created attachment 114718
  --> https://bugs.kde.org/attachment.cgi?id=114718&action=edit
Proof of Concept

Hello,


I found an issue that may allow to maliciously deploy file at arbitrary
location by opening Okular archives.

When opening an Okular archive, "content.xml" is parsed in order to extract the
document name (field "DocumentFileName"). If this file is also present in the
archive, it is temporarily saved inside "/tmp" under a random name with
"okular_XXXXXX.extension" form and is finally opened by the viewer.

The issue comes from the "unpackDocumentArchive(...)" of "core/document.cpp":

1: To create the temporary name of the document, this function search extract
the extension of the "DocumentFileName" using the following line:

const int dotPos = documentFileName.indexOf( QLatin1Char('.') );
if ( dotPos != -1 )
    archiveData->document.setFileTemplate(QDir::tempPath() +
QLatin1String("/okular_XXXXXX") + documentFileName.mid(dotPos));

In case of a "DocumentFileName" named "this.is.a.test", the temporary name will
have the form "/tmp/okular_XXXXXX.is.a.test".
If "DocumentFileName" was "aaa.aaa/../../testXXXXXX.txt", the temporary name
would become the path "/tmp/okular_XXXXXX.aaa/../../testXXXXXX.txt".



2: Before generating this name, the function "unpackDocumentArchive(...)" check
if the document exists using the following code:

const KArchiveEntry * docEntry = mainDir->entry( documentFileName );
if ( !docEntry || !docEntry->isFile() )
    return nullptr;

Archives are not supposed to contain files with relative paths but it is
possible to manually craft them. As the "KArchiveDirectory" class used to parse
archives do not raise any exceptions in such case, it is possible to control
the path of the temporary file (with exception of the six random characters).



3: Such temporary files are supposed to be removed when closing Okular which
limit the impact of this bug. However, it may be possible to forge malicious
archives containing documents that would cause a crash of Okular during opening
(for example a document with very large pictures to ran out of memory) in order
to avoid the deletion phase. As PDF may be "polyglot" (
https://en.wikipedia.org/wiki/Polyglot_(computing) ), the document could also
contain a configuration file or an executable to deploy on the victim
workstation.



Correcting this issue may be done by searching the last dot and not the first
one on the line :
const int dotPos = documentFileName.indexOf( QLatin1Char('.') );

To illustrate this issue, I have joined an Okular archive file which (when
opened with "root" permission) create a polyglot (PDF/script) file named
"payloadXXXXX.pdf" in the "/root/" folder.

I'm apologizing for the mistakes and am available if you have any question.


Best regards,

Joran HERVE

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the Okular-devel mailing list