|Affected Products:||libpurple (all versions), libpurple clients with DBUS support (incl. all versions of pidgin), pidgin-otr (all versions)|
|Class:||Information Exposure (CWE-200), Privacy Violation (CWE-359), Information Exposure Through Sent Data (CWE-201)|
|Discovered by:||Dimitris Glynos|
libpurple-based applications broadcast the plaintext of OTR (off-the-record) conversations over DBUS.
This makes the plaintext available to other (possibly unrelated) applications executing under the same
user. Also, due to a design flaw in libpurple, the user’s choice of not logging OTR plaintext on Pidgin is not communicated over to the third party applications listening on DBUS. This may lead to unintentional (on disk) logging of private messages.
libpurple is an Instant Messaging (IM) library developed by the Pidgin project. It is used by a number of IM clients including Pidgin and Adium. libpurple-based clients support the OTR (“Off-the-Record”) protocol either natively or via a plugin. The OTR messaging protocol enables users to communicate securely over any IM network.
If libpurple is compiled with DBUS support and there is a DBUS session daemon running on the system, then all messages passing through libpurple are broadcasted over DBUS. The reason behind this is to allow for third party applications, such as desktop widgets to process these
messages (e.g. create an animation when a message arrives). However, among the messages transmitted over DBUS one also finds the plaintext form of OTR conversations. This is a security problem, as the private OTR messages may leak to other (unrelated) processes that are executing
under the same user as the libpurple-based application.
The core issue lies in the fact that when private information is broadcasted over DBUS
there is no guaranty as to which applications will receive this and how they will handle it.
The IM client that decrypts OTR ciphertext might enforce special security policies
to protect the plaintext (such as disallow logging), but there is no way of making
these policies mandatory for the 3rd party applications that receive the plaintext
via DBUS. The sender essentially relies on the receiver being a “good citizen” and
honoring the security attributes of incoming DBUS signals.
Also, as pointed out by Howard Chu, libpurple does not allow for full attribute manipulation
by plug-ins. Hence, with the current API of libpurple, it is impossible for pidgin-otr to
indicate to other applications that logging is prohibited for private messages.
This issue is associated with a low risk factor, as it requires from an attacker to have already
gained same-user access to the victim user’s host. However, we will provide some exploitation notes
on this, mostly for reasons of completeness. For our exploitation example we will be focusing on
the popular libpurple-based application, Pidgin.
To snoop in on a Pidgin user’s conversation a remote attacker would need to connect to the
DBUS daemon that is responsible for the user’s session. There are at least two ways
to achieve this.
The first one is to exploit an application that runs within the same desktop session
as Pidgin. This application would have inherited the necessary DBUS_SESSION_BUS_ADDRESS environmental variable and would thus be able to connect to the DBUS daemon over a unix socket
without a problem.
The second way is to compromise the user’s account in some way and steal the DBUS_SESSION_BUS_ADDRESS value. There are multiple ways of acquiring the value
for this variable, one of them being through /proc/<pid>/environ (which is accessible to processes of the same owner), and another being through a file in ~/.dbus/session-bus/. Using this value, the attacker would now be able to connect to DBUS with applications that are not
part of the desktop session.
Please note that the above methods do not require any control over the Pidgin process (ptrace or other).
pidgin-otr-snooping.py is a proof-of-concept
Python script that connects to DBUS and prints all messages received via Pidgin’s “ReceivedImMsg” and “WroteImMsg” signals. The example below shows messages transmitted during an OTR conversation:
user@host:~$ python pidgin-otr-snooping.py
sent 'hey' to [email protected]
received 'ho' from [email protected]
sent 'lets go!' to [email protected]
An exploited application that connects to DBUS (or reuses an already established connection)
to listen for private messages provides identical forensic evidence (logs) as any application
that connects to DBUS for legitimate purposes. It is thus difficult to identify in-memory
eavesdropping of this sort, especially in cases where there is no supportive evidence that might
suggest it (offending process image, related traffic logs etc.).
A possible way to fix this issue is for libpurple to support a new type of IM messages,
i.e. private messages.
Most (if not all) communication primitives in libpurple use a flags parameter (of type PurpleMessageFlags) to qualify the type of message being transmitted/received. The example below shows the prototype of such a communication function from pidgin-2.10.1/libpurple/server.c:
557 void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
558 PurpleMessageFlags flags, time_t mtime)
type is defined in pidgin-2.10.1/libpurple/conversation.h
105 typedef enum
107 PURPLE_MESSAGE_SEND = 0x0001,
108 PURPLE_MESSAGE_RECV = 0x0002,
109 PURPLE_MESSAGE_SYSTEM = 0x0004,
110 PURPLE_MESSAGE_AUTO_RESP = 0x0008,
111 PURPLE_MESSAGE_ACTIVE_ONLY = 0x0010,
118 PURPLE_MESSAGE_NICK = 0x0020,
119 PURPLE_MESSAGE_NO_LOG = 0x0040,
120 PURPLE_MESSAGE_WHISPER = 0x0080,
121 PURPLE_MESSAGE_ERROR = 0x0200,
122 PURPLE_MESSAGE_DELAYED = 0x0400,
123 PURPLE_MESSAGE_RAW = 0x0800,
125 PURPLE_MESSAGE_IMAGES = 0x1000,
126 PURPLE_MESSAGE_NOTIFY = 0x2000,
127 PURPLE_MESSAGE_NO_LINKIFY = 0x4000,
129 PURPLE_MESSAGE_INVISIBLE = 0x8000
130 } PurpleMessageFlags;
This enumeration could be extended to include a new type for private messages. Private messages should by default not be logged by applications or be broadcasted over DBUS.
The Pidgin/libpurple development team has acknowledged this issue.
On a related note, Nadim Kobeissi has reported a similar leak in Adium. Apparently Adium forwards OTR plaintexts to the Growl notification system which by default keeps them in its notification history.
|Vendor Contact(s):||December 20th, 2011 [1, 2, 3]|
|CVE assignment:||February 21st, 2012|
|Public Disclosure:||February 25th, 2012|
We would like to thank Peter Lawler for his helpful comments.