|Affected Products:||Any application that uses the Rasterbar Software libtorrent library (versions ≤ 0.14.3) for BitTorrent file downloads.|
|Class:||Relative Path Traversal (CWE-23), Improper Handling of Syntactically Invalid Structure (CWE-228)|
|Discovered by:||Dimitris Glynos|
We have discovered an “arbitrary file overwrite” vulnerability in libtorrent that allows an
attacker to create and modify arbitrary files (and directories) in remote systems, with the effective rights of the user executing the vulnerable libtorrent-based application.
libtorrent is an open-source C++ bittorrent library by Rasterbar
Software that is used in many desktop applications and embedded devices.
Popular BitTorrent clients that use this library are “firetorrent”,
“qBittorrent” and “deluge Torrent”. See here for a more comprehensive list of libtorrent-based applications.
libtorrent (up to and including version 0.14.3) employs an insufficient path sanitization method that allows the formulation of relative paths from the path elements described in .torrent files. Specifically, this applies to .torrent files that describe multiple files (see “Multiple File Mode”). An adversary could use such relative paths, in a specially crafted .torrent file,
to replace or create files in vulnerable systems.
The BitTorrent specification states that
in Multiple File Mode the filename path is: a list containing one or more string elements that together represent the path and filename. Each element in the list corresponds to either a directory name or (in the case of the final element) the filename. For example, the file “dir1/dir2/file.ext” would consist of three string elements: “dir1”, “dir2”, and “file.ext”. This is encoded as a bencoded list of strings such as “l4:dir14:dir28:file.exte”.
libtorrent provides a faithful implementation of this specification but fails to address the (albeit erroneous) case where the input does not conform to the above rules.
In src/torrent_info.cpp:184 (libtorrent-0.14.3) we find that the only check that is
performed on the directory components is an equality check for “..”:
184: for (int i = 0, end(p->list_size()); i < end; ++i)
186: if (p->list_at(i)->type() != lazy_entry::string_t)
187: return false;
188: std::string path_element = p->list_at(i)->string_value();
189: if (path_element != "..")
190: target.path /= path_element;
An attacker may fool this path sanitization mechanism by “overloading” a directory component
(such as “dir1” in the example above) with a string containing a (partial) relative path (e.g. “../../dir1”).
Line 190 will add any further path components to the overloaded one, thus constructing a path
that may point to any file location that is accessible via a relative path (e.g. “../../dir1/dir2/file.ext”). The attacker may use such paths in specially crafted .torrent files to replace or create new files on remote systems with data of his own choice. Furthermore, because of the way the Multiple File Mode works, any directories referrenced by these malicious torrent files (e.g. “../../dir1”, “../../dir1/dir2” etc.) will also be created as needed.
The maintainer of libtorrent has been contacted and a new version of the library (0.14.4)
has been released that addresses
this issue. All affected parties are advised to upgrade to the latest release.