Show Notes

161 - XMPP Stanza Smuggling in Jabber and a Cobalt Strike RCE

A vuln where ultimately untrusted input can make its way into eval() in a perl script via the Controller servlet. Sophos Firewall exposes two dashboards, a user portal and a web admin console. Both of these run a jetty server, which requests are issued to via the Controller servlet. Jetty will take the json param from the HTTP request and create an object to send to the “CSC” server, which will validate it using the CyberAPIArch perl script. The issue is the fact that an attacker can create a json object that contains a _discriminator key, which is a special key that’s used to map field values to object names. When the perl script sees _discriminator, it’ll iterate over the hashmap stored in the value to resolve the object names to Perl objects using eval(). By passing this key, an attacker effectively can pass arbitrary input to eval().

Interestingly, Sophos does have some filtering on the json keys here, but it seems the values aren’t filtered. This vuln was exploited in the wild to target a small number of organizations, and is similar to a previous bug that was abused by an APT in March.

Cisco’s Jabber, an XMPP client would treat the ending </stream:stream> XML tag as a special case resetting the state of the XML parsing, which would allow any next tag to be treated as the root of the XML document and allow injecting of control stanzas.

While Jabber passing through arbitrary XML as part of a message onto the recipient may sound dangerous, it is an intended feature to allow plugins to implement their own handlers. Where things go wrong is that the Gloox library for processing XML was modified to cleanup the state of the parser whenever it parsed the a closing stream:stream tag regardless of the context in-which is appears.

An attacker could inject a <stream:stream /> tag in their message, and then start providing a new XML stanze that can include control commands like pointing the recipient client to a new server, or adding contacts.

So Java’s Swing UI Toolkit in some cases will try to parse any strings that start with a < as HTML, and dangerously so as its handling of <object> tags will attempt to initialize a class with the name from the classid attribute (must inherit from java.awt.Component), and it will attempt to set any <param> tags through their setter functions.

The JSVGCanvas class could be abused to get JavaScript execution through an embeded <script> tag from there the script’s xlink:href parameter could be used to provide a jar file to be executed.

An attacker with control of a string presented in a Swing field could get code execution, so from a Cobalt Strike beacon running on the attacker’s machine they could potentially modify it’s memory or run an application with a malicious string as its process name. There are other avenues that could be used to exploit the issue, those are the two examples given though.

A bit of a followup to a previously covered issue; first-request routing, where a front-end proxy would route all incoming requests on the same connection to the host specified in the first request. Now with HTTP/3 browsers can do connection coalescing, sending traffic for multiple domains down the same connection as long as the domains resolve to the same IP and have a HTTPS certificate that is valid for both. This feature combined with a vulnerable server can mean that an attack on one domain can impact another domain if it gets coalleseced but then routed to the wrong back-end server because of first-request routing.

As a bit more concrete example (taken from the post) say you have wordpress.example.com and secure.example.com and the frontend server does this vulnerable first-request routing. An XSS on the WordPress domain could have its connection coalesced with the secure domain. Then issue requests to secure.example.com but that get routed to and served content wordpress.example.com. Allowing any injected scripts to now be executing in the secure.example.com context instead of just the WordPress domain.