• Skip to primary navigation
  • Skip to content
  • Skip to primary sidebar
  • Skip to footer

Sucuri Blog

Website Security News

  • Products
    • Website Security Platform
    • Website Firewall (WAF)
    • Enterprise Website Security
    • Multisite Solutions
  • Features
    • Detection
    • Protection
    • Performance
    • Response
    • Backups
  • Partners
    • Agency Solutions
    • Partners
    • Referral Program
    • Ecommerce
  • Resources
    • Guides
    • Webinars
    • Infographics
    • SiteCheck
    • Reports
    • Email Courses
  • Immediate Help
  • Login

Vulnerability Details: Joomla! Remote Code Execution

December 15, 2015Marc-Alexandre Montpas

FacebookTwitterSubscribe

The Joomla! team released a new version of Joomla! CMS yesterday to patch a serious and easy to exploit remote code execution vulnerability that affected pretty much all versions of the platform up to 3.4.5. As soon as the patch was released, we were able to start our investigation and found that it was already being exploited in the wild – 2 days before the disclosure.

We will now shed some light on vulnerability, specifically how it works.

PHP Session 102

By default, Joomla! stores users session in the site’s database. Here’s an example of what a typical session would look like:

1-sessions

A quick look reveals an interesting behavior about PHP’s way of unserializing sessions (which can be reproduced using PHP function session_decode). PHP’s session serialization function is a bit different than the usual serialize() we’re used to, especially when it comes to array indexes. Here’s a comparison of the two for a given array, array( ‘a’ => ‘a’, ‘b’ => ‘b’):

  • A standard serialize() call would give us a:2:{s:1:”a”;s:1:”a”;s:1:”b”;s:1:”b”;}
  • Whereas session_encode() is returning a|s:1:”a”;b|s:1:”b”;

As you can see, the second encoding still uses regular variable serialization but differ in the way it’s declaring indexes for the $_SESSION array. In this case, this is one of the thing that will allow attackers to store arbitrary session data inside the database.

When User Input Meets Session Data

Some of you might have noticed already, but the above session was created by me using Firefox. But wait, how does Joomla! know this?

2-u-a

When it creates a new session, Joomla! takes the client’s user-agent and stores it in the session’s session.client.browser index, which will be saved later on the database. Meaning, one could in theory close the current serialized object/array they are into and start a new one, using a payload similar to “}__test|a:100:{some serialized data}. The problem with this approach, as some will have noticed, is that we leave an extra pipe ( | ) character, which breaks the resulting serialized payload. To get anything malicious in the session, an attacker needs to get rid of all the data located after the injected payload.

Tainted Session Data Meets MySQL

Checking the session table’s collation gives us the last piece of the puzzle:

3-db

WordPress had a very similar issue recently, involving the lack of support of MySQL’s utf8_general_ci collation for 4 byte UTF-8 characters. MySQL’s default behavior when it meets an UTF-8 character that isn’t supported by utf8_general_ci is that it will just truncate all the data, starting from that specific character, exactly what’s needed for the exploit to work. The payload would then become something like: “}__test|a:100:{some serialized data}

What About Achieving Code Execution?

From the moment the attacker can push an arbitrary serialized payload in its session, he’s conducting what is known as an Object Injection attack, which as we have seen in the wild and shown in past disclosures usually allows Remote Code Execution to occur on the victim’s site. We won’t show this part here as there is still a lot of sites not updated, but you get the point.

Update As Soon As Possible

Attackers are already exploiting this vulnerability in the wild, so updating your sites should be done in priority. In the event where this wouldn’t be possible, we strongly encourage you to consider adding other security measures to prevent it from being hacked, such as a Website Application Firewall (WAF).

FacebookTwitterSubscribe

Categories: Joomla Security, Vulnerability DisclosureTags: Malware Updates

About Marc-Alexandre Montpas

Marc-Alexandre Montpas is Sucuri’s Senior Security Analyst who joined the company in 2014. Marc’s main responsibilities include reversing security patches and scavenging vulnerabilities, old and new. His professional experience covers eight years of finding bugs in open-source software. When Marc isn’t breaking things, you might find him participating in a hacking CTF competition. Connect with him on Twitter.

Reader Interactions

Comments

  1. Anonymous hacker

    December 15, 2015

    PoC or didin’t happen!

    • Daniel Cid

      December 15, 2015

      There is quite a few PoC’s circulating the web. We won’t be sharing from here.

      • blackwat3r

        December 15, 2015

        the best part is you guys tried to castrate the payload in your previous post but forgot to remove it from ddecode, probably because you wanted to achieve publicity by doing so, just like what seems to be the new thing with you types of “researchers”… gotta drop a bomb to make your resumes explosive right

        • Alycia

          December 15, 2015

          ddecode.com is a public tool, Sucuri didn’t put it there. Someone else must have tried to decode it.

      • Reza

        March 2, 2016

        Will you explain the part that how it can lead to code execution later?

    • guest

      December 15, 2015

      Try harder 😉

  2. Concerned Joomla

    December 15, 2015

    If you’re not using a database to store session data (ie, using PHP sessions instead), is this exploit still effective?

    What if your jos_sessions table doesn’t have a “data” column? Is it possible to see if you are exploited to check the data column in jos_sessions for a specific keyword?

    • Phil Taylor, The Joomla Expert

      December 16, 2015

      If you’re not using a database to store session data YES this exploit still is valid. Its a session issue – not a database issue.

  3. Bitsum

    December 16, 2015

    Another great analysis. Were you able to entirely mitigate this attack for your customers? Or at least most of them? Or did their protection depend on them updating Jooma, which has seemed to have had a lot of security exploits lately.

    • Daniel Cid

      December 16, 2015

      Yes, they were entirely protected from this attack, even before we knew about it (and without patches). That was due to our user-agent/x-forwarded-for filters that blocked / patched the vulnerability.

  4. Xristoph (X70) C.Rad

    December 16, 2015

    Can haz firewall?

  5. njk

    December 17, 2015

    I think I understand how this is supposed to work, and I certainly see people trying it on our sites. But I don’t see how it CAN work. Where the user-agent string is being inserted is preceded by a type, a length, and an open quote (s:412:”). So even if you close the quotes and close the object php is going to reject the whole thing because it didn’t get 412 characters when reading the value for client.browser. Unless this also requires a broken php deserializer?

  6. Hemang Rindani

    December 21, 2015

    I feel a quick look into JDatabaseDriverMysqli would be a good thing to do and check for the IPs in the log that makes Joomla vulnerable to the attacks. If you are a user of Joomla 3.x, update immediately to 3.4.6.

  7. jans

    April 23, 2016

    This injection is useless, because as noted @njk it will be stored with wrong length parameter e.g. s:500:”dummy”;} . So such session string cannot be decoded in correct way. Moreover the injected payload will be taken up due to such large size, and PHP interpreter devours session identifier __test|a……. Therefore nor 1-st nor 2-nd session will be decoded properly.
    The described “vulnerability” is not exploitable. I intentionally proved the existing PoC with vulnerable version of Joomla 3.4.4. It does not work. In the database session.counter is always 1 – it proves, that session cannot be unserialized.

    • Th3PonyWizard

      April 26, 2016

      It does not work?
      The CVE signed, and patched, is not valid?

Primary Sidebar

Socialize With Sucuri

We're actively engaged across multiple platforms. Follow us and let's connect!

  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
  • Instagram
  • RSS Feed

Join Over 20,000 Subscribers!

Sucuri Sidebar Malware Removal to Signup Page

Footer

Products

  • Website Firewall
  • Website AntiVirus
  • Website Backups
  • WordPress Security
  • Enterprise Services

Solutions

  • DDos Protection
  • Malware Detection
  • Malware Removal
  • Malware Prevention
  • Blacklist Removal

Support

  • Blog
  • Knowledge Base
  • SiteCheck
  • Research Labs
  • FAQ

Company

  • About
  • Media
  • Events
  • Employment
  • Contact
  • Testimonials
  • Facebook
  • Twitter
  • LinkedIn
  • Instagram

Customer Login

Sucuri Home

  • Terms of Use
  • Privacy Policy
  • Frequently Asked Questions

© 2023 Sucuri Inc. All rights reserved

Sucuri Cookie Policy
See our policy>>

Our website uses cookies, which help us to improve our site and enables us to deliver the best possible service and customer experience.